diff --git a/metadata/metadata b/metadata/metadata --- a/metadata/metadata +++ b/metadata/metadata @@ -1,10173 +1,10186 @@ [Arith_Prog_Rel_Primes] title = Arithmetic progressions and relative primes author = José Manuel Rodríguez Caballero topic = Mathematics/Number theory date = 2020-02-01 notify = jose.manuel.rodriguez.caballero@ut.ee abstract = This article provides a formalization of the solution obtained by the author of the Problem “ARITHMETIC PROGRESSIONS” from the Putnam exam problems of 2002. The statement of the problem is as follows: For which integers n > 1 does the set of positive integers less than and relatively prime to n constitute an arithmetic progression? [Banach_Steinhaus] title = Banach-Steinhaus Theorem author = Dominique Unruh , Jose Manuel Rodriguez Caballero topic = Mathematics/Analysis date = 2020-05-02 notify = jose.manuel.rodriguez.caballero@ut.ee, unruh@ut.ee abstract = We formalize in Isabelle/HOL a result due to S. Banach and H. Steinhaus known as the Banach-Steinhaus theorem or Uniform boundedness principle: a pointwise-bounded family of continuous linear operators from a Banach space to a normed space is uniformly bounded. Our approach is an adaptation to Isabelle/HOL of a proof due to A. Sokal. [Complex_Geometry] title = Complex Geometry author = Filip Marić , Danijela Simić topic = Mathematics/Geometry date = 2019-12-16 notify = danijela@matf.bg.ac.rs, filip@matf.bg.ac.rs, boutry@unistra.fr abstract = A formalization of geometry of complex numbers is presented. Fundamental objects that are investigated are the complex plane extended by a single infinite point, its objects (points, lines and circles), and groups of transformations that act on them (e.g., inversions and Möbius transformations). Most objects are defined algebraically, but correspondence with classical geometric definitions is shown. [Poincare_Disc] title = Poincaré Disc Model author = Danijela Simić , Filip Marić , Pierre Boutry topic = Mathematics/Geometry date = 2019-12-16 notify = danijela@matf.bg.ac.rs, filip@matf.bg.ac.rs, boutry@unistra.fr abstract = We describe formalization of the Poincaré disc model of hyperbolic geometry within the Isabelle/HOL proof assistant. The model is defined within the extended complex plane (one dimensional complex projectives space ℂP1), formalized in the AFP entry “Complex Geometry”. Points, lines, congruence of pairs of points, betweenness of triples of points, circles, and isometries are defined within the model. It is shown that the model satisfies all Tarski's axioms except the Euclid's axiom. It is shown that it satisfies its negation and the limiting parallels axiom (which proves it to be a model of hyperbolic geometry). [Fourier] title = Fourier Series author = Lawrence C Paulson topic = Mathematics/Analysis date = 2019-09-06 notify = lp15@cam.ac.uk abstract = This development formalises the square integrable functions over the reals and the basics of Fourier series. It culminates with a proof that every well-behaved periodic function can be approximated by a Fourier series. The material is ported from HOL Light: https://github.com/jrh13/hol-light/blob/master/100/fourier.ml [Generic_Deriving] title = Deriving generic class instances for datatypes author = Jonas Rädle , Lars Hupel topic = Computer science/Data structures date = 2018-11-06 notify = jonas.raedle@gmail.com abstract =

We provide a framework for automatically deriving instances for generic type classes. Our approach is inspired by Haskell's generic-deriving package and Scala's shapeless library. In addition to generating the code for type class functions, we also attempt to automatically prove type class laws for these instances. As of now, however, some manual proofs are still required for recursive datatypes.

Note: There are already articles in the AFP that provide automatic instantiation for a number of classes. Concretely, Deriving allows the automatic instantiation of comparators, linear orders, equality, and hashing. Show instantiates a Haskell-style show class.

Our approach works for arbitrary classes (with some Isabelle/HOL overhead for each class), but a smaller set of datatypes.

[Partial_Order_Reduction] title = Partial Order Reduction author = Julian Brunner topic = Computer science/Automata and formal languages date = 2018-06-05 notify = brunnerj@in.tum.de abstract = This entry provides a formalization of the abstract theory of ample set partial order reduction. The formalization includes transition systems with actions, trace theory, as well as basics on finite, infinite, and lazy sequences. We also provide a basic framework for static analysis on concurrent systems with respect to the ample set condition. [CakeML] title = CakeML author = Lars Hupel , Yu Zhang <> contributors = Johannes Åman Pohjola <> topic = Computer science/Programming languages/Language definitions date = 2018-03-12 notify = hupel@in.tum.de abstract = CakeML is a functional programming language with a proven-correct compiler and runtime system. This entry contains an unofficial version of the CakeML semantics that has been exported from the Lem specifications to Isabelle. Additionally, there are some hand-written theory files that adapt the exported code to Isabelle and port proofs from the HOL4 formalization, e.g. termination and equivalence proofs. [CakeML_Codegen] title = A Verified Code Generator from Isabelle/HOL to CakeML author = Lars Hupel topic = Computer science/Programming languages/Compiling, Logic/Rewriting date = 2019-07-08 notify = lars@hupel.info abstract = This entry contains the formalization that accompanies my PhD thesis (see https://lars.hupel.info/research/codegen/). I develop a verified compilation toolchain from executable specifications in Isabelle/HOL to CakeML abstract syntax trees. This improves over the state-of-the-art in Isabelle by providing a trustworthy procedure for code generation. [DiscretePricing] title = Pricing in discrete financial models author = Mnacho Echenim topic = Mathematics/Probability theory, Mathematics/Games and economics date = 2018-07-16 notify = mnacho.echenim@univ-grenoble-alpes.fr abstract = We have formalized the computation of fair prices for derivative products in discrete financial models. As an application, we derive a way to compute fair prices of derivative products in the Cox-Ross-Rubinstein model of a financial market, thus completing the work that was presented in this paper. extra-history = Change history: [2019-05-12]: Renamed discr_mkt predicate to stk_strict_subs and got rid of predicate A for a more natural definition of the type discrete_market; renamed basic quantity processes for coherent notation; renamed value_process into val_process and closing_value_process to cls_val_process; relaxed hypothesis of lemma CRR_market_fair_price. Added functions to price some basic options. (revision 0b813a1a833f)
[Pell] title = Pell's Equation author = Manuel Eberl topic = Mathematics/Number theory date = 2018-06-23 notify = eberlm@in.tum.de abstract =

This article gives the basic theory of Pell's equation x2 = 1 + Dy2, where D ∈ ℕ is a parameter and x, y are integer variables.

The main result that is proven is the following: If D is not a perfect square, then there exists a fundamental solution (x0, y0) that is not the trivial solution (1, 0) and which generates all other solutions (x, y) in the sense that there exists some n ∈ ℕ such that |x| + |y| √D = (x0 + y0 √D)n. This also implies that the set of solutions is infinite, and it gives us an explicit and executable characterisation of all the solutions.

Based on this, simple executable algorithms for computing the fundamental solution and the infinite sequence of all non-negative solutions are also provided.

[WebAssembly] title = WebAssembly author = Conrad Watt topic = Computer science/Programming languages/Language definitions date = 2018-04-29 notify = caw77@cam.ac.uk abstract = This is a mechanised specification of the WebAssembly language, drawn mainly from the previously published paper formalisation of Haas et al. Also included is a full proof of soundness of the type system, together with a verified type checker and interpreter. We include only a partial procedure for the extraction of the type checker and interpreter here. For more details, please see our paper in CPP 2018. [Knuth_Morris_Pratt] title = The string search algorithm by Knuth, Morris and Pratt author = Fabian Hellauer , Peter Lammich topic = Computer science/Algorithms date = 2017-12-18 notify = hellauer@in.tum.de, lammich@in.tum.de abstract = The Knuth-Morris-Pratt algorithm is often used to show that the problem of finding a string s in a text t can be solved deterministically in O(|s| + |t|) time. We use the Isabelle Refinement Framework to formulate and verify the algorithm. Via refinement, we apply some optimisations and finally use the Sepref tool to obtain executable code in Imperative/HOL. [Minkowskis_Theorem] title = Minkowski's Theorem author = Manuel Eberl topic = Mathematics/Geometry, Mathematics/Number theory date = 2017-07-13 notify = eberlm@in.tum.de abstract =

Minkowski's theorem relates a subset of ℝn, the Lebesgue measure, and the integer lattice ℤn: It states that any convex subset of ℝn with volume greater than 2n contains at least one lattice point from ℤn\{0}, i. e. a non-zero point with integer coefficients.

A related theorem which directly implies this is Blichfeldt's theorem, which states that any subset of ℝn with a volume greater than 1 contains two different points whose difference vector has integer components.

The entry contains a proof of both theorems.

[Name_Carrying_Type_Inference] title = Verified Metatheory and Type Inference for a Name-Carrying Simply-Typed Lambda Calculus author = Michael Rawson topic = Computer science/Programming languages/Type systems date = 2017-07-09 notify = mr644@cam.ac.uk, michaelrawson76@gmail.com abstract = I formalise a Church-style simply-typed \(\lambda\)-calculus, extended with pairs, a unit value, and projection functions, and show some metatheory of the calculus, such as the subject reduction property. Particular attention is paid to the treatment of names in the calculus. A nominal style of binding is used, but I use a manual approach over Nominal Isabelle in order to extract an executable type inference algorithm. More information can be found in my undergraduate dissertation. [Propositional_Proof_Systems] title = Propositional Proof Systems author = Julius Michaelis , Tobias Nipkow topic = Logic/Proof theory date = 2017-06-21 notify = maintainafpppt@liftm.de abstract = We formalize a range of proof systems for classical propositional logic (sequent calculus, natural deduction, Hilbert systems, resolution) and prove the most important meta-theoretic results about semantics and proofs: compactness, soundness, completeness, translations between proof systems, cut-elimination, interpolation and model existence. [Optics] title = Optics author = Simon Foster , Frank Zeyda topic = Computer science/Functional programming, Mathematics/Algebra date = 2017-05-25 notify = simon.foster@york.ac.uk abstract = Lenses provide an abstract interface for manipulating data types through spatially-separated views. They are defined abstractly in terms of two functions, get, the return a value from the source type, and put that updates the value. We mechanise the underlying theory of lenses, in terms of an algebraic hierarchy of lenses, including well-behaved and very well-behaved lenses, each lens class being characterised by a set of lens laws. We also mechanise a lens algebra in Isabelle that enables their composition and comparison, so as to allow construction of complex lenses. This is accompanied by a large library of algebraic laws. Moreover we also show how the lens classes can be applied by instantiating them with a number of Isabelle data types. extra-history = Change history: [2020-03-02]: Added partial bijective and symmetric lenses. Improved alphabet command generating additional lenses and results. Several additional lens relations, including observational equivalence. Additional theorems throughout. Adaptations for Isabelle 2020. (revision 44e2e5c) [Game_Based_Crypto] title = Game-based cryptography in HOL author = Andreas Lochbihler , S. Reza Sefidgar <>, Bhargav Bhatt topic = Computer science/Security/Cryptography date = 2017-05-05 notify = mail@andreas-lochbihler.de abstract =

In this AFP entry, we show how to specify game-based cryptographic security notions and formally prove secure several cryptographic constructions from the literature using the CryptHOL framework. Among others, we formalise the notions of a random oracle, a pseudo-random function, an unpredictable function, and of encryption schemes that are indistinguishable under chosen plaintext and/or ciphertext attacks. We prove the random-permutation/random-function switching lemma, security of the Elgamal and hashed Elgamal public-key encryption scheme and correctness and security of several constructions with pseudo-random functions.

Our proofs follow the game-hopping style advocated by Shoup and Bellare and Rogaway, from which most of the examples have been taken. We generalise some of their results such that they can be reused in other proofs. Thanks to CryptHOL's integration with Isabelle's parametricity infrastructure, many simple hops are easily justified using the theory of representation independence.

extra-history = Change history: [2018-09-28]: added the CryptHOL tutorial for game-based cryptography (revision 489a395764ae) [Multi_Party_Computation] title = Multi-Party Computation author = David Aspinall , David Butler topic = Computer science/Security date = 2019-05-09 notify = dbutler@turing.ac.uk abstract = We use CryptHOL to consider Multi-Party Computation (MPC) protocols. MPC was first considered by Yao in 1983 and recent advances in efficiency and an increased demand mean it is now deployed in the real world. Security is considered using the real/ideal world paradigm. We first define security in the semi-honest security setting where parties are assumed not to deviate from the protocol transcript. In this setting we prove multiple Oblivious Transfer (OT) protocols secure and then show security for the gates of the GMW protocol. We then define malicious security, this is a stronger notion of security where parties are assumed to be fully corrupted by an adversary. In this setting we again consider OT, as it is a fundamental building block of almost all MPC protocols. [Sigma_Commit_Crypto] title = Sigma Protocols and Commitment Schemes author = David Butler , Andreas Lochbihler topic = Computer science/Security/Cryptography date = 2019-10-07 notify = dbutler@turing.ac.uk abstract = We use CryptHOL to formalise commitment schemes and Sigma-protocols. Both are widely used fundamental two party cryptographic primitives. Security for commitment schemes is considered using game-based definitions whereas the security of Sigma-protocols is considered using both the game-based and simulation-based security paradigms. In this work, we first define security for both primitives and then prove secure multiple case studies: the Schnorr, Chaum-Pedersen and Okamoto Sigma-protocols as well as a construction that allows for compound (AND and OR statements) Sigma-protocols and the Pedersen and Rivest commitment schemes. We also prove that commitment schemes can be constructed from Sigma-protocols. We formalise this proof at an abstract level, only assuming the existence of a Sigma-protocol; consequently, the instantiations of this result for the concrete Sigma-protocols we consider come for free. [CryptHOL] title = CryptHOL author = Andreas Lochbihler topic = Computer science/Security/Cryptography, Computer science/Functional programming, Mathematics/Probability theory date = 2017-05-05 notify = mail@andreas-lochbihler.de abstract =

CryptHOL provides a framework for formalising cryptographic arguments in Isabelle/HOL. It shallowly embeds a probabilistic functional programming language in higher order logic. The language features monadic sequencing, recursion, random sampling, failures and failure handling, and black-box access to oracles. Oracles are probabilistic functions which maintain hidden state between different invocations. All operators are defined in the new semantic domain of generative probabilistic values, a codatatype. We derive proof rules for the operators and establish a connection with the theory of relational parametricity. Thus, the resuting proofs are trustworthy and comprehensible, and the framework is extensible and widely applicable.

The framework is used in the accompanying AFP entry "Game-based Cryptography in HOL". There, we show-case our framework by formalizing different game-based proofs from the literature. This formalisation continues the work described in the author's ESOP 2016 paper.

[Constructive_Cryptography] title = Constructive Cryptography in HOL author = Andreas Lochbihler , S. Reza Sefidgar<> topic = Computer science/Security/Cryptography, Mathematics/Probability theory date = 2018-12-17 notify = mail@andreas-lochbihler.de, reza.sefidgar@inf.ethz.ch abstract = Inspired by Abstract Cryptography, we extend CryptHOL, a framework for formalizing game-based proofs, with an abstract model of Random Systems and provide proof rules about their composition and equality. This foundation facilitates the formalization of Constructive Cryptography proofs, where the security of a cryptographic scheme is realized as a special form of construction in which a complex random system is built from simpler ones. This is a first step towards a fully-featured compositional framework, similar to Universal Composability framework, that supports formalization of simulation-based proofs. [Probabilistic_While] title = Probabilistic while loop author = Andreas Lochbihler topic = Computer science/Functional programming, Mathematics/Probability theory, Computer science/Algorithms date = 2017-05-05 notify = mail@andreas-lochbihler.de abstract = This AFP entry defines a probabilistic while operator based on sub-probability mass functions and formalises zero-one laws and variant rules for probabilistic loop termination. As applications, we implement probabilistic algorithms for the Bernoulli, geometric and arbitrary uniform distributions that only use fair coin flips, and prove them correct and terminating with probability 1. extra-history = Change history: [2018-02-02]: Added a proof that probabilistic conditioning can be implemented by repeated sampling. (revision 305867c4e911)
[Monad_Normalisation] title = Monad normalisation author = Joshua Schneider <>, Manuel Eberl , Andreas Lochbihler topic = Tools, Computer science/Functional programming, Logic/Rewriting date = 2017-05-05 notify = mail@andreas-lochbihler.de abstract = The usual monad laws can directly be used as rewrite rules for Isabelle’s simplifier to normalise monadic HOL terms and decide equivalences. In a commutative monad, however, the commutativity law is a higher-order permutative rewrite rule that makes the simplifier loop. This AFP entry implements a simproc that normalises monadic expressions in commutative monads using ordered rewriting. The simproc can also permute computations across control operators like if and case. [Monomorphic_Monad] title = Effect polymorphism in higher-order logic author = Andreas Lochbihler topic = Computer science/Functional programming date = 2017-05-05 notify = mail@andreas-lochbihler.de abstract = The notion of a monad cannot be expressed within higher-order logic (HOL) due to type system restrictions. We show that if a monad is used with values of only one type, this notion can be formalised in HOL. Based on this idea, we develop a library of effect specifications and implementations of monads and monad transformers. Hence, we can abstract over the concrete monad in HOL definitions and thus use the same definition for different (combinations of) effects. We illustrate the usefulness of effect polymorphism with a monadic interpreter for a simple language. extra-history = Change history: [2018-02-15]: added further specifications and implementations of non-determinism; more examples (revision bc5399eea78e)
[Constructor_Funs] title = Constructor Functions author = Lars Hupel topic = Tools date = 2017-04-19 notify = hupel@in.tum.de abstract = Isabelle's code generator performs various adaptations for target languages. Among others, constructor applications have to be fully saturated. That means that for constructor calls occuring as arguments to higher-order functions, synthetic lambdas have to be inserted. This entry provides tooling to avoid this construction altogether by introducing constructor functions. [Lazy_Case] title = Lazifying case constants author = Lars Hupel topic = Tools date = 2017-04-18 notify = hupel@in.tum.de abstract = Isabelle's code generator performs various adaptations for target languages. Among others, case statements are printed as match expressions. Internally, this is a sophisticated procedure, because in HOL, case statements are represented as nested calls to the case combinators as generated by the datatype package. Furthermore, the procedure relies on laziness of match expressions in the target language, i.e., that branches guarded by patterns that fail to match are not evaluated. Similarly, if-then-else is printed to the corresponding construct in the target language. This entry provides tooling to replace these special cases in the code generator by ignoring these target language features, instead printing case expressions and if-then-else as functions. [Dict_Construction] title = Dictionary Construction author = Lars Hupel topic = Tools date = 2017-05-24 notify = hupel@in.tum.de abstract = Isabelle's code generator natively supports type classes. For targets that do not have language support for classes and instances, it performs the well-known dictionary translation, as described by Haftmann and Nipkow. This translation happens outside the logic, i.e., there is no guarantee that it is correct, besides the pen-and-paper proof. This work implements a certified dictionary translation that produces new class-free constants and derives equality theorems. [Higher_Order_Terms] title = An Algebra for Higher-Order Terms author = Lars Hupel contributors = Yu Zhang <> topic = Computer science/Programming languages/Lambda calculi date = 2019-01-15 notify = lars@hupel.info abstract = In this formalization, I introduce a higher-order term algebra, generalizing the notions of free variables, matching, and substitution. The need arose from the work on a verified compiler from Isabelle to CakeML. Terms can be thought of as consisting of a generic (free variables, constants, application) and a specific part. As example applications, this entry provides instantiations for de-Bruijn terms, terms with named variables, and Blanchette’s λ-free higher-order terms. Furthermore, I implement translation functions between de-Bruijn terms and named terms and prove their correctness. [Subresultants] title = Subresultants author = Sebastiaan Joosten , René Thiemann , Akihisa Yamada topic = Mathematics/Algebra date = 2017-04-06 notify = rene.thiemann@uibk.ac.at abstract = We formalize the theory of subresultants and the subresultant polynomial remainder sequence as described by Brown and Traub. As a result, we obtain efficient certified algorithms for computing the resultant and the greatest common divisor of polynomials. [Comparison_Sort_Lower_Bound] title = Lower bound on comparison-based sorting algorithms author = Manuel Eberl topic = Computer science/Algorithms date = 2017-03-15 notify = eberlm@in.tum.de abstract =

This article contains a formal proof of the well-known fact that number of comparisons that a comparison-based sorting algorithm needs to perform to sort a list of length n is at least log2 (n!) in the worst case, i. e. Ω(n log n).

For this purpose, a shallow embedding for comparison-based sorting algorithms is defined: a sorting algorithm is a recursive datatype containing either a HOL function or a query of a comparison oracle with a continuation containing the remaining computation. This makes it possible to force the algorithm to use only comparisons and to track the number of comparisons made.

[Quick_Sort_Cost] title = The number of comparisons in QuickSort author = Manuel Eberl topic = Computer science/Algorithms date = 2017-03-15 notify = eberlm@in.tum.de abstract =

We give a formal proof of the well-known results about the number of comparisons performed by two variants of QuickSort: first, the expected number of comparisons of randomised QuickSort (i. e. QuickSort with random pivot choice) is 2 (n+1) Hn - 4 n, which is asymptotically equivalent to 2 n ln n; second, the number of comparisons performed by the classic non-randomised QuickSort has the same distribution in the average case as the randomised one.

[Random_BSTs] title = Expected Shape of Random Binary Search Trees author = Manuel Eberl topic = Computer science/Data structures date = 2017-04-04 notify = eberlm@in.tum.de abstract =

This entry contains proofs for the textbook results about the distributions of the height and internal path length of random binary search trees (BSTs), i. e. BSTs that are formed by taking an empty BST and inserting elements from a fixed set in random order.

In particular, we prove a logarithmic upper bound on the expected height and the Θ(n log n) closed-form solution for the expected internal path length in terms of the harmonic numbers. We also show how the internal path length relates to the average-case cost of a lookup in a BST.

[Randomised_BSTs] title = Randomised Binary Search Trees author = Manuel Eberl topic = Computer science/Data structures date = 2018-10-19 notify = eberlm@in.tum.de abstract =

This work is a formalisation of the Randomised Binary Search Trees introduced by Martínez and Roura, including definitions and correctness proofs.

Like randomised treaps, they are a probabilistic data structure that behaves exactly as if elements were inserted into a non-balancing BST in random order. However, unlike treaps, they only use discrete probability distributions, but their use of randomness is more complicated.

[E_Transcendental] title = The Transcendence of e author = Manuel Eberl topic = Mathematics/Analysis, Mathematics/Number theory date = 2017-01-12 notify = eberlm@in.tum.de abstract =

This work contains a proof that Euler's number e is transcendental. The proof follows the standard approach of assuming that e is algebraic and then using a specific integer polynomial to derive two inconsistent bounds, leading to a contradiction.

This kind of approach can be found in many different sources; this formalisation mostly follows a PlanetMath article by Roger Lipsett.

[Pi_Transcendental] title = The Transcendence of π author = Manuel Eberl topic = Mathematics/Number theory date = 2018-09-28 notify = eberlm@in.tum.de abstract =

This entry shows the transcendence of π based on the classic proof using the fundamental theorem of symmetric polynomials first given by von Lindemann in 1882, but the formalisation mostly follows the version by Niven. The proof reuses much of the machinery developed in the AFP entry on the transcendence of e.

[DFS_Framework] title = A Framework for Verifying Depth-First Search Algorithms author = Peter Lammich , René Neumann notify = lammich@in.tum.de date = 2016-07-05 topic = Computer science/Algorithms/Graph abstract =

This entry presents a framework for the modular verification of DFS-based algorithms, which is described in our [CPP-2015] paper. It provides a generic DFS algorithm framework, that can be parameterized with user-defined actions on certain events (e.g. discovery of new node). It comes with an extensible library of invariants, which can be used to derive invariants of a specific parameterization. Using refinement techniques, efficient implementations of the algorithms can easily be derived. Here, the framework comes with templates for a recursive and a tail-recursive implementation, and also with several templates for implementing the data structures required by the DFS algorithm. Finally, this entry contains a set of re-usable DFS-based algorithms, which illustrate the application of the framework.

[CPP-2015] Peter Lammich, René Neumann: A Framework for Verifying Depth-First Search Algorithms. CPP 2015: 137-146

[Flow_Networks] title = Flow Networks and the Min-Cut-Max-Flow Theorem author = Peter Lammich , S. Reza Sefidgar <> topic = Mathematics/Graph theory date = 2017-06-01 notify = lammich@in.tum.de abstract = We present a formalization of flow networks and the Min-Cut-Max-Flow theorem. Our formal proof closely follows a standard textbook proof, and is accessible even without being an expert in Isabelle/HOL, the interactive theorem prover used for the formalization. [Prpu_Maxflow] title = Formalizing Push-Relabel Algorithms author = Peter Lammich , S. Reza Sefidgar <> topic = Computer science/Algorithms/Graph, Mathematics/Graph theory date = 2017-06-01 notify = lammich@in.tum.de abstract = We present a formalization of push-relabel algorithms for computing the maximum flow in a network. We start with Goldberg's et al.~generic push-relabel algorithm, for which we show correctness and the time complexity bound of O(V^2E). We then derive the relabel-to-front and FIFO implementation. Using stepwise refinement techniques, we derive an efficient verified implementation. Our formal proof of the abstract algorithms closely follows a standard textbook proof. It is accessible even without being an expert in Isabelle/HOL, the interactive theorem prover used for the formalization. [Buildings] title = Chamber Complexes, Coxeter Systems, and Buildings author = Jeremy Sylvestre notify = jeremy.sylvestre@ualberta.ca date = 2016-07-01 topic = Mathematics/Algebra, Mathematics/Geometry abstract = We provide a basic formal framework for the theory of chamber complexes and Coxeter systems, and for buildings as thick chamber complexes endowed with a system of apartments. Along the way, we develop some of the general theory of abstract simplicial complexes and of groups (relying on the group_add class for the basics), including free groups and group presentations, and their universal properties. The main results verified are that the deletion condition is both necessary and sufficient for a group with a set of generators of order two to be a Coxeter system, and that the apartments in a (thick) building are all uniformly Coxeter. [Algebraic_VCs] title = Program Construction and Verification Components Based on Kleene Algebra author = Victor B. F. Gomes , Georg Struth notify = victor.gomes@cl.cam.ac.uk, g.struth@sheffield.ac.uk date = 2016-06-18 topic = Mathematics/Algebra abstract = Variants of Kleene algebra support program construction and verification by algebraic reasoning. This entry provides a verification component for Hoare logic based on Kleene algebra with tests, verification components for weakest preconditions and strongest postconditions based on Kleene algebra with domain and a component for step-wise refinement based on refinement Kleene algebra with tests. In addition to these components for the partial correctness of while programs, a verification component for total correctness based on divergence Kleene algebras and one for (partial correctness) of recursive programs based on domain quantales are provided. Finally we have integrated memory models for programs with pointers and a program trace semantics into the weakest precondition component. [C2KA_DistributedSystems] title = Communicating Concurrent Kleene Algebra for Distributed Systems Specification author = Maxime Buyse , Jason Jaskolka topic = Computer science/Automata and formal languages, Mathematics/Algebra date = 2019-08-06 notify = maxime.buyse@polytechnique.edu, jason.jaskolka@carleton.ca abstract = Communicating Concurrent Kleene Algebra (C²KA) is a mathematical framework for capturing the communicating and concurrent behaviour of agents in distributed systems. It extends Hoare et al.'s Concurrent Kleene Algebra (CKA) with communication actions through the notions of stimuli and shared environments. C²KA has applications in studying system-level properties of distributed systems such as safety, security, and reliability. In this work, we formalize results about C²KA and its application for distributed systems specification. We first formalize the stimulus structure and behaviour structure (CKA). Next, we combine them to formalize C²KA and its properties. Then, we formalize notions and properties related to the topology of distributed systems and the potential for communication via stimuli and via shared environments of agents, all within the algebraic setting of C²KA. [Card_Equiv_Relations] title = Cardinality of Equivalence Relations author = Lukas Bulwahn notify = lukas.bulwahn@gmail.com date = 2016-05-24 topic = Mathematics/Combinatorics abstract = This entry provides formulae for counting the number of equivalence relations and partial equivalence relations over a finite carrier set with given cardinality. To count the number of equivalence relations, we provide bijections between equivalence relations and set partitions, and then transfer the main results of the two AFP entries, Cardinality of Set Partitions and Spivey's Generalized Recurrence for Bell Numbers, to theorems on equivalence relations. To count the number of partial equivalence relations, we observe that counting partial equivalence relations over a set A is equivalent to counting all equivalence relations over all subsets of the set A. From this observation and the results on equivalence relations, we show that the cardinality of partial equivalence relations over a finite set of cardinality n is equal to the n+1-th Bell number. [Twelvefold_Way] title = The Twelvefold Way author = Lukas Bulwahn topic = Mathematics/Combinatorics date = 2016-12-29 notify = lukas.bulwahn@gmail.com abstract = This entry provides all cardinality theorems of the Twelvefold Way. The Twelvefold Way systematically classifies twelve related combinatorial problems concerning two finite sets, which include counting permutations, combinations, multisets, set partitions and number partitions. This development builds upon the existing formal developments with cardinality theorems for those structures. It provides twelve bijections from the various structures to different equivalence classes on finite functions, and hence, proves cardinality formulae for these equivalence classes on finite functions. [Chord_Segments] title = Intersecting Chords Theorem author = Lukas Bulwahn notify = lukas.bulwahn@gmail.com date = 2016-10-11 topic = Mathematics/Geometry abstract = This entry provides a geometric proof of the intersecting chords theorem. The theorem states that when two chords intersect each other inside a circle, the products of their segments are equal. After a short review of existing proofs in the literature, I decided to use a proof approach that employs reasoning about lengths of line segments, the orthogonality of two lines and the Pythagoras Law. Hence, one can understand the formalized proof easily with the knowledge of a few general geometric facts that are commonly taught in high-school. This theorem is the 55th theorem of the Top 100 Theorems list. [Category3] title = Category Theory with Adjunctions and Limits author = Eugene W. Stark notify = stark@cs.stonybrook.edu date = 2016-06-26 topic = Mathematics/Category theory abstract =

This article attempts to develop a usable framework for doing category theory in Isabelle/HOL. Our point of view, which to some extent differs from that of the previous AFP articles on the subject, is to try to explore how category theory can be done efficaciously within HOL, rather than trying to match exactly the way things are done using a traditional approach. To this end, we define the notion of category in an "object-free" style, in which a category is represented by a single partial composition operation on arrows. This way of defining categories provides some advantages in the context of HOL, including the ability to avoid the use of records and the possibility of defining functors and natural transformations simply as certain functions on arrows, rather than as composite objects. We define various constructions associated with the basic notions, including: dual category, product category, functor category, discrete category, free category, functor composition, and horizontal and vertical composite of natural transformations. A "set category" locale is defined that axiomatizes the notion "category of all sets at a type and all functions between them," and a fairly extensive set of properties of set categories is derived from the locale assumptions. The notion of a set category is used to prove the Yoneda Lemma in a general setting of a category equipped with a "hom embedding," which maps arrows of the category to the "universe" of the set category. We also give a treatment of adjunctions, defining adjunctions via left and right adjoint functors, natural bijections between hom-sets, and unit and counit natural transformations, and showing the equivalence of these definitions. We also develop the theory of limits, including representations of functors, diagrams and cones, and diagonal functors. We show that right adjoint functors preserve limits, and that limits can be constructed via products and equalizers. We characterize the conditions under which limits exist in a set category. We also examine the case of limits in a functor category, ultimately culminating in a proof that the Yoneda embedding preserves limits.

Revisions made subsequent to the first version of this article added material on equivalence of categories, cartesian categories, categories with pullbacks, categories with finite limits, and cartesian closed categories. A construction was given of the category of hereditarily finite sets and functions between them, and it was shown that this category is cartesian closed.

extra-history = Change history: [2018-05-29]: Revised axioms for the category locale. Introduced notation for composition and "in hom". (revision 8318366d4575)
[2020-02-15]: Move ConcreteCategory.thy from Bicategory to Category3 and use it systematically. Make other minor improvements throughout. (revision a51840d36867)
[2020-07-10]: Added new material, mostly centered around cartesian categories. (revision 06640f317a79)
[2020-11-04]: Minor modifications and extensions made in conjunction with the addition of new material to Bicategory. (revision 472cb2268826)
[MonoidalCategory] title = Monoidal Categories author = Eugene W. Stark topic = Mathematics/Category theory date = 2017-05-04 notify = stark@cs.stonybrook.edu abstract =

Building on the formalization of basic category theory set out in the author's previous AFP article, the present article formalizes some basic aspects of the theory of monoidal categories. Among the notions defined here are monoidal category, monoidal functor, and equivalence of monoidal categories. The main theorems formalized are MacLane's coherence theorem and the constructions of the free monoidal category and free strict monoidal category generated by a given category. The coherence theorem is proved syntactically, using a structurally recursive approach to reduction of terms that might have some novel aspects. We also give proofs of some results given by Etingof et al, which may prove useful in a formal setting. In particular, we show that the left and right unitors need not be taken as given data in the definition of monoidal category, nor does the definition of monoidal functor need to take as given a specific isomorphism expressing the preservation of the unit object. Our definitions of monoidal category and monoidal functor are stated so as to take advantage of the economy afforded by these facts.

Revisions made subsequent to the first version of this article added material on cartesian monoidal categories; showing that the underlying category of a cartesian monoidal category is a cartesian category, and that every cartesian category extends to a cartesian monoidal category.

extra-history = Change history: [2017-05-18]: Integrated material from MonoidalCategory/Category3Adapter into Category3/ and deleted adapter. (revision 015543cdd069)
[2018-05-29]: Modifications required due to 'Category3' changes. Introduced notation for "in hom". (revision 8318366d4575)
[2020-02-15]: Cosmetic improvements. (revision a51840d36867)
[2020-07-10]: Added new material on cartesian monoidal categories. (revision 06640f317a79)
[Card_Multisets] title = Cardinality of Multisets author = Lukas Bulwahn notify = lukas.bulwahn@gmail.com date = 2016-06-26 topic = Mathematics/Combinatorics abstract =

This entry provides three lemmas to count the number of multisets of a given size and finite carrier set. The first lemma provides a cardinality formula assuming that the multiset's elements are chosen from the given carrier set. The latter two lemmas provide formulas assuming that the multiset's elements also cover the given carrier set, i.e., each element of the carrier set occurs in the multiset at least once.

The proof of the first lemma uses the argument of the recurrence relation for counting multisets. The proof of the second lemma is straightforward, and the proof of the third lemma is easily obtained using the first cardinality lemma. A challenge for the formalization is the derivation of the required induction rule, which is a special combination of the induction rules for finite sets and natural numbers. The induction rule is derived by defining a suitable inductive predicate and transforming the predicate's induction rule.

[Posix-Lexing] title = POSIX Lexing with Derivatives of Regular Expressions author = Fahad Ausaf , Roy Dyckhoff , Christian Urban notify = christian.urban@kcl.ac.uk date = 2016-05-24 topic = Computer science/Automata and formal languages abstract = Brzozowski introduced the notion of derivatives for regular expressions. They can be used for a very simple regular expression matching algorithm. Sulzmann and Lu cleverly extended this algorithm in order to deal with POSIX matching, which is the underlying disambiguation strategy for regular expressions needed in lexers. In this entry we give our inductive definition of what a POSIX value is and show (i) that such a value is unique (for given regular expression and string being matched) and (ii) that Sulzmann and Lu's algorithm always generates such a value (provided that the regular expression matches the string). We also prove the correctness of an optimised version of the POSIX matching algorithm. [LocalLexing] title = Local Lexing author = Steven Obua topic = Computer science/Automata and formal languages date = 2017-04-28 notify = steven@recursivemind.com abstract = This formalisation accompanies the paper Local Lexing which introduces a novel parsing concept of the same name. The paper also gives a high-level algorithm for local lexing as an extension of Earley's algorithm. This formalisation proves the algorithm to be correct with respect to its local lexing semantics. As a special case, this formalisation thus also contains a proof of the correctness of Earley's algorithm. The paper contains a short outline of how this formalisation is organised. [MFMC_Countable] title = A Formal Proof of the Max-Flow Min-Cut Theorem for Countable Networks author = Andreas Lochbihler date = 2016-05-09 topic = Mathematics/Graph theory abstract = This article formalises a proof of the maximum-flow minimal-cut theorem for networks with countably many edges. A network is a directed graph with non-negative real-valued edge labels and two dedicated vertices, the source and the sink. A flow in a network assigns non-negative real numbers to the edges such that for all vertices except for the source and the sink, the sum of values on incoming edges equals the sum of values on outgoing edges. A cut is a subset of the vertices which contains the source, but not the sink. Our theorem states that in every network, there is a flow and a cut such that the flow saturates all the edges going out of the cut and is zero on all the incoming edges. The proof is based on the paper The Max-Flow Min-Cut theorem for countable networks by Aharoni et al. Additionally, we prove a characterisation of the lifting operation for relations on discrete probability distributions, which leads to a concise proof of its distributivity over relation composition. notify = mail@andreas-lochbihler.de extra-history = Change history: [2017-09-06]: derive characterisation for the lifting operations on discrete distributions from finite version of the max-flow min-cut theorem (revision a7a198f5bab0)
[2020-12-19]: simpler proof of linkability for bounded unhindered bipartite webs, leading to a simpler proof for networks with bounded out-capacities (revision 93ca33f4d915)
[Liouville_Numbers] title = Liouville numbers author = Manuel Eberl date = 2015-12-28 topic = Mathematics/Analysis, Mathematics/Number theory abstract =

Liouville numbers are a class of transcendental numbers that can be approximated particularly well with rational numbers. Historically, they were the first numbers whose transcendence was proven.

In this entry, we define the concept of Liouville numbers as well as the standard construction to obtain Liouville numbers (including Liouville's constant) and we prove their most important properties: irrationality and transcendence.

The proof is very elementary and requires only standard arithmetic, the Mean Value Theorem for polynomials, and the boundedness of polynomials on compact intervals.

notify = eberlm@in.tum.de [Triangle] title = Basic Geometric Properties of Triangles author = Manuel Eberl date = 2015-12-28 topic = Mathematics/Geometry abstract =

This entry contains a definition of angles between vectors and between three points. Building on this, we prove basic geometric properties of triangles, such as the Isosceles Triangle Theorem, the Law of Sines and the Law of Cosines, that the sum of the angles of a triangle is π, and the congruence theorems for triangles.

The definitions and proofs were developed following those by John Harrison in HOL Light. However, due to Isabelle's type class system, all definitions and theorems in the Isabelle formalisation hold for all real inner product spaces.

notify = eberlm@in.tum.de [Prime_Harmonic_Series] title = The Divergence of the Prime Harmonic Series author = Manuel Eberl date = 2015-12-28 topic = Mathematics/Number theory abstract =

In this work, we prove the lower bound ln(H_n) - ln(5/3) for the partial sum of the Prime Harmonic series and, based on this, the divergence of the Prime Harmonic Series ∑[p prime] · 1/p.

The proof relies on the unique squarefree decomposition of natural numbers. This is similar to Euler's original proof (which was highly informal and morally questionable). Its advantage over proofs by contradiction, like the famous one by Paul Erdős, is that it provides a relatively good lower bound for the partial sums.

notify = eberlm@in.tum.de [Descartes_Sign_Rule] title = Descartes' Rule of Signs author = Manuel Eberl date = 2015-12-28 topic = Mathematics/Analysis abstract =

Descartes' Rule of Signs relates the number of positive real roots of a polynomial with the number of sign changes in its coefficient sequence.

Our proof follows the simple inductive proof given by Rob Arthan, which was also used by John Harrison in his HOL Light formalisation. We proved most of the lemmas for arbitrary linearly-ordered integrity domains (e.g. integers, rationals, reals); the main result, however, requires the intermediate value theorem and was therefore only proven for real polynomials.

notify = eberlm@in.tum.de [Euler_MacLaurin] title = The Euler–MacLaurin Formula author = Manuel Eberl topic = Mathematics/Analysis date = 2017-03-10 notify = eberlm@in.tum.de abstract =

The Euler-MacLaurin formula relates the value of a discrete sum to that of the corresponding integral in terms of the derivatives at the borders of the summation and a remainder term. Since the remainder term is often very small as the summation bounds grow, this can be used to compute asymptotic expansions for sums.

This entry contains a proof of this formula for functions from the reals to an arbitrary Banach space. Two variants of the formula are given: the standard textbook version and a variant outlined in Concrete Mathematics that is more useful for deriving asymptotic estimates.

As example applications, we use that formula to derive the full asymptotic expansion of the harmonic numbers and the sum of inverse squares.

[Card_Partitions] title = Cardinality of Set Partitions author = Lukas Bulwahn date = 2015-12-12 topic = Mathematics/Combinatorics abstract = The theory's main theorem states that the cardinality of set partitions of size k on a carrier set of size n is expressed by Stirling numbers of the second kind. In Isabelle, Stirling numbers of the second kind are defined in the AFP entry `Discrete Summation` through their well-known recurrence relation. The main theorem relates them to the alternative definition as cardinality of set partitions. The proof follows the simple and short explanation in Richard P. Stanley's `Enumerative Combinatorics: Volume 1` and Wikipedia, and unravels the full details and implicit reasoning steps of these explanations. notify = lukas.bulwahn@gmail.com [Card_Number_Partitions] title = Cardinality of Number Partitions author = Lukas Bulwahn date = 2016-01-14 topic = Mathematics/Combinatorics abstract = This entry provides a basic library for number partitions, defines the two-argument partition function through its recurrence relation and relates this partition function to the cardinality of number partitions. The main proof shows that the recursively-defined partition function with arguments n and k equals the cardinality of number partitions of n with exactly k parts. The combinatorial proof follows the proof sketch of Theorem 2.4.1 in Mazur's textbook `Combinatorics: A Guided Tour`. This entry can serve as starting point for various more intrinsic properties about number partitions, the partition function and related recurrence relations. notify = lukas.bulwahn@gmail.com [Multirelations] title = Binary Multirelations author = Hitoshi Furusawa , Georg Struth date = 2015-06-11 topic = Mathematics/Algebra abstract = Binary multirelations associate elements of a set with its subsets; hence they are binary relations from a set to its power set. Applications include alternating automata, models and logics for games, program semantics with dual demonic and angelic nondeterministic choices and concurrent dynamic logics. This proof document supports an arXiv article that formalises the basic algebra of multirelations and proposes axiom systems for them, ranging from weak bi-monoids to weak bi-quantales. notify = [Noninterference_Generic_Unwinding] title = The Generic Unwinding Theorem for CSP Noninterference Security author = Pasquale Noce date = 2015-06-11 topic = Computer science/Security, Computer science/Concurrency/Process calculi abstract =

The classical definition of noninterference security for a deterministic state machine with outputs requires to consider the outputs produced by machine actions after any trace, i.e. any indefinitely long sequence of actions, of the machine. In order to render the verification of the security of such a machine more straightforward, there is a need of some sufficient condition for security such that just individual actions, rather than unbounded sequences of actions, have to be considered.

By extending previous results applying to transitive noninterference policies, Rushby has proven an unwinding theorem that provides a sufficient condition of this kind in the general case of a possibly intransitive policy. This condition has to be satisfied by a generic function mapping security domains into equivalence relations over machine states.

An analogous problem arises for CSP noninterference security, whose definition requires to consider any possible future, i.e. any indefinitely long sequence of subsequent events and any indefinitely large set of refused events associated to that sequence, for each process trace.

This paper provides a sufficient condition for CSP noninterference security, which indeed requires to just consider individual accepted and refused events and applies to the general case of a possibly intransitive policy. This condition follows Rushby's one for classical noninterference security, and has to be satisfied by a generic function mapping security domains into equivalence relations over process traces; hence its name, Generic Unwinding Theorem. Variants of this theorem applying to deterministic processes and trace set processes are also proven. Finally, the sufficient condition for security expressed by the theorem is shown not to be a necessary condition as well, viz. there exists a secure process such that no domain-relation map satisfying the condition exists.

notify = [Noninterference_Ipurge_Unwinding] title = The Ipurge Unwinding Theorem for CSP Noninterference Security author = Pasquale Noce date = 2015-06-11 topic = Computer science/Security abstract =

The definition of noninterference security for Communicating Sequential Processes requires to consider any possible future, i.e. any indefinitely long sequence of subsequent events and any indefinitely large set of refused events associated to that sequence, for each process trace. In order to render the verification of the security of a process more straightforward, there is a need of some sufficient condition for security such that just individual accepted and refused events, rather than unbounded sequences and sets of events, have to be considered.

Of course, if such a sufficient condition were necessary as well, it would be even more valuable, since it would permit to prove not only that a process is secure by verifying that the condition holds, but also that a process is not secure by verifying that the condition fails to hold.

This paper provides a necessary and sufficient condition for CSP noninterference security, which indeed requires to just consider individual accepted and refused events and applies to the general case of a possibly intransitive policy. This condition follows Rushby's output consistency for deterministic state machines with outputs, and has to be satisfied by a specific function mapping security domains into equivalence relations over process traces. The definition of this function makes use of an intransitive purge function following Rushby's one; hence the name given to the condition, Ipurge Unwinding Theorem.

Furthermore, in accordance with Hoare's formal definition of deterministic processes, it is shown that a process is deterministic just in case it is a trace set process, i.e. it may be identified by means of a trace set alone, matching the set of its traces, in place of a failures-divergences pair. Then, variants of the Ipurge Unwinding Theorem are proven for deterministic processes and trace set processes.

notify = [Relational_Method] title = The Relational Method with Message Anonymity for the Verification of Cryptographic Protocols author = Pasquale Noce topic = Computer science/Security date = 2020-12-05 notify = pasquale.noce.lavoro@gmail.com abstract = This paper introduces a new method for the formal verification of cryptographic protocols, the relational method, derived from Paulson's inductive method by means of some enhancements aimed at streamlining formal definitions and proofs, specially for protocols using public key cryptography. Moreover, this paper proposes a method to formalize a further security property, message anonymity, in addition to message confidentiality and authenticity. The relational method, including message anonymity, is then applied to the verification of a sample authentication protocol, comprising Password Authenticated Connection Establishment (PACE) with Chip Authentication Mapping followed by the explicit verification of an additional password over the PACE secure channel. [List_Interleaving] title = Reasoning about Lists via List Interleaving author = Pasquale Noce date = 2015-06-11 topic = Computer science/Data structures abstract =

Among the various mathematical tools introduced in his outstanding work on Communicating Sequential Processes, Hoare has defined "interleaves" as the predicate satisfied by any three lists such that the first list may be split into sublists alternately extracted from the other two ones, whatever is the criterion for extracting an item from either one list or the other in each step.

This paper enriches Hoare's definition by identifying such criterion with the truth value of a predicate taking as inputs the head and the tail of the first list. This enhanced "interleaves" predicate turns out to permit the proof of equalities between lists without the need of an induction. Some rules that allow to infer "interleaves" statements without induction, particularly applying to the addition or removal of a prefix to the input lists, are also proven. Finally, a stronger version of the predicate, named "Interleaves", is shown to fulfil further rules applying to the addition or removal of a suffix to the input lists.

notify = [Residuated_Lattices] title = Residuated Lattices author = Victor B. F. Gomes , Georg Struth date = 2015-04-15 topic = Mathematics/Algebra abstract = The theory of residuated lattices, first proposed by Ward and Dilworth, is formalised in Isabelle/HOL. This includes concepts of residuated functions; their adjoints and conjugates. It also contains necessary and sufficient conditions for the existence of these operations in an arbitrary lattice. The mathematical components for residuated lattices are linked to the AFP entry for relation algebra. In particular, we prove Jonsson and Tsinakis conditions for a residuated boolean algebra to form a relation algebra. notify = g.struth@sheffield.ac.uk [ConcurrentGC] title = Relaxing Safely: Verified On-the-Fly Garbage Collection for x86-TSO author = Peter Gammie , Tony Hosking , Kai Engelhardt <> date = 2015-04-13 topic = Computer science/Algorithms/Concurrent abstract =

We use ConcurrentIMP to model Schism, a state-of-the-art real-time garbage collection scheme for weak memory, and show that it is safe on x86-TSO.

This development accompanies the PLDI 2015 paper of the same name.

notify = peteg42@gmail.com [List_Update] title = Analysis of List Update Algorithms author = Maximilian P.L. Haslbeck , Tobias Nipkow date = 2016-02-17 topic = Computer science/Algorithms/Online abstract =

These theories formalize the quantitative analysis of a number of classical algorithms for the list update problem: 2-competitiveness of move-to-front, the lower bound of 2 for the competitiveness of deterministic list update algorithms and 1.6-competitiveness of the randomized COMB algorithm, the best randomized list update algorithm known to date. The material is based on the first two chapters of Online Computation and Competitive Analysis by Borodin and El-Yaniv.

For an informal description see the FSTTCS 2016 publication Verified Analysis of List Update Algorithms by Haslbeck and Nipkow.

notify = nipkow@in.tum.de [ConcurrentIMP] title = Concurrent IMP author = Peter Gammie date = 2015-04-13 topic = Computer science/Programming languages/Logics abstract = ConcurrentIMP extends the small imperative language IMP with control non-determinism and constructs for synchronous message passing. notify = peteg42@gmail.com [TortoiseHare] title = The Tortoise and Hare Algorithm author = Peter Gammie date = 2015-11-18 topic = Computer science/Algorithms abstract = We formalize the Tortoise and Hare cycle-finding algorithm ascribed to Floyd by Knuth, and an improved version due to Brent. notify = peteg42@gmail.com [UPF] title = The Unified Policy Framework (UPF) author = Achim D. Brucker , Lukas Brügger , Burkhart Wolff date = 2014-11-28 topic = Computer science/Security abstract = We present the Unified Policy Framework (UPF), a generic framework for modelling security (access-control) policies. UPF emphasizes the view that a policy is a policy decision function that grants or denies access to resources, permissions, etc. In other words, instead of modelling the relations of permitted or prohibited requests directly, we model the concrete function that implements the policy decision point in a system. In more detail, UPF is based on the following four principles: 1) Functional representation of policies, 2) No conflicts are possible, 3) Three-valued decision type (allow, deny, undefined), 4) Output type not containing the decision only. notify = adbrucker@0x5f.org, wolff@lri.fr, lukas.a.bruegger@gmail.com [UPF_Firewall] title = Formal Network Models and Their Application to Firewall Policies author = Achim D. Brucker , Lukas Brügger<>, Burkhart Wolff topic = Computer science/Security, Computer science/Networks date = 2017-01-08 notify = adbrucker@0x5f.org abstract = We present a formal model of network protocols and their application to modeling firewall policies. The formalization is based on the Unified Policy Framework (UPF). The formalization was originally developed with for generating test cases for testing the security configuration actual firewall and router (middle-boxes) using HOL-TestGen. Our work focuses on modeling application level protocols on top of tcp/ip. [AODV] title = Loop freedom of the (untimed) AODV routing protocol author = Timothy Bourke , Peter Höfner date = 2014-10-23 topic = Computer science/Concurrency/Process calculi abstract =

The Ad hoc On-demand Distance Vector (AODV) routing protocol allows the nodes in a Mobile Ad hoc Network (MANET) or a Wireless Mesh Network (WMN) to know where to forward data packets. Such a protocol is ‘loop free’ if it never leads to routing decisions that forward packets in circles.

This development mechanises an existing pen-and-paper proof of loop freedom of AODV. The protocol is modelled in the Algebra of Wireless Networks (AWN), which is the subject of an earlier paper and AFP mechanization. The proof relies on a novel compositional approach for lifting invariants to networks of nodes.

We exploit the mechanization to analyse several variants of AODV and show that Isabelle/HOL can re-establish most proof obligations automatically and identify exactly the steps that are no longer valid.

notify = tim@tbrk.org [Show] title = Haskell's Show Class in Isabelle/HOL author = Christian Sternagel , René Thiemann date = 2014-07-29 topic = Computer science/Functional programming license = LGPL abstract = We implemented a type class for "to-string" functions, similar to Haskell's Show class. Moreover, we provide instantiations for Isabelle/HOL's standard types like bool, prod, sum, nats, ints, and rats. It is further possible, to automatically derive show functions for arbitrary user defined datatypes similar to Haskell's "deriving Show". extra-history = Change history: [2015-03-11]: Adapted development to new-style (BNF-based) datatypes.
[2015-04-10]: Moved development for old-style datatypes into subdirectory "Old_Datatype".
notify = christian.sternagel@uibk.ac.at, rene.thiemann@uibk.ac.at [Certification_Monads] title = Certification Monads author = Christian Sternagel , René Thiemann date = 2014-10-03 topic = Computer science/Functional programming abstract = This entry provides several monads intended for the development of stand-alone certifiers via code generation from Isabelle/HOL. More specifically, there are three flavors of error monads (the sum type, for the case where all monadic functions are total; an instance of the former, the so called check monad, yielding either success without any further information or an error message; as well as a variant of the sum type that accommodates partial functions by providing an explicit bottom element) and a parser monad built on top. All of this monads are heavily used in the IsaFoR/CeTA project which thus provides many examples of their usage. notify = c.sternagel@gmail.com, rene.thiemann@uibk.ac.at [CISC-Kernel] title = Formal Specification of a Generic Separation Kernel author = Freek Verbeek , Sergey Tverdyshev , Oto Havle , Holger Blasum , Bruno Langenstein , Werner Stephan , Yakoub Nemouchi , Abderrahmane Feliachi , Burkhart Wolff , Julien Schmaltz date = 2014-07-18 topic = Computer science/Security abstract =

Intransitive noninterference has been a widely studied topic in the last few decades. Several well-established methodologies apply interactive theorem proving to formulate a noninterference theorem over abstract academic models. In joint work with several industrial and academic partners throughout Europe, we are helping in the certification process of PikeOS, an industrial separation kernel developed at SYSGO. In this process, established theories could not be applied. We present a new generic model of separation kernels and a new theory of intransitive noninterference. The model is rich in detail, making it suitable for formal verification of realistic and industrial systems such as PikeOS. Using a refinement-based theorem proving approach, we ensure that proofs remain manageable.

This document corresponds to the deliverable D31.1 of the EURO-MILS Project http://www.euromils.eu.

notify = [pGCL] title = pGCL for Isabelle author = David Cock date = 2014-07-13 topic = Computer science/Programming languages/Language definitions abstract =

pGCL is both a programming language and a specification language that incorporates both probabilistic and nondeterministic choice, in a unified manner. Program verification is by refinement or annotation (or both), using either Hoare triples, or weakest-precondition entailment, in the style of GCL.

This package provides both a shallow embedding of the language primitives, and an annotation and refinement framework. The generated document includes a brief tutorial.

notify = [Noninterference_CSP] title = Noninterference Security in Communicating Sequential Processes author = Pasquale Noce date = 2014-05-23 topic = Computer science/Security abstract =

An extension of classical noninterference security for deterministic state machines, as introduced by Goguen and Meseguer and elegantly formalized by Rushby, to nondeterministic systems should satisfy two fundamental requirements: it should be based on a mathematically precise theory of nondeterminism, and should be equivalent to (or at least not weaker than) the classical notion in the degenerate deterministic case.

This paper proposes a definition of noninterference security applying to Hoare's Communicating Sequential Processes (CSP) in the general case of a possibly intransitive noninterference policy, and proves the equivalence of this security property to classical noninterference security for processes representing deterministic state machines.

Furthermore, McCullough's generalized noninterference security is shown to be weaker than both the proposed notion of CSP noninterference security for a generic process, and classical noninterference security for processes representing deterministic state machines. This renders CSP noninterference security preferable as an extension of classical noninterference security to nondeterministic systems.

notify = pasquale.noce.lavoro@gmail.com [Floyd_Warshall] title = The Floyd-Warshall Algorithm for Shortest Paths author = Simon Wimmer , Peter Lammich topic = Computer science/Algorithms/Graph date = 2017-05-08 notify = wimmers@in.tum.de abstract = The Floyd-Warshall algorithm [Flo62, Roy59, War62] is a classic dynamic programming algorithm to compute the length of all shortest paths between any two vertices in a graph (i.e. to solve the all-pairs shortest path problem, or APSP for short). Given a representation of the graph as a matrix of weights M, it computes another matrix M' which represents a graph with the same path lengths and contains the length of the shortest path between any two vertices i and j. This is only possible if the graph does not contain any negative cycles. However, in this case the Floyd-Warshall algorithm will detect the situation by calculating a negative diagonal entry. This entry includes a formalization of the algorithm and of these key properties. The algorithm is refined to an efficient imperative version using the Imperative Refinement Framework. [Roy_Floyd_Warshall] title = Transitive closure according to Roy-Floyd-Warshall author = Makarius Wenzel <> date = 2014-05-23 topic = Computer science/Algorithms/Graph abstract = This formulation of the Roy-Floyd-Warshall algorithm for the transitive closure bypasses matrices and arrays, but uses a more direct mathematical model with adjacency functions for immediate predecessors and successors. This can be implemented efficiently in functional programming languages and is particularly adequate for sparse relations. notify = [GPU_Kernel_PL] title = Syntax and semantics of a GPU kernel programming language author = John Wickerson date = 2014-04-03 topic = Computer science/Programming languages/Language definitions abstract = This document accompanies the article "The Design and Implementation of a Verification Technique for GPU Kernels" by Adam Betts, Nathan Chong, Alastair F. Donaldson, Jeroen Ketema, Shaz Qadeer, Paul Thomson and John Wickerson. It formalises all of the definitions provided in Sections 3 and 4 of the article. notify = [AWN] title = Mechanization of the Algebra for Wireless Networks (AWN) author = Timothy Bourke date = 2014-03-08 topic = Computer science/Concurrency/Process calculi abstract =

AWN is a process algebra developed for modelling and analysing protocols for Mobile Ad hoc Networks (MANETs) and Wireless Mesh Networks (WMNs). AWN models comprise five distinct layers: sequential processes, local parallel compositions, nodes, partial networks, and complete networks.

This development mechanises the original operational semantics of AWN and introduces a variant 'open' operational semantics that enables the compositional statement and proof of invariants across distinct network nodes. It supports labels (for weakening invariants) and (abstract) data state manipulations. A framework for compositional invariant proofs is developed, including a tactic (inv_cterms) for inductive invariant proofs of sequential processes, lifting rules for the open versions of the higher layers, and a rule for transferring lifted properties back to the standard semantics. A notion of 'control terms' reduces proof obligations to the subset of subterms that act directly (in contrast to operators for combining terms and joining processes).

notify = tim@tbrk.org [Selection_Heap_Sort] title = Verification of Selection and Heap Sort Using Locales author = Danijela Petrovic date = 2014-02-11 topic = Computer science/Algorithms abstract = Stepwise program refinement techniques can be used to simplify program verification. Programs are better understood since their main properties are clearly stated, and verification of rather complex algorithms is reduced to proving simple statements connecting successive program specifications. Additionally, it is easy to analyze similar algorithms and to compare their properties within a single formalization. Usually, formal analysis is not done in educational setting due to complexity of verification and a lack of tools and procedures to make comparison easy. Verification of an algorithm should not only give correctness proof, but also better understanding of an algorithm. If the verification is based on small step program refinement, it can become simple enough to be demonstrated within the university-level computer science curriculum. In this paper we demonstrate this and give a formal analysis of two well known algorithms (Selection Sort and Heap Sort) using proof assistant Isabelle/HOL and program refinement techniques. notify = [Real_Impl] title = Implementing field extensions of the form Q[sqrt(b)] author = René Thiemann date = 2014-02-06 license = LGPL topic = Mathematics/Analysis abstract = We apply data refinement to implement the real numbers, where we support all numbers in the field extension Q[sqrt(b)], i.e., all numbers of the form p + q * sqrt(b) for rational numbers p and q and some fixed natural number b. To this end, we also developed algorithms to precisely compute roots of a rational number, and to perform a factorization of natural numbers which eliminates duplicate prime factors.

Our results have been used to certify termination proofs which involve polynomial interpretations over the reals. extra-history = Change history: [2014-07-11]: Moved NthRoot_Impl to Sqrt-Babylonian. notify = rene.thiemann@uibk.ac.at [ShortestPath] title = An Axiomatic Characterization of the Single-Source Shortest Path Problem author = Christine Rizkallah date = 2013-05-22 topic = Mathematics/Graph theory abstract = This theory is split into two sections. In the first section, we give a formal proof that a well-known axiomatic characterization of the single-source shortest path problem is correct. Namely, we prove that in a directed graph with a non-negative cost function on the edges the single-source shortest path function is the only function that satisfies a set of four axioms. In the second section, we give a formal proof of the correctness of an axiomatic characterization of the single-source shortest path problem for directed graphs with general cost functions. The axioms here are more involved because we have to account for potential negative cycles in the graph. The axioms are summarized in three Isabelle locales. notify = [Launchbury] title = The Correctness of Launchbury's Natural Semantics for Lazy Evaluation author = Joachim Breitner date = 2013-01-31 topic = Computer science/Programming languages/Lambda calculi, Computer science/Semantics abstract = In his seminal paper "Natural Semantics for Lazy Evaluation", John Launchbury proves his semantics correct with respect to a denotational semantics, and outlines an adequacy proof. We have formalized both semantics and machine-checked the correctness proof, clarifying some details. Furthermore, we provide a new and more direct adequacy proof that does not require intermediate operational semantics. extra-history = Change history: [2014-05-24]: Added the proof of adequacy, as well as simplified and improved the existing proofs. Adjusted abstract accordingly. [2015-03-16]: Booleans and if-then-else added to syntax and semantics, making this entry suitable to be used by the entry "Call_Arity". notify = [Call_Arity] title = The Safety of Call Arity author = Joachim Breitner date = 2015-02-20 topic = Computer science/Programming languages/Transformations abstract = We formalize the Call Arity analysis, as implemented in GHC, and prove both functional correctness and, more interestingly, safety (i.e. the transformation does not increase allocation).

We use syntax and the denotational semantics from the entry "Launchbury", where we formalized Launchbury's natural semantics for lazy evaluation.

The functional correctness of Call Arity is proved with regard to that denotational semantics. The operational properties are shown with regard to a small-step semantics akin to Sestoft's mark 1 machine, which we prove to be equivalent to Launchbury's semantics.

We use Christian Urban's Nominal2 package to define our terms and make use of Brian Huffman's HOLCF package for the domain-theoretical aspects of the development. extra-history = Change history: [2015-03-16]: This entry now builds on top of the Launchbury entry, and the equivalency proof of the natural and the small-step semantics was added. notify = [CCS] title = CCS in nominal logic author = Jesper Bengtson date = 2012-05-29 topic = Computer science/Concurrency/Process calculi abstract = We formalise a large portion of CCS as described in Milner's book 'Communication and Concurrency' using the nominal datatype package in Isabelle. Our results include many of the standard theorems of bisimulation equivalence and congruence, for both weak and strong versions. One main goal of this formalisation is to keep the machine-checked proofs as close to their pen-and-paper counterpart as possible.

This entry is described in detail in Bengtson's thesis. notify = [Pi_Calculus] title = The pi-calculus in nominal logic author = Jesper Bengtson date = 2012-05-29 topic = Computer science/Concurrency/Process calculi abstract = We formalise the pi-calculus using the nominal datatype package, based on ideas from the nominal logic by Pitts et al., and demonstrate an implementation in Isabelle/HOL. The purpose is to derive powerful induction rules for the semantics in order to conduct machine checkable proofs, closely following the intuitive arguments found in manual proofs. In this way we have covered many of the standard theorems of bisimulation equivalence and congruence, both late and early, and both strong and weak in a uniform manner. We thus provide one of the most extensive formalisations of a the pi-calculus ever done inside a theorem prover.

A significant gain in our formulation is that agents are identified up to alpha-equivalence, thereby greatly reducing the arguments about bound names. This is a normal strategy for manual proofs about the pi-calculus, but that kind of hand waving has previously been difficult to incorporate smoothly in an interactive theorem prover. We show how the nominal logic formalism and its support in Isabelle accomplishes this and thus significantly reduces the tedium of conducting completely formal proofs. This improves on previous work using weak higher order abstract syntax since we do not need extra assumptions to filter out exotic terms and can keep all arguments within a familiar first-order logic.

This entry is described in detail in Bengtson's thesis. notify = [Psi_Calculi] title = Psi-calculi in Isabelle author = Jesper Bengtson date = 2012-05-29 topic = Computer science/Concurrency/Process calculi abstract = Psi-calculi are extensions of the pi-calculus, accommodating arbitrary nominal datatypes to represent not only data but also communication channels, assertions and conditions, giving it an expressive power beyond the applied pi-calculus and the concurrent constraint pi-calculus.

We have formalised psi-calculi in the interactive theorem prover Isabelle using its nominal datatype package. One distinctive feature is that the framework needs to treat binding sequences, as opposed to single binders, in an efficient way. While different methods for formalising single binder calculi have been proposed over the last decades, representations for such binding sequences are not very well explored.

The main effort in the formalisation is to keep the machine checked proofs as close to their pen-and-paper counterparts as possible. This includes treating all binding sequences as atomic elements, and creating custom induction and inversion rules that to remove the bulk of manual alpha-conversions.

This entry is described in detail in Bengtson's thesis. notify = [Encodability_Process_Calculi] title = Analysing and Comparing Encodability Criteria for Process Calculi author = Kirstin Peters , Rob van Glabbeek date = 2015-08-10 topic = Computer science/Concurrency/Process calculi abstract = Encodings or the proof of their absence are the main way to compare process calculi. To analyse the quality of encodings and to rule out trivial or meaningless encodings, they are augmented with quality criteria. There exists a bunch of different criteria and different variants of criteria in order to reason in different settings. This leads to incomparable results. Moreover it is not always clear whether the criteria used to obtain a result in a particular setting do indeed fit to this setting. We show how to formally reason about and compare encodability criteria by mapping them on requirements on a relation between source and target terms that is induced by the encoding function. In particular we analyse the common criteria full abstraction, operational correspondence, divergence reflection, success sensitiveness, and respect of barbs; e.g. we analyse the exact nature of the simulation relation (coupled simulation versus bisimulation) that is induced by different variants of operational correspondence. This way we reduce the problem of analysing or comparing encodability criteria to the better understood problem of comparing relations on processes. notify = kirstin.peters@tu-berlin.de [Circus] title = Isabelle/Circus author = Abderrahmane Feliachi , Burkhart Wolff , Marie-Claude Gaudel contributors = Makarius Wenzel date = 2012-05-27 topic = Computer science/Concurrency/Process calculi, Computer science/System description languages abstract = The Circus specification language combines elements for complex data and behavior specifications, using an integration of Z and CSP with a refinement calculus. Its semantics is based on Hoare and He's Unifying Theories of Programming (UTP). Isabelle/Circus is a formalization of the UTP and the Circus language in Isabelle/HOL. It contains proof rules and tactic support that allows for proofs of refinement for Circus processes (involving both data and behavioral aspects).

The Isabelle/Circus environment supports a syntax for the semantic definitions which is close to textbook presentations of Circus. This article contains an extended version of corresponding VSTTE Paper together with the complete formal development of its underlying commented theories. extra-history = Change history: [2014-06-05]: More polishing, shorter proofs, added Circus syntax, added Makarius Wenzel as contributor. notify = [Dijkstra_Shortest_Path] title = Dijkstra's Shortest Path Algorithm author = Benedikt Nordhoff , Peter Lammich topic = Computer science/Algorithms/Graph date = 2012-01-30 abstract = We implement and prove correct Dijkstra's algorithm for the single source shortest path problem, conceived in 1956 by E. Dijkstra. The algorithm is implemented using the data refinement framework for monadic, nondeterministic programs. An efficient implementation is derived using data structures from the Isabelle Collection Framework. notify = lammich@in.tum.de [Refine_Monadic] title = Refinement for Monadic Programs author = Peter Lammich topic = Computer science/Programming languages/Logics date = 2012-01-30 abstract = We provide a framework for program and data refinement in Isabelle/HOL. The framework is based on a nondeterminism-monad with assertions, i.e., the monad carries a set of results or an assertion failure. Recursion is expressed by fixed points. For convenience, we also provide while and foreach combinators.

The framework provides tools to automatize canonical tasks, such as verification condition generation, finding appropriate data refinement relations, and refine an executable program to a form that is accepted by the Isabelle/HOL code generator.

This submission comes with a collection of examples and a user-guide, illustrating the usage of the framework. extra-history = Change history: [2012-04-23] Introduced ordered FOREACH loops
[2012-06] New features: REC_rule_arb and RECT_rule_arb allow for generalizing over variables. prepare_code_thms - command extracts code equations for recursion combinators.
[2012-07] New example: Nested DFS for emptiness check of Buchi-automata with witness.
New feature: fo_rule method to apply resolution using first-order matching. Useful for arg_conf, fun_cong.
[2012-08] Adaptation to ICF v2.
[2012-10-05] Adaptations to include support for Automatic Refinement Framework.
[2013-09] This entry now depends on Automatic Refinement
[2014-06] New feature: vc_solve method to solve verification conditions. Maintenace changes: VCG-rules for nfoldli, improved setup for FOREACH-loops.
[2014-07] Now defining recursion via flat domain. Dropped many single-valued prerequisites. Changed notion of data refinement. In single-valued case, this matches the old notion. In non-single valued case, the new notion allows for more convenient rules. In particular, the new definitions allow for projecting away ghost variables as a refinement step.
[2014-11] New features: le-or-fail relation (leof), modular reasoning about loop invariants. notify = lammich@in.tum.de [Refine_Imperative_HOL] title = The Imperative Refinement Framework author = Peter Lammich notify = lammich@in.tum.de date = 2016-08-08 topic = Computer science/Programming languages/Transformations,Computer science/Data structures abstract = We present the Imperative Refinement Framework (IRF), a tool that supports a stepwise refinement based approach to imperative programs. This entry is based on the material we presented in [ITP-2015, CPP-2016]. It uses the Monadic Refinement Framework as a frontend for the specification of the abstract programs, and Imperative/HOL as a backend to generate executable imperative programs. The IRF comes with tool support to synthesize imperative programs from more abstract, functional ones, using efficient imperative implementations for the abstract data structures. This entry also includes the Imperative Isabelle Collection Framework (IICF), which provides a library of re-usable imperative collection data structures. Moreover, this entry contains a quickstart guide and a reference manual, which provide an introduction to using the IRF for Isabelle/HOL experts. It also provids a collection of (partly commented) practical examples, some highlights being Dijkstra's Algorithm, Nested-DFS, and a generic worklist algorithm with subsumption. Finally, this entry contains benchmark scripts that compare the runtime of some examples against reference implementations of the algorithms in Java and C++. [ITP-2015] Peter Lammich: Refinement to Imperative/HOL. ITP 2015: 253--269 [CPP-2016] Peter Lammich: Refinement based verification of imperative data structures. CPP 2016: 27--36 [Automatic_Refinement] title = Automatic Data Refinement author = Peter Lammich topic = Computer science/Programming languages/Logics date = 2013-10-02 abstract = We present the Autoref tool for Isabelle/HOL, which automatically refines algorithms specified over abstract concepts like maps and sets to algorithms over concrete implementations like red-black-trees, and produces a refinement theorem. It is based on ideas borrowed from relational parametricity due to Reynolds and Wadler. The tool allows for rapid prototyping of verified, executable algorithms. Moreover, it can be configured to fine-tune the result to the user~s needs. Our tool is able to automatically instantiate generic algorithms, which greatly simplifies the implementation of executable data structures.

This AFP-entry provides the basic tool, which is then used by the Refinement and Collection Framework to provide automatic data refinement for the nondeterminism monad and various collection datastructures. notify = lammich@in.tum.de [EdmondsKarp_Maxflow] title = Formalizing the Edmonds-Karp Algorithm author = Peter Lammich , S. Reza Sefidgar<> notify = lammich@in.tum.de date = 2016-08-12 topic = Computer science/Algorithms/Graph abstract = We present a formalization of the Ford-Fulkerson method for computing the maximum flow in a network. Our formal proof closely follows a standard textbook proof, and is accessible even without being an expert in Isabelle/HOL--- the interactive theorem prover used for the formalization. We then use stepwise refinement to obtain the Edmonds-Karp algorithm, and formally prove a bound on its complexity. Further refinement yields a verified implementation, whose execution time compares well to an unverified reference implementation in Java. This entry is based on our ITP-2016 paper with the same title. [VerifyThis2018] title = VerifyThis 2018 - Polished Isabelle Solutions author = Peter Lammich , Simon Wimmer topic = Computer science/Algorithms date = 2018-04-27 notify = lammich@in.tum.de abstract = VerifyThis 2018 was a program verification competition associated with ETAPS 2018. It was the 7th event in the VerifyThis competition series. In this entry, we present polished and completed versions of our solutions that we created during the competition. [PseudoHoops] title = Pseudo Hoops author = George Georgescu <>, Laurentiu Leustean <>, Viorel Preoteasa topic = Mathematics/Algebra date = 2011-09-22 abstract = Pseudo-hoops are algebraic structures introduced by B. Bosbach under the name of complementary semigroups. In this formalization we prove some properties of pseudo-hoops and we define the basic concepts of filter and normal filter. The lattice of normal filters is isomorphic with the lattice of congruences of a pseudo-hoop. We also study some important classes of pseudo-hoops. Bounded Wajsberg pseudo-hoops are equivalent to pseudo-Wajsberg algebras and bounded basic pseudo-hoops are equivalent to pseudo-BL algebras. Some examples of pseudo-hoops are given in the last section of the formalization. notify = viorel.preoteasa@aalto.fi [MonoBoolTranAlgebra] title = Algebra of Monotonic Boolean Transformers author = Viorel Preoteasa topic = Computer science/Programming languages/Logics date = 2011-09-22 abstract = Algebras of imperative programming languages have been successful in reasoning about programs. In general an algebra of programs is an algebraic structure with programs as elements and with program compositions (sequential composition, choice, skip) as algebra operations. Various versions of these algebras were introduced to model partial correctness, total correctness, refinement, demonic choice, and other aspects. We formalize here an algebra which can be used to model total correctness, refinement, demonic and angelic choice. The basic model of this algebra are monotonic Boolean transformers (monotonic functions from a Boolean algebra to itself). notify = viorel.preoteasa@aalto.fi [LatticeProperties] title = Lattice Properties author = Viorel Preoteasa topic = Mathematics/Order date = 2011-09-22 abstract = This formalization introduces and collects some algebraic structures based on lattices and complete lattices for use in other developments. The structures introduced are modular, and lattice ordered groups. In addition to the results proved for the new lattices, this formalization also introduces theorems about latices and complete lattices in general. extra-history = Change history: [2012-01-05]: Removed the theory about distributive complete lattices which is in the standard library now. Added a theory about well founded and transitive relations and a result about fixpoints in complete lattices and well founded relations. Moved the results about conjunctive and disjunctive functions to a new theory. Removed the syntactic classes for inf and sup which are in the standard library now. notify = viorel.preoteasa@aalto.fi [Impossible_Geometry] title = Proving the Impossibility of Trisecting an Angle and Doubling the Cube author = Ralph Romanos , Lawrence C. Paulson topic = Mathematics/Algebra, Mathematics/Geometry date = 2012-08-05 abstract = Squaring the circle, doubling the cube and trisecting an angle, using a compass and straightedge alone, are classic unsolved problems first posed by the ancient Greeks. All three problems were proved to be impossible in the 19th century. The following document presents the proof of the impossibility of solving the latter two problems using Isabelle/HOL, following a proof by Carrega. The proof uses elementary methods: no Galois theory or field extensions. The set of points constructible using a compass and straightedge is defined inductively. Radical expressions, which involve only square roots and arithmetic of rational numbers, are defined, and we find that all constructive points have radical coordinates. Finally, doubling the cube and trisecting certain angles requires solving certain cubic equations that can be proved to have no rational roots. The Isabelle proofs require a great many detailed calculations. notify = ralph.romanos@student.ecp.fr, lp15@cam.ac.uk [IP_Addresses] title = IP Addresses author = Cornelius Diekmann , Julius Michaelis , Lars Hupel notify = diekmann@net.in.tum.de date = 2016-06-28 topic = Computer science/Networks abstract = This entry contains a definition of IP addresses and a library to work with them. Generic IP addresses are modeled as machine words of arbitrary length. Derived from this generic definition, IPv4 addresses are 32bit machine words, IPv6 addresses are 128bit words. Additionally, IPv4 addresses can be represented in dot-decimal notation and IPv6 addresses in (compressed) colon-separated notation. We support toString functions and parsers for both notations. Sets of IP addresses can be represented with a netmask (e.g. 192.168.0.0/255.255.0.0) or in CIDR notation (e.g. 192.168.0.0/16). To provide executable code for set operations on IP address ranges, the library includes a datatype to work on arbitrary intervals of machine words. [Simple_Firewall] title = Simple Firewall author = Cornelius Diekmann , Julius Michaelis , Maximilian Haslbeck notify = diekmann@net.in.tum.de, max.haslbeck@gmx.de date = 2016-08-24 topic = Computer science/Networks abstract = We present a simple model of a firewall. The firewall can accept or drop a packet and can match on interfaces, IP addresses, protocol, and ports. It was designed to feature nice mathematical properties: The type of match expressions was carefully crafted such that the conjunction of two match expressions is only one match expression. This model is too simplistic to mirror all aspects of the real world. In the upcoming entry "Iptables Semantics", we will translate the Linux firewall iptables to this model. For a fixed service (e.g. ssh, http), we provide an algorithm to compute an overview of the firewall's filtering behavior. The algorithm computes minimal service matrices, i.e. graphs which partition the complete IPv4 and IPv6 address space and visualize the allowed accesses between partitions. For a detailed description, see Verified iptables Firewall Analysis, IFIP Networking 2016. [Iptables_Semantics] title = Iptables Semantics author = Cornelius Diekmann , Lars Hupel notify = diekmann@net.in.tum.de, hupel@in.tum.de date = 2016-09-09 topic = Computer science/Networks abstract = We present a big step semantics of the filtering behavior of the Linux/netfilter iptables firewall. We provide algorithms to simplify complex iptables rulests to a simple firewall model (c.f. AFP entry Simple_Firewall) and to verify spoofing protection of a ruleset. Internally, we embed our semantics into ternary logic, ultimately supporting every iptables match condition by abstracting over unknowns. Using this AFP entry and all entries it depends on, we created an easy-to-use, stand-alone haskell tool called fffuu. The tool does not require any input —except for the iptables-save dump of the analyzed firewall— and presents interesting results about the user's ruleset. Real-Word firewall errors have been uncovered, and the correctness of rulesets has been proved, with the help of our tool. [Routing] title = Routing author = Julius Michaelis , Cornelius Diekmann notify = afp@liftm.de date = 2016-08-31 topic = Computer science/Networks abstract = This entry contains definitions for routing with routing tables/longest prefix matching. A routing table entry is modelled as a record of a prefix match, a metric, an output port, and an optional next hop. A routing table is a list of entries, sorted by prefix length and metric. Additionally, a parser and serializer for the output of the ip-route command, a function to create a relation from output port to corresponding destination IP space, and a model of a Linux-style router are included. [KBPs] title = Knowledge-based programs author = Peter Gammie topic = Computer science/Automata and formal languages date = 2011-05-17 abstract = Knowledge-based programs (KBPs) are a formalism for directly relating agents' knowledge and behaviour. Here we present a general scheme for compiling KBPs to executable automata with a proof of correctness in Isabelle/HOL. We develop the algorithm top-down, using Isabelle's locale mechanism to structure these proofs, and show that two classic examples can be synthesised using Isabelle's code generator. extra-history = Change history: [2012-03-06]: Add some more views and revive the code generation. notify = kleing@cse.unsw.edu.au [Tarskis_Geometry] title = The independence of Tarski's Euclidean axiom author = T. J. M. Makarios topic = Mathematics/Geometry date = 2012-10-30 abstract = Tarski's axioms of plane geometry are formalized and, using the standard real Cartesian model, shown to be consistent. A substantial theory of the projective plane is developed. Building on this theory, the Klein-Beltrami model of the hyperbolic plane is defined and shown to satisfy all of Tarski's axioms except his Euclidean axiom; thus Tarski's Euclidean axiom is shown to be independent of his other axioms of plane geometry.

An earlier version of this work was the subject of the author's MSc thesis, which contains natural-language explanations of some of the more interesting proofs. notify = tjm1983@gmail.com [General-Triangle] title = The General Triangle Is Unique author = Joachim Breitner topic = Mathematics/Geometry date = 2011-04-01 abstract = Some acute-angled triangles are special, e.g. right-angled or isoscele triangles. Some are not of this kind, but, without measuring angles, look as if they were. In that sense, there is exactly one general triangle. This well-known fact is proven here formally. notify = mail@joachim-breitner.de [LightweightJava] title = Lightweight Java author = Rok Strniša , Matthew Parkinson topic = Computer science/Programming languages/Language definitions date = 2011-02-07 abstract = A fully-formalized and extensible minimal imperative fragment of Java. notify = rok@strnisa.com [Lower_Semicontinuous] title = Lower Semicontinuous Functions author = Bogdan Grechuk topic = Mathematics/Analysis date = 2011-01-08 abstract = We define the notions of lower and upper semicontinuity for functions from a metric space to the extended real line. We prove that a function is both lower and upper semicontinuous if and only if it is continuous. We also give several equivalent characterizations of lower semicontinuity. In particular, we prove that a function is lower semicontinuous if and only if its epigraph is a closed set. Also, we introduce the notion of the lower semicontinuous hull of an arbitrary function and prove its basic properties. notify = hoelzl@in.tum.de [RIPEMD-160-SPARK] title = RIPEMD-160 author = Fabian Immler topic = Computer science/Programming languages/Static analysis date = 2011-01-10 abstract = This work presents a verification of an implementation in SPARK/ADA of the cryptographic hash-function RIPEMD-160. A functional specification of RIPEMD-160 is given in Isabelle/HOL. Proofs for the verification conditions generated by the static-analysis toolset of SPARK certify the functional correctness of the implementation. extra-history = Change history: [2015-11-09]: Entry is now obsolete, moved to Isabelle distribution. notify = immler@in.tum.de [Regular-Sets] title = Regular Sets and Expressions author = Alexander Krauss , Tobias Nipkow contributors = Manuel Eberl topic = Computer science/Automata and formal languages date = 2010-05-12 abstract = This is a library of constructions on regular expressions and languages. It provides the operations of concatenation, Kleene star and derivative on languages. Regular expressions and their meaning are defined. An executable equivalence checker for regular expressions is verified; it does not need automata but works directly on regular expressions. By mapping regular expressions to binary relations, an automatic and complete proof method for (in)equalities of binary relations over union, concatenation and (reflexive) transitive closure is obtained.

Extended regular expressions with complement and intersection are also defined and an equivalence checker is provided. extra-history = Change history: [2011-08-26]: Christian Urban added a theory about derivatives and partial derivatives of regular expressions
[2012-05-10]: Tobias Nipkow added extended regular expressions
[2012-05-10]: Tobias Nipkow added equivalence checking with partial derivatives notify = nipkow@in.tum.de, krauss@in.tum.de, christian.urban@kcl.ac.uk [Regex_Equivalence] title = Unified Decision Procedures for Regular Expression Equivalence author = Tobias Nipkow , Dmitriy Traytel topic = Computer science/Automata and formal languages date = 2014-01-30 abstract = We formalize a unified framework for verified decision procedures for regular expression equivalence. Five recently published formalizations of such decision procedures (three based on derivatives, two on marked regular expressions) can be obtained as instances of the framework. We discover that the two approaches based on marked regular expressions, which were previously thought to be the same, are different, and one seems to produce uniformly smaller automata. The common framework makes it possible to compare the performance of the different decision procedures in a meaningful way. The formalization is described in a paper of the same name presented at Interactive Theorem Proving 2014. notify = nipkow@in.tum.de, traytel@in.tum.de [MSO_Regex_Equivalence] title = Decision Procedures for MSO on Words Based on Derivatives of Regular Expressions author = Dmitriy Traytel , Tobias Nipkow topic = Computer science/Automata and formal languages, Logic/General logic/Decidability of theories date = 2014-06-12 abstract = Monadic second-order logic on finite words (MSO) is a decidable yet expressive logic into which many decision problems can be encoded. Since MSO formulas correspond to regular languages, equivalence of MSO formulas can be reduced to the equivalence of some regular structures (e.g. automata). We verify an executable decision procedure for MSO formulas that is not based on automata but on regular expressions.

Decision procedures for regular expression equivalence have been formalized before, usually based on Brzozowski derivatives. Yet, for a straightforward embedding of MSO formulas into regular expressions an extension of regular expressions with a projection operation is required. We prove total correctness and completeness of an equivalence checker for regular expressions extended in that way. We also define a language-preserving translation of formulas into regular expressions with respect to two different semantics of MSO.

The formalization is described in this ICFP 2013 functional pearl. notify = traytel@in.tum.de, nipkow@in.tum.de [Formula_Derivatives] title = Derivatives of Logical Formulas author = Dmitriy Traytel topic = Computer science/Automata and formal languages, Logic/General logic/Decidability of theories date = 2015-05-28 abstract = We formalize new decision procedures for WS1S, M2L(Str), and Presburger Arithmetics. Formulas of these logics denote regular languages. Unlike traditional decision procedures, we do not translate formulas into automata (nor into regular expressions), at least not explicitly. Instead we devise notions of derivatives (inspired by Brzozowski derivatives for regular expressions) that operate on formulas directly and compute a syntactic bisimulation using these derivatives. The treatment of Boolean connectives and quantifiers is uniform for all mentioned logics and is abstracted into a locale. This locale is then instantiated by different atomic formulas and their derivatives (which may differ even for the same logic under different encodings of interpretations as formal words).

The WS1S instance is described in the draft paper A Coalgebraic Decision Procedure for WS1S by the author. notify = traytel@in.tum.de [Myhill-Nerode] title = The Myhill-Nerode Theorem Based on Regular Expressions author = Chunhan Wu <>, Xingyuan Zhang <>, Christian Urban contributors = Manuel Eberl topic = Computer science/Automata and formal languages date = 2011-08-26 abstract = There are many proofs of the Myhill-Nerode theorem using automata. In this library we give a proof entirely based on regular expressions, since regularity of languages can be conveniently defined using regular expressions (it is more painful in HOL to define regularity in terms of automata). We prove the first direction of the Myhill-Nerode theorem by solving equational systems that involve regular expressions. For the second direction we give two proofs: one using tagging-functions and another using partial derivatives. We also establish various closure properties of regular languages. Most details of the theories are described in our ITP 2011 paper. notify = christian.urban@kcl.ac.uk [Universal_Turing_Machine] title = Universal Turing Machine author = Jian Xu<>, Xingyuan Zhang<>, Christian Urban , Sebastiaan J. C. Joosten topic = Logic/Computability, Computer science/Automata and formal languages date = 2019-02-08 notify = sjcjoosten@gmail.com, christian.urban@kcl.ac.uk abstract = We formalise results from computability theory: recursive functions, undecidability of the halting problem, and the existence of a universal Turing machine. This formalisation is the AFP entry corresponding to the paper Mechanising Turing Machines and Computability Theory in Isabelle/HOL, ITP 2013. [CYK] title = A formalisation of the Cocke-Younger-Kasami algorithm author = Maksym Bortin date = 2016-04-27 topic = Computer science/Algorithms, Computer science/Automata and formal languages abstract = The theory provides a formalisation of the Cocke-Younger-Kasami algorithm (CYK for short), an approach to solving the word problem for context-free languages. CYK decides if a word is in the languages generated by a context-free grammar in Chomsky normal form. The formalized algorithm is executable. notify = maksym.bortin@nicta.com.au [Boolean_Expression_Checkers] title = Boolean Expression Checkers author = Tobias Nipkow date = 2014-06-08 topic = Computer science/Algorithms, Logic/General logic/Mechanization of proofs abstract = This entry provides executable checkers for the following properties of boolean expressions: satisfiability, tautology and equivalence. Internally, the checkers operate on binary decision trees and are reasonably efficient (for purely functional algorithms). extra-history = Change history: [2015-09-23]: Salomon Sickert added an interface that does not require the usage of the Boolean formula datatype. Furthermore the general Mapping type is used instead of an association list. notify = nipkow@in.tum.de [Presburger-Automata] title = Formalizing the Logic-Automaton Connection author = Stefan Berghofer , Markus Reiter <> date = 2009-12-03 topic = Computer science/Automata and formal languages, Logic/General logic/Decidability of theories abstract = This work presents a formalization of a library for automata on bit strings. It forms the basis of a reflection-based decision procedure for Presburger arithmetic, which is efficiently executable thanks to Isabelle's code generator. With this work, we therefore provide a mechanized proof of a well-known connection between logic and automata theory. The formalization is also described in a publication [TPHOLs 2009]. notify = berghofe@in.tum.de [Functional-Automata] title = Functional Automata author = Tobias Nipkow date = 2004-03-30 topic = Computer science/Automata and formal languages abstract = This theory defines deterministic and nondeterministic automata in a functional representation: the transition function/relation and the finality predicate are just functions. Hence the state space may be infinite. It is shown how to convert regular expressions into such automata. A scanner (generator) is implemented with the help of functional automata: the scanner chops the input up into longest recognized substrings. Finally we also show how to convert a certain subclass of functional automata (essentially the finite deterministic ones) into regular sets. notify = nipkow@in.tum.de [Statecharts] title = Formalizing Statecharts using Hierarchical Automata author = Steffen Helke , Florian Kammüller topic = Computer science/Automata and formal languages date = 2010-08-08 abstract = We formalize in Isabelle/HOL the abtract syntax and a synchronous step semantics for the specification language Statecharts. The formalization is based on Hierarchical Automata which allow a structural decomposition of Statecharts into Sequential Automata. To support the composition of Statecharts, we introduce calculating operators to construct a Hierarchical Automaton in a stepwise manner. Furthermore, we present a complete semantics of Statecharts including a theory of data spaces, which enables the modelling of racing effects. We also adapt CTL for Statecharts to build a bridge for future combinations with model checking. However the main motivation of this work is to provide a sound and complete basis for reasoning on Statecharts. As a central meta theorem we prove that the well-formedness of a Statechart is preserved by the semantics. notify = nipkow@in.tum.de [Stuttering_Equivalence] title = Stuttering Equivalence author = Stephan Merz topic = Computer science/Automata and formal languages date = 2012-05-07 abstract =

Two omega-sequences are stuttering equivalent if they differ only by finite repetitions of elements. Stuttering equivalence is a fundamental concept in the theory of concurrent and distributed systems. Notably, Lamport argues that refinement notions for such systems should be insensitive to finite stuttering. Peled and Wilke showed that all PLTL (propositional linear-time temporal logic) properties that are insensitive to stuttering equivalence can be expressed without the next-time operator. Stuttering equivalence is also important for certain verification techniques such as partial-order reduction for model checking.

We formalize stuttering equivalence in Isabelle/HOL. Our development relies on the notion of stuttering sampling functions that may skip blocks of identical sequence elements. We also encode PLTL and prove the theorem due to Peled and Wilke.

extra-history = Change history: [2013-01-31]: Added encoding of PLTL and proved Peled and Wilke's theorem. Adjusted abstract accordingly. notify = Stephan.Merz@loria.fr [Coinductive_Languages] title = A Codatatype of Formal Languages author = Dmitriy Traytel topic = Computer science/Automata and formal languages date = 2013-11-15 abstract =

We define formal languages as a codataype of infinite trees branching over the alphabet. Each node in such a tree indicates whether the path to this node constitutes a word inside or outside of the language. This codatatype is isormorphic to the set of lists representation of languages, but caters for definitions by corecursion and proofs by coinduction.

Regular operations on languages are then defined by primitive corecursion. A difficulty arises here, since the standard definitions of concatenation and iteration from the coalgebraic literature are not primitively corecursive-they require guardedness up-to union/concatenation. Without support for up-to corecursion, these operation must be defined as a composition of primitive ones (and proved being equal to the standard definitions). As an exercise in coinduction we also prove the axioms of Kleene algebra for the defined regular operations.

Furthermore, a language for context-free grammars given by productions in Greibach normal form and an initial nonterminal is constructed by primitive corecursion, yielding an executable decision procedure for the word problem without further ado.

notify = traytel@in.tum.de [Tree-Automata] title = Tree Automata author = Peter Lammich date = 2009-11-25 topic = Computer science/Automata and formal languages abstract = This work presents a machine-checked tree automata library for Standard-ML, OCaml and Haskell. The algorithms are efficient by using appropriate data structures like RB-trees. The available algorithms for non-deterministic automata include membership query, reduction, intersection, union, and emptiness check with computation of a witness for non-emptiness. The executable algorithms are derived from less-concrete, non-executable algorithms using data-refinement techniques. The concrete data structures are from the Isabelle Collections Framework. Moreover, this work contains a formalization of the class of tree-regular languages and its closure properties under set operations. notify = peter.lammich@uni-muenster.de, nipkow@in.tum.de [Depth-First-Search] title = Depth First Search author = Toshiaki Nishihara <>, Yasuhiko Minamide <> date = 2004-06-24 topic = Computer science/Algorithms/Graph abstract = Depth-first search of a graph is formalized with recdef. It is shown that it visits all of the reachable nodes from a given list of nodes. Executable ML code of depth-first search is obtained using the code generation feature of Isabelle/HOL. notify = lp15@cam.ac.uk, krauss@in.tum.de [FFT] title = Fast Fourier Transform author = Clemens Ballarin date = 2005-10-12 topic = Computer science/Algorithms/Mathematical abstract = We formalise a functional implementation of the FFT algorithm over the complex numbers, and its inverse. Both are shown equivalent to the usual definitions of these operations through Vandermonde matrices. They are also shown to be inverse to each other, more precisely, that composition of the inverse and the transformation yield the identity up to a scalar. notify = ballarin@in.tum.de [Gauss-Jordan-Elim-Fun] title = Gauss-Jordan Elimination for Matrices Represented as Functions author = Tobias Nipkow date = 2011-08-19 topic = Computer science/Algorithms/Mathematical, Mathematics/Algebra abstract = This theory provides a compact formulation of Gauss-Jordan elimination for matrices represented as functions. Its distinctive feature is succinctness. It is not meant for large computations. notify = nipkow@in.tum.de [UpDown_Scheme] title = Verification of the UpDown Scheme author = Johannes Hölzl date = 2015-01-28 topic = Computer science/Algorithms/Mathematical abstract = The UpDown scheme is a recursive scheme used to compute the stiffness matrix on a special form of sparse grids. Usually, when discretizing a Euclidean space of dimension d we need O(n^d) points, for n points along each dimension. Sparse grids are a hierarchical representation where the number of points is reduced to O(n * log(n)^d). One disadvantage of such sparse grids is that the algorithm now operate recursively in the dimensions and levels of the sparse grid.

The UpDown scheme allows us to compute the stiffness matrix on such a sparse grid. The stiffness matrix represents the influence of each representation function on the L^2 scalar product. For a detailed description see Dirk Pflüger's PhD thesis. This formalization was developed as an interdisciplinary project (IDP) at the Technische Universität München. notify = hoelzl@in.tum.de [GraphMarkingIBP] title = Verification of the Deutsch-Schorr-Waite Graph Marking Algorithm using Data Refinement author = Viorel Preoteasa , Ralph-Johan Back date = 2010-05-28 topic = Computer science/Algorithms/Graph abstract = The verification of the Deutsch-Schorr-Waite graph marking algorithm is used as a benchmark in many formalizations of pointer programs. The main purpose of this mechanization is to show how data refinement of invariant based programs can be used in verifying practical algorithms. The verification starts with an abstract algorithm working on a graph given by a relation next on nodes. Gradually the abstract program is refined into Deutsch-Schorr-Waite graph marking algorithm where only one bit per graph node of additional memory is used for marking. extra-history = Change history: [2012-01-05]: Updated for the new definition of data refinement and the new syntax for demonic and angelic update statements notify = viorel.preoteasa@aalto.fi [Efficient-Mergesort] title = Efficient Mergesort topic = Computer science/Algorithms date = 2011-11-09 author = Christian Sternagel abstract = We provide a formalization of the mergesort algorithm as used in GHC's Data.List module, proving correctness and stability. Furthermore, experimental data suggests that generated (Haskell-)code for this algorithm is much faster than for previous algorithms available in the Isabelle distribution. extra-history = Change history: [2012-10-24]: Added reference to journal article.
[2018-09-17]: Added theory Efficient_Mergesort that works exclusively with the mutual induction schemas generated by the function package.
[2018-09-19]: Added theory Mergesort_Complexity that proves an upper bound on the number of comparisons that are required by mergesort.
[2018-09-19]: Theory Efficient_Mergesort replaces theory Efficient_Sort but keeping the old name Efficient_Sort. [2020-11-20]: Additional theory Natural_Mergesort that developes an efficient mergesort algorithm without key-functions for educational purposes. notify = c.sternagel@gmail.com [SATSolverVerification] title = Formal Verification of Modern SAT Solvers author = Filip Marić date = 2008-07-23 topic = Computer science/Algorithms abstract = This document contains formal correctness proofs of modern SAT solvers. Following (Krstic et al, 2007) and (Nieuwenhuis et al., 2006), solvers are described using state-transition systems. Several different SAT solver descriptions are given and their partial correctness and termination is proved. These include:

  • a solver based on classical DPLL procedure (using only a backtrack-search with unit propagation),
  • a very general solver with backjumping and learning (similar to the description given in (Nieuwenhuis et al., 2006)), and
  • a solver with a specific conflict analysis algorithm (similar to the description given in (Krstic et al., 2007)).
Within the SAT solver correctness proofs, a large number of lemmas about propositional logic and CNF formulae are proved. This theory is self-contained and could be used for further exploring of properties of CNF based SAT algorithms. notify = [Transitive-Closure] title = Executable Transitive Closures of Finite Relations topic = Computer science/Algorithms/Graph date = 2011-03-14 author = Christian Sternagel , René Thiemann license = LGPL abstract = We provide a generic work-list algorithm to compute the transitive closure of finite relations where only successors of newly detected states are generated. This algorithm is then instantiated for lists over arbitrary carriers and red black trees (which are faster but require a linear order on the carrier), respectively. Our formalization was performed as part of the IsaFoR/CeTA project where reflexive transitive closures of large tree automata have to be computed. extra-history = Change history: [2014-09-04] added example simprocs in Finite_Transitive_Closure_Simprocs notify = c.sternagel@gmail.com, rene.thiemann@uibk.ac.at [Transitive-Closure-II] title = Executable Transitive Closures topic = Computer science/Algorithms/Graph date = 2012-02-29 author = René Thiemann license = LGPL abstract =

We provide a generic work-list algorithm to compute the (reflexive-)transitive closure of relations where only successors of newly detected states are generated. In contrast to our previous work, the relations do not have to be finite, but each element must only have finitely many (indirect) successors. Moreover, a subsumption relation can be used instead of pure equality. An executable variant of the algorithm is available where the generic operations are instantiated with list operations.

This formalization was performed as part of the IsaFoR/CeTA project, and it has been used to certify size-change termination proofs where large transitive closures have to be computed.

notify = rene.thiemann@uibk.ac.at [MuchAdoAboutTwo] title = Much Ado About Two author = Sascha Böhme date = 2007-11-06 topic = Computer science/Algorithms abstract = This article is an Isabelle formalisation of a paper with the same title. In a similar way as Knuth's 0-1-principle for sorting algorithms, that paper develops a 0-1-2-principle for parallel prefix computations. notify = boehmes@in.tum.de [DiskPaxos] title = Proving the Correctness of Disk Paxos date = 2005-06-22 author = Mauro Jaskelioff , Stephan Merz topic = Computer science/Algorithms/Distributed abstract = Disk Paxos is an algorithm for building arbitrary fault-tolerant distributed systems. The specification of Disk Paxos has been proved correct informally and tested using the TLC model checker, but up to now, it has never been fully formally verified. In this work we have formally verified its correctness using the Isabelle theorem prover and the HOL logic system, showing that Isabelle is a practical tool for verifying properties of TLA+ specifications. notify = kleing@cse.unsw.edu.au [GenClock] title = Formalization of a Generalized Protocol for Clock Synchronization author = Alwen Tiu date = 2005-06-24 topic = Computer science/Algorithms/Distributed abstract = We formalize the generalized Byzantine fault-tolerant clock synchronization protocol of Schneider. This protocol abstracts from particular algorithms or implementations for clock synchronization. This abstraction includes several assumptions on the behaviors of physical clocks and on general properties of concrete algorithms/implementations. Based on these assumptions the correctness of the protocol is proved by Schneider. His proof was later verified by Shankar using the theorem prover EHDM (precursor to PVS). Our formalization in Isabelle/HOL is based on Shankar's formalization. notify = kleing@cse.unsw.edu.au [ClockSynchInst] title = Instances of Schneider's generalized protocol of clock synchronization author = Damián Barsotti date = 2006-03-15 topic = Computer science/Algorithms/Distributed abstract = F. B. Schneider ("Understanding protocols for Byzantine clock synchronization") generalizes a number of protocols for Byzantine fault-tolerant clock synchronization and presents a uniform proof for their correctness. In Schneider's schema, each processor maintains a local clock by periodically adjusting each value to one computed by a convergence function applied to the readings of all the clocks. Then, correctness of an algorithm, i.e. that the readings of two clocks at any time are within a fixed bound of each other, is based upon some conditions on the convergence function. To prove that a particular clock synchronization algorithm is correct it suffices to show that the convergence function used by the algorithm meets Schneider's conditions. Using the theorem prover Isabelle, we formalize the proofs that the convergence functions of two algorithms, namely, the Interactive Convergence Algorithm (ICA) of Lamport and Melliar-Smith and the Fault-tolerant Midpoint algorithm of Lundelius-Lynch, meet Schneider's conditions. Furthermore, we experiment on handling some parts of the proofs with fully automatic tools like ICS and CVC-lite. These theories are part of a joint work with Alwen Tiu and Leonor P. Nieto "Verification of Clock Synchronization Algorithms: Experiments on a combination of deductive tools" in proceedings of AVOCS 2005. In this work the correctness of Schneider schema was also verified using Isabelle (entry GenClock in AFP). notify = kleing@cse.unsw.edu.au [Heard_Of] title = Verifying Fault-Tolerant Distributed Algorithms in the Heard-Of Model date = 2012-07-27 author = Henri Debrat , Stephan Merz topic = Computer science/Algorithms/Distributed abstract = Distributed computing is inherently based on replication, promising increased tolerance to failures of individual computing nodes or communication channels. Realizing this promise, however, involves quite subtle algorithmic mechanisms, and requires precise statements about the kinds and numbers of faults that an algorithm tolerates (such as process crashes, communication faults or corrupted values). The landmark theorem due to Fischer, Lynch, and Paterson shows that it is impossible to achieve Consensus among N asynchronously communicating nodes in the presence of even a single permanent failure. Existing solutions must rely on assumptions of "partial synchrony".

Indeed, there have been numerous misunderstandings on what exactly a given algorithm is supposed to realize in what kinds of environments. Moreover, the abundance of subtly different computational models complicates comparisons between different algorithms. Charron-Bost and Schiper introduced the Heard-Of model for representing algorithms and failure assumptions in a uniform framework, simplifying comparisons between algorithms.

In this contribution, we represent the Heard-Of model in Isabelle/HOL. We define two semantics of runs of algorithms with different unit of atomicity and relate these through a reduction theorem that allows us to verify algorithms in the coarse-grained semantics (where proofs are easier) and infer their correctness for the fine-grained one (which corresponds to actual executions). We instantiate the framework by verifying six Consensus algorithms that differ in the underlying algorithmic mechanisms and the kinds of faults they tolerate. notify = Stephan.Merz@loria.fr [Consensus_Refined] title = Consensus Refined date = 2015-03-18 author = Ognjen Maric <>, Christoph Sprenger topic = Computer science/Algorithms/Distributed abstract = Algorithms for solving the consensus problem are fundamental to distributed computing. Despite their brevity, their ability to operate in concurrent, asynchronous and failure-prone environments comes at the cost of complex and subtle behaviors. Accordingly, understanding how they work and proving their correctness is a non-trivial endeavor where abstraction is immensely helpful. Moreover, research on consensus has yielded a large number of algorithms, many of which appear to share common algorithmic ideas. A natural question is whether and how these similarities can be distilled and described in a precise, unified way. In this work, we combine stepwise refinement and lockstep models to provide an abstract and unified view of a sizeable family of consensus algorithms. Our models provide insights into the design choices underlying the different algorithms, and classify them based on those choices. notify = sprenger@inf.ethz.ch [Key_Agreement_Strong_Adversaries] title = Refining Authenticated Key Agreement with Strong Adversaries author = Joseph Lallemand , Christoph Sprenger topic = Computer science/Security license = LGPL date = 2017-01-31 notify = joseph.lallemand@loria.fr, sprenger@inf.ethz.ch abstract = We develop a family of key agreement protocols that are correct by construction. Our work substantially extends prior work on developing security protocols by refinement. First, we strengthen the adversary by allowing him to compromise different resources of protocol participants, such as their long-term keys or their session keys. This enables the systematic development of protocols that ensure strong properties such as perfect forward secrecy. Second, we broaden the class of protocols supported to include those with non-atomic keys and equationally defined cryptographic operators. We use these extensions to develop key agreement protocols including signed Diffie-Hellman and the core of IKEv1 and SKEME. [Security_Protocol_Refinement] title = Developing Security Protocols by Refinement author = Christoph Sprenger , Ivano Somaini<> topic = Computer science/Security license = LGPL date = 2017-05-24 notify = sprenger@inf.ethz.ch abstract = We propose a development method for security protocols based on stepwise refinement. Our refinement strategy transforms abstract security goals into protocols that are secure when operating over an insecure channel controlled by a Dolev-Yao-style intruder. As intermediate levels of abstraction, we employ messageless guard protocols and channel protocols communicating over channels with security properties. These abstractions provide insights on why protocols are secure and foster the development of families of protocols sharing common structure and properties. We have implemented our method in Isabelle/HOL and used it to develop different entity authentication and key establishment protocols, including realistic features such as key confirmation, replay caches, and encrypted tickets. Our development highlights that guard protocols and channel protocols provide fundamental abstractions for bridging the gap between security properties and standard protocol descriptions based on cryptographic messages. It also shows that our refinement approach scales to protocols of nontrivial size and complexity. [Abortable_Linearizable_Modules] title = Abortable Linearizable Modules author = Rachid Guerraoui , Viktor Kuncak , Giuliano Losa date = 2012-03-01 topic = Computer science/Algorithms/Distributed abstract = We define the Abortable Linearizable Module automaton (ALM for short) and prove its key composition property using the IOA theory of HOLCF. The ALM is at the heart of the Speculative Linearizability framework. This framework simplifies devising correct speculative algorithms by enabling their decomposition into independent modules that can be analyzed and proved correct in isolation. It is particularly useful when working in a distributed environment, where the need to tolerate faults and asynchrony has made current monolithic protocols so intricate that it is no longer tractable to check their correctness. Our theory contains a typical example of a refinement proof in the I/O-automata framework of Lynch and Tuttle. notify = giuliano@losa.fr, nipkow@in.tum.de [Amortized_Complexity] title = Amortized Complexity Verified author = Tobias Nipkow date = 2014-07-07 topic = Computer science/Data structures abstract = A framework for the analysis of the amortized complexity of functional data structures is formalized in Isabelle/HOL and applied to a number of standard examples and to the folowing non-trivial ones: skew heaps, splay trees, splay heaps and pairing heaps.

A preliminary version of this work (without pairing heaps) is described in a paper published in the proceedings of the conference on Interactive Theorem Proving ITP 2015. An extended version of this publication is available here. extra-history = Change history: [2015-03-17]: Added pairing heaps by Hauke Brinkop.
[2016-07-12]: Moved splay heaps from here to Splay_Tree
[2016-07-14]: Moved pairing heaps from here to the new Pairing_Heap notify = nipkow@in.tum.de [Dynamic_Tables] title = Parameterized Dynamic Tables author = Tobias Nipkow date = 2015-06-07 topic = Computer science/Data structures abstract = This article formalizes the amortized analysis of dynamic tables parameterized with their minimal and maximal load factors and the expansion and contraction factors.

A full description is found in a companion paper. notify = nipkow@in.tum.de [AVL-Trees] title = AVL Trees author = Tobias Nipkow , Cornelia Pusch <> date = 2004-03-19 topic = Computer science/Data structures abstract = Two formalizations of AVL trees with room for extensions. The first formalization is monolithic and shorter, the second one in two stages, longer and a bit simpler. The final implementation is the same. If you are interested in developing this further, please contact gerwin.klein@nicta.com.au. extra-history = Change history: [2011-04-11]: Ondrej Kuncar added delete function notify = kleing@cse.unsw.edu.au [BDD] title = BDD Normalisation author = Veronika Ortner <>, Norbert Schirmer <> date = 2008-02-29 topic = Computer science/Data structures abstract = We present the verification of the normalisation of a binary decision diagram (BDD). The normalisation follows the original algorithm presented by Bryant in 1986 and transforms an ordered BDD in a reduced, ordered and shared BDD. The verification is based on Hoare logics. notify = kleing@cse.unsw.edu.au, norbert.schirmer@web.de [BinarySearchTree] title = Binary Search Trees author = Viktor Kuncak date = 2004-04-05 topic = Computer science/Data structures abstract = The correctness is shown of binary search tree operations (lookup, insert and remove) implementing a set. Two versions are given, for both structured and linear (tactic-style) proofs. An implementation of integer-indexed maps is also verified. notify = lp15@cam.ac.uk [Splay_Tree] title = Splay Tree author = Tobias Nipkow notify = nipkow@in.tum.de date = 2014-08-12 topic = Computer science/Data structures abstract = Splay trees are self-adjusting binary search trees which were invented by Sleator and Tarjan [JACM 1985]. This entry provides executable and verified functional splay trees as well as the related splay heaps (due to Okasaki).

The amortized complexity of splay trees and heaps is analyzed in the AFP entry Amortized Complexity. extra-history = Change history: [2016-07-12]: Moved splay heaps here from Amortized_Complexity [Root_Balanced_Tree] title = Root-Balanced Tree author = Tobias Nipkow notify = nipkow@in.tum.de date = 2017-08-20 topic = Computer science/Data structures abstract =

Andersson introduced general balanced trees, search trees based on the design principle of partial rebuilding: perform update operations naively until the tree becomes too unbalanced, at which point a whole subtree is rebalanced. This article defines and analyzes a functional version of general balanced trees, which we call root-balanced trees. Using a lightweight model of execution time, amortized logarithmic complexity is verified in the theorem prover Isabelle.

This is the Isabelle formalization of the material decribed in the APLAS 2017 article Verified Root-Balanced Trees by the same author, which also presents experimental results that show competitiveness of root-balanced with AVL and red-black trees.

[Skew_Heap] title = Skew Heap author = Tobias Nipkow date = 2014-08-13 topic = Computer science/Data structures abstract = Skew heaps are an amazingly simple and lightweight implementation of priority queues. They were invented by Sleator and Tarjan [SIAM 1986] and have logarithmic amortized complexity. This entry provides executable and verified functional skew heaps.

The amortized complexity of skew heaps is analyzed in the AFP entry Amortized Complexity. notify = nipkow@in.tum.de [Pairing_Heap] title = Pairing Heap author = Hauke Brinkop , Tobias Nipkow date = 2016-07-14 topic = Computer science/Data structures abstract = This library defines three different versions of pairing heaps: a functional version of the original design based on binary trees [Fredman et al. 1986], the version by Okasaki [1998] and a modified version of the latter that is free of structural invariants.

The amortized complexity of pairing heaps is analyzed in the AFP article Amortized Complexity. extra-0 = Origin: This library was extracted from Amortized Complexity and extended. notify = nipkow@in.tum.de [Priority_Queue_Braun] title = Priority Queues Based on Braun Trees author = Tobias Nipkow date = 2014-09-04 topic = Computer science/Data structures abstract = This entry verifies priority queues based on Braun trees. Insertion and deletion take logarithmic time and preserve the balanced nature of Braun trees. Two implementations of deletion are provided. notify = nipkow@in.tum.de extra-history = Change history: [2019-12-16]: Added theory Priority_Queue_Braun2 with second version of del_min [Binomial-Queues] title = Functional Binomial Queues author = René Neumann date = 2010-10-28 topic = Computer science/Data structures abstract = Priority queues are an important data structure and efficient implementations of them are crucial. We implement a functional variant of binomial queues in Isabelle/HOL and show its functional correctness. A verification against an abstract reference specification of priority queues has also been attempted, but could not be achieved to the full extent. notify = florian.haftmann@informatik.tu-muenchen.de [Binomial-Heaps] title = Binomial Heaps and Skew Binomial Heaps author = Rene Meis , Finn Nielsen , Peter Lammich date = 2010-10-28 topic = Computer science/Data structures abstract = We implement and prove correct binomial heaps and skew binomial heaps. Both are data-structures for priority queues. While binomial heaps have logarithmic findMin, deleteMin, insert, and meld operations, skew binomial heaps have constant time findMin, insert, and meld operations, and only the deleteMin-operation is logarithmic. This is achieved by using skew links to avoid cascading linking on insert-operations, and data-structural bootstrapping to get constant-time findMin and meld operations. Our implementation follows the paper by Brodal and Okasaki. notify = peter.lammich@uni-muenster.de [Finger-Trees] title = Finger Trees author = Benedikt Nordhoff , Stefan Körner , Peter Lammich date = 2010-10-28 topic = Computer science/Data structures abstract = We implement and prove correct 2-3 finger trees. Finger trees are a general purpose data structure, that can be used to efficiently implement other data structures, such as priority queues. Intuitively, a finger tree is an annotated sequence, where the annotations are elements of a monoid. Apart from operations to access the ends of the sequence, the main operation is to split the sequence at the point where a monotone predicate over the sum of the left part of the sequence becomes true for the first time. The implementation follows the paper of Hinze and Paterson. The code generator can be used to get efficient, verified code. notify = peter.lammich@uni-muenster.de [Trie] title = Trie author = Andreas Lochbihler , Tobias Nipkow date = 2015-03-30 topic = Computer science/Data structures abstract = This article formalizes the ``trie'' data structure invented by Fredkin [CACM 1960]. It also provides a specialization where the entries in the trie are lists. extra-0 = Origin: This article was extracted from existing articles by the authors. notify = nipkow@in.tum.de [FinFun] title = Code Generation for Functions as Data author = Andreas Lochbihler date = 2009-05-06 topic = Computer science/Data structures abstract = FinFuns are total functions that are constant except for a finite set of points, i.e. a generalisation of finite maps. They are formalised as a new type in Isabelle/HOL such that the code generator can handle equality tests and quantification on FinFuns. On the code output level, FinFuns are explicitly represented by constant functions and pointwise updates, similarly to associative lists. Inside the logic, they behave like ordinary functions with extensionality. Via the update/constant pattern, a recursion combinator and an induction rule for FinFuns allow for defining and reasoning about operators on FinFun that are also executable. extra-history = Change history: [2010-08-13]: new concept domain of a FinFun as a FinFun (revision 34b3517cbc09)
[2010-11-04]: new conversion function from FinFun to list of elements in the domain (revision 0c167102e6ed)
[2012-03-07]: replace sets as FinFuns by predicates as FinFuns because the set type constructor has been reintroduced (revision b7aa87989f3a) notify = nipkow@in.tum.de [Collections] title = Collections Framework author = Peter Lammich contributors = Andreas Lochbihler , Thomas Tuerk <> date = 2009-11-25 topic = Computer science/Data structures abstract = This development provides an efficient, extensible, machine checked collections framework. The library adopts the concepts of interface, implementation and generic algorithm from object-oriented programming and implements them in Isabelle/HOL. The framework features the use of data refinement techniques to refine an abstract specification (using high-level concepts like sets) to a more concrete implementation (using collection datastructures, like red-black-trees). The code-generator of Isabelle/HOL can be used to generate efficient code. extra-history = Change history: [2010-10-08]: New Interfaces: OrderedSet, OrderedMap, List. Fifo now implements list-interface: Function names changed: put/get --> enqueue/dequeue. New Implementations: ArrayList, ArrayHashMap, ArrayHashSet, TrieMap, TrieSet. Invariant-free datastructures: Invariant implicitely hidden in typedef. Record-interfaces: All operations of an interface encapsulated as record. Examples moved to examples subdirectory.
[2010-12-01]: New Interfaces: Priority Queues, Annotated Lists. Implemented by finger trees, (skew) binomial queues.
[2011-10-10]: SetSpec: Added operations: sng, isSng, bexists, size_abort, diff, filter, iterate_rule_insertP MapSpec: Added operations: sng, isSng, iterate_rule_insertP, bexists, size, size_abort, restrict, map_image_filter, map_value_image_filter Some maintenance changes
[2012-04-25]: New iterator foundation by Tuerk. Various maintenance changes.
[2012-08]: Collections V2. New features: Polymorphic iterators. Generic algorithm instantiation where required. Naming scheme changed from xx_opname to xx.opname. A compatibility file CollectionsV1 tries to simplify porting of existing theories, by providing old naming scheme and the old monomorphic iterator locales.
[2013-09]: Added Generic Collection Framework based on Autoref. The GenCF provides: Arbitrary nesting, full integration with Autoref.
[2014-06]: Maintenace changes to GenCF: Optimized inj_image on list_set. op_set_cart (Cartesian product). big-Union operation. atLeastLessThan - operation ({a..<b})
notify = lammich@in.tum.de [Containers] title = Light-weight Containers author = Andreas Lochbihler contributors = René Thiemann date = 2013-04-15 topic = Computer science/Data structures abstract = This development provides a framework for container types like sets and maps such that generated code implements these containers with different (efficient) data structures. Thanks to type classes and refinement during code generation, this light-weight approach can seamlessly replace Isabelle's default setup for code generation. Heuristics automatically pick one of the available data structures depending on the type of elements to be stored, but users can also choose on their own. The extensible design permits to add more implementations at any time.

To support arbitrary nesting of sets, we define a linear order on sets based on a linear order of the elements and provide efficient implementations. It even allows to compare complements with non-complements. extra-history = Change history: [2013-07-11]: add pretty printing for sets (revision 7f3f52c5f5fa)
[2013-09-20]: provide generators for canonical type class instantiations (revision 159f4401f4a8 by René Thiemann)
[2014-07-08]: add support for going from partial functions to mappings (revision 7a6fc957e8ed)
[2018-03-05]: add two application examples: depth-first search and 2SAT (revision e5e1a1da2411) notify = mail@andreas-lochbihler.de [FileRefinement] title = File Refinement author = Karen Zee , Viktor Kuncak date = 2004-12-09 topic = Computer science/Data structures abstract = These theories illustrates the verification of basic file operations (file creation, file read and file write) in the Isabelle theorem prover. We describe a file at two levels of abstraction: an abstract file represented as a resizable array, and a concrete file represented using data blocks. notify = kkz@mit.edu [Datatype_Order_Generator] title = Generating linear orders for datatypes author = René Thiemann date = 2012-08-07 topic = Computer science/Data structures abstract = We provide a framework for registering automatic methods to derive class instances of datatypes, as it is possible using Haskell's ``deriving Ord, Show, ...'' feature.

We further implemented such automatic methods to derive (linear) orders or hash-functions which are required in the Isabelle Collection Framework. Moreover, for the tactic of Huffman and Krauss to show that a datatype is countable, we implemented a wrapper so that this tactic becomes accessible in our framework.

Our formalization was performed as part of the IsaFoR/CeTA project. With our new tactic we could completely remove tedious proofs for linear orders of two datatypes.

This development is aimed at datatypes generated by the "old_datatype" command. notify = rene.thiemann@uibk.ac.at [Deriving] title = Deriving class instances for datatypes author = Christian Sternagel , René Thiemann date = 2015-03-11 topic = Computer science/Data structures abstract =

We provide a framework for registering automatic methods to derive class instances of datatypes, as it is possible using Haskell's ``deriving Ord, Show, ...'' feature.

We further implemented such automatic methods to derive comparators, linear orders, parametrizable equality functions, and hash-functions which are required in the Isabelle Collection Framework and the Container Framework. Moreover, for the tactic of Blanchette to show that a datatype is countable, we implemented a wrapper so that this tactic becomes accessible in our framework. All of the generators are based on the infrastructure that is provided by the BNF-based datatype package.

Our formalization was performed as part of the IsaFoR/CeTA project. With our new tactics we could remove several tedious proofs for (conditional) linear orders, and conditional equality operators within IsaFoR and the Container Framework.

notify = rene.thiemann@uibk.ac.at [List-Index] title = List Index date = 2010-02-20 author = Tobias Nipkow topic = Computer science/Data structures abstract = This theory provides functions for finding the index of an element in a list, by predicate and by value. notify = nipkow@in.tum.de [List-Infinite] title = Infinite Lists date = 2011-02-23 author = David Trachtenherz <> topic = Computer science/Data structures abstract = We introduce a theory of infinite lists in HOL formalized as functions over naturals (folder ListInf, theories ListInf and ListInf_Prefix). It also provides additional results for finite lists (theory ListInf/List2), natural numbers (folder CommonArith, esp. division/modulo, naturals with infinity), sets (folder CommonSet, esp. cutting/truncating sets, traversing sets of naturals). notify = nipkow@in.tum.de [Matrix] title = Executable Matrix Operations on Matrices of Arbitrary Dimensions topic = Computer science/Data structures date = 2010-06-17 author = Christian Sternagel , René Thiemann license = LGPL abstract = We provide the operations of matrix addition, multiplication, transposition, and matrix comparisons as executable functions over ordered semirings. Moreover, it is proven that strongly normalizing (monotone) orders can be lifted to strongly normalizing (monotone) orders over matrices. We further show that the standard semirings over the naturals, integers, and rationals, as well as the arctic semirings satisfy the axioms that are required by our matrix theory. Our formalization is part of the CeTA system which contains several termination techniques. The provided theories have been essential to formalize matrix-interpretations and arctic interpretations. extra-history = Change history: [2010-09-17]: Moved theory on arbitrary (ordered) semirings to Abstract Rewriting. notify = rene.thiemann@uibk.ac.at, christian.sternagel@uibk.ac.at [Matrix_Tensor] title = Tensor Product of Matrices topic = Computer science/Data structures, Mathematics/Algebra date = 2016-01-18 author = T.V.H. Prathamesh abstract = In this work, the Kronecker tensor product of matrices and the proofs of some of its properties are formalized. Properties which have been formalized include associativity of the tensor product and the mixed-product property. notify = prathamesh@imsc.res.in [Huffman] title = The Textbook Proof of Huffman's Algorithm author = Jasmin Christian Blanchette date = 2008-10-15 topic = Computer science/Data structures abstract = Huffman's algorithm is a procedure for constructing a binary tree with minimum weighted path length. This report presents a formal proof of the correctness of Huffman's algorithm written using Isabelle/HOL. Our proof closely follows the sketches found in standard algorithms textbooks, uncovering a few snags in the process. Another distinguishing feature of our formalization is the use of custom induction rules to help Isabelle's automatic tactics, leading to very short proofs for most of the lemmas. notify = jasmin.blanchette@gmail.com [Partial_Function_MR] title = Mutually Recursive Partial Functions author = René Thiemann topic = Computer science/Functional programming date = 2014-02-18 license = LGPL abstract = We provide a wrapper around the partial-function command that supports mutual recursion. notify = rene.thiemann@uibk.ac.at [Lifting_Definition_Option] title = Lifting Definition Option author = René Thiemann topic = Computer science/Functional programming date = 2014-10-13 license = LGPL abstract = We implemented a command that can be used to easily generate elements of a restricted type {x :: 'a. P x}, provided the definition is of the form f ys = (if check ys then Some(generate ys :: 'a) else None) where ys is a list of variables y1 ... yn and check ys ==> P(generate ys) can be proved.

In principle, such a definition is also directly possible using the lift_definition command. However, then this definition will not be suitable for code-generation. To this end, we automated a more complex construction of Joachim Breitner which is amenable for code-generation, and where the test check ys will only be performed once. In the automation, one auxiliary type is created, and Isabelle's lifting- and transfer-package is invoked several times. notify = rene.thiemann@uibk.ac.at [Coinductive] title = Coinductive topic = Computer science/Functional programming author = Andreas Lochbihler contributors = Johannes Hölzl date = 2010-02-12 abstract = This article collects formalisations of general-purpose coinductive data types and sets. Currently, it contains coinductive natural numbers, coinductive lists, i.e. lazy lists or streams, infinite streams, coinductive terminated lists, coinductive resumptions, a library of operations on coinductive lists, and a version of König's lemma as an application for coinductive lists.
The initial theory was contributed by Paulson and Wenzel. Extensions and other coinductive formalisations of general interest are welcome. extra-history = Change history: [2010-06-10]: coinductive lists: setup for quotient package (revision 015574f3bf3c)
[2010-06-28]: new codatatype terminated lazy lists (revision e12de475c558)
[2010-08-04]: terminated lazy lists: setup for quotient package; more lemmas (revision 6ead626f1d01)
[2010-08-17]: Koenig's lemma as an example application for coinductive lists (revision f81ce373fa96)
[2011-02-01]: lazy implementation of coinductive (terminated) lists for the code generator (revision 6034973dce83)
[2011-07-20]: new codatatype resumption (revision 811364c776c7)
[2012-06-27]: new codatatype stream with operations (with contributions by Peter Gammie) (revision dd789a56473c)
[2013-03-13]: construct codatatypes with the BNF package and adjust the definitions and proofs, setup for lifting and transfer packages (revision f593eda5b2c0)
[2013-09-20]: stream theory uses type and operations from HOL/BNF/Examples/Stream (revision 692809b2b262)
[2014-04-03]: ccpo structure on codatatypes used to define ldrop, ldropWhile, lfilter, lconcat as least fixpoint; ccpo topology on coinductive lists contributed by Johannes Hölzl; added examples (revision 23cd8156bd42)
notify = mail@andreas-lochbihler.de [Stream-Fusion] title = Stream Fusion author = Brian Huffman topic = Computer science/Functional programming date = 2009-04-29 abstract = Stream Fusion is a system for removing intermediate list structures from Haskell programs; it consists of a Haskell library along with several compiler rewrite rules. (The library is available online.)

These theories contain a formalization of much of the Stream Fusion library in HOLCF. Lazy list and stream types are defined, along with coercions between the two types, as well as an equivalence relation for streams that generate the same list. List and stream versions of map, filter, foldr, enumFromTo, append, zipWith, and concatMap are defined, and the stream versions are shown to respect stream equivalence. notify = brianh@cs.pdx.edu [Tycon] title = Type Constructor Classes and Monad Transformers author = Brian Huffman date = 2012-06-26 topic = Computer science/Functional programming abstract = These theories contain a formalization of first class type constructors and axiomatic constructor classes for HOLCF. This work is described in detail in the ICFP 2012 paper Formal Verification of Monad Transformers by the author. The formalization is a revised and updated version of earlier joint work with Matthews and White.

Based on the hierarchy of type classes in Haskell, we define classes for functors, monads, monad-plus, etc. Each one includes all the standard laws as axioms. We also provide a new user command, tycondef, for defining new type constructors in HOLCF. Using tycondef, we instantiate the type class hierarchy with various monads and monad transformers. notify = huffman@in.tum.de [CoreC++] title = CoreC++ author = Daniel Wasserrab date = 2006-05-15 topic = Computer science/Programming languages/Language definitions abstract = We present an operational semantics and type safety proof for multiple inheritance in C++. The semantics models the behavior of method calls, field accesses, and two forms of casts in C++ class hierarchies. For explanations see the OOPSLA 2006 paper by Wasserrab, Nipkow, Snelting and Tip. notify = nipkow@in.tum.de [FeatherweightJava] title = A Theory of Featherweight Java in Isabelle/HOL author = J. Nathan Foster , Dimitrios Vytiniotis date = 2006-03-31 topic = Computer science/Programming languages/Language definitions abstract = We formalize the type system, small-step operational semantics, and type soundness proof for Featherweight Java, a simple object calculus, in Isabelle/HOL. notify = kleing@cse.unsw.edu.au [Jinja] title = Jinja is not Java author = Gerwin Klein , Tobias Nipkow date = 2005-06-01 topic = Computer science/Programming languages/Language definitions abstract = We introduce Jinja, a Java-like programming language with a formal semantics designed to exhibit core features of the Java language architecture. Jinja is a compromise between realism of the language and tractability and clarity of the formal semantics. The following aspects are formalised: a big and a small step operational semantics for Jinja and a proof of their equivalence; a type system and a definite initialisation analysis; a type safety proof of the small step semantics; a virtual machine (JVM), its operational semantics and its type system; a type safety proof for the JVM; a bytecode verifier, i.e. data flow analyser for the JVM; a correctness proof of the bytecode verifier w.r.t. the type system; a compiler and a proof that it preserves semantics and well-typedness. The emphasis of this work is not on particular language features but on providing a unified model of the source language, the virtual machine and the compiler. The whole development has been carried out in the theorem prover Isabelle/HOL. notify = kleing@cse.unsw.edu.au, nipkow@in.tum.de [JinjaThreads] title = Jinja with Threads author = Andreas Lochbihler date = 2007-12-03 topic = Computer science/Programming languages/Language definitions abstract = We extend the Jinja source code semantics by Klein and Nipkow with Java-style arrays and threads. Concurrency is captured in a generic framework semantics for adding concurrency through interleaving to a sequential semantics, which features dynamic thread creation, inter-thread communication via shared memory, lock synchronisation and joins. Also, threads can suspend themselves and be notified by others. We instantiate the framework with the adapted versions of both Jinja source and byte code and show type safety for the multithreaded case. Equally, the compiler from source to byte code is extended, for which we prove weak bisimilarity between the source code small step semantics and the defensive Jinja virtual machine. On top of this, we formalise the JMM and show the DRF guarantee and consistency. For description of the different parts, see Lochbihler's papers at FOOL 2008, ESOP 2010, ITP 2011, and ESOP 2012. extra-history = Change history: [2008-04-23]: added bytecode formalisation with arrays and threads, added thread joins (revision f74a8be156a7)
[2009-04-27]: added verified compiler from source code to bytecode; encapsulate native methods in separate semantics (revision e4f26541e58a)
[2009-11-30]: extended compiler correctness proof to infinite and deadlocking computations (revision e50282397435)
[2010-06-08]: added thread interruption; new abstract memory model with sequential consistency as implementation (revision 0cb9e8dbd78d)
[2010-06-28]: new thread interruption model (revision c0440d0a1177)
[2010-10-15]: preliminary version of the Java memory model for source code (revision 02fee0ef3ca2)
[2010-12-16]: improved version of the Java memory model, also for bytecode executable scheduler for source code semantics (revision 1f41c1842f5a)
[2011-02-02]: simplified code generator setup new random scheduler (revision 3059dafd013f)
[2011-07-21]: new interruption model, generalized JMM proof of DRF guarantee, allow class Object to declare methods and fields, simplified subtyping relation, corrected division and modulo implementation (revision 46e4181ed142)
[2012-02-16]: added example programs (revision bf0b06c8913d)
[2012-11-21]: type safety proof for the Java memory model, allow spurious wake-ups (revision 76063d860ae0)
[2013-05-16]: support for non-deterministic memory allocators (revision cc3344a49ced)
[2017-10-20]: add an atomic compare-and-swap operation for volatile fields (revision a6189b1d6b30)
notify = mail@andreas-lochbihler.de [Locally-Nameless-Sigma] title = Locally Nameless Sigma Calculus author = Ludovic Henrio , Florian Kammüller , Bianca Lutz , Henry Sudhof date = 2010-04-30 topic = Computer science/Programming languages/Language definitions abstract = We present a Theory of Objects based on the original functional sigma-calculus by Abadi and Cardelli but with an additional parameter to methods. We prove confluence of the operational semantics following the outline of Nipkow's proof of confluence for the lambda-calculus reusing his theory Commutation, a generic diamond lemma reduction. We furthermore formalize a simple type system for our sigma-calculus including a proof of type safety. The entire development uses the concept of Locally Nameless representation for binders. We reuse an earlier proof of confluence for a simpler sigma-calculus based on de Bruijn indices and lists to represent objects. notify = nipkow@in.tum.de [Attack_Trees] title = Attack Trees in Isabelle for GDPR compliance of IoT healthcare systems author = Florian Kammueller topic = Computer science/Security date = 2020-04-27 notify = florian.kammuller@gmail.com abstract = In this article, we present a proof theory for Attack Trees. Attack Trees are a well established and useful model for the construction of attacks on systems since they allow a stepwise exploration of high level attacks in application scenarios. Using the expressiveness of Higher Order Logic in Isabelle, we develop a generic theory of Attack Trees with a state-based semantics based on Kripke structures and CTL. The resulting framework allows mechanically supported logic analysis of the meta-theory of the proof calculus of Attack Trees and at the same time the developed proof theory enables application to case studies. A central correctness and completeness result proved in Isabelle establishes a connection between the notion of Attack Tree validity and CTL. The application is illustrated on the example of a healthcare IoT system and GDPR compliance verification. [AutoFocus-Stream] title = AutoFocus Stream Processing for Single-Clocking and Multi-Clocking Semantics author = David Trachtenherz <> date = 2011-02-23 topic = Computer science/Programming languages/Language definitions abstract = We formalize the AutoFocus Semantics (a time-synchronous subset of the Focus formalism) as stream processing functions on finite and infinite message streams represented as finite/infinite lists. The formalization comprises both the conventional single-clocking semantics (uniform global clock for all components and communications channels) and its extension to multi-clocking semantics (internal execution clocking of a component may be a multiple of the external communication clocking). The semantics is defined by generic stream processing functions making it suitable for simulation/code generation in Isabelle/HOL. Furthermore, a number of AutoFocus semantics properties are formalized using definitions from the IntervalLogic theories. notify = nipkow@in.tum.de [FocusStreamsCaseStudies] title = Stream Processing Components: Isabelle/HOL Formalisation and Case Studies author = Maria Spichkova date = 2013-11-14 topic = Computer science/Programming languages/Language definitions abstract = This set of theories presents an Isabelle/HOL formalisation of stream processing components introduced in Focus, a framework for formal specification and development of interactive systems. This is an extended and updated version of the formalisation, which was elaborated within the methodology "Focus on Isabelle". In addition, we also applied the formalisation on three case studies that cover different application areas: process control (Steam Boiler System), data transmission (FlexRay communication protocol), memory and processing components (Automotive-Gateway System). notify = lp15@cam.ac.uk, maria.spichkova@rmit.edu.au [Isabelle_Meta_Model] title = A Meta-Model for the Isabelle API author = Frédéric Tuong , Burkhart Wolff date = 2015-09-16 topic = Computer science/Programming languages/Language definitions abstract = We represent a theory of (a fragment of) Isabelle/HOL in Isabelle/HOL. The purpose of this exercise is to write packages for domain-specific specifications such as class models, B-machines, ..., and generally speaking, any domain-specific languages whose abstract syntax can be defined by a HOL "datatype". On this basis, the Isabelle code-generator can then be used to generate code for global context transformations as well as tactic code.

Consequently the package is geared towards parsing, printing and code-generation to the Isabelle API. It is at the moment not sufficiently rich for doing meta theory on Isabelle itself. Extensions in this direction are possible though.

Moreover, the chosen fragment is fairly rudimentary. However it should be easily adapted to one's needs if a package is written on top of it. The supported API contains types, terms, transformation of global context like definitions and data-type declarations as well as infrastructure for Isar-setups.

This theory is drawn from the Featherweight OCL project where it is used to construct a package for object-oriented data-type theories generated from UML class diagrams. The Featherweight OCL, for example, allows for both the direct execution of compiled tactic code by the Isabelle API as well as the generation of ".thy"-files for debugging purposes.

Gained experience from this project shows that the compiled code is sufficiently efficient for practical purposes while being based on a formal model on which properties of the package can be proven such as termination of certain transformations, correctness, etc. notify = tuong@users.gforge.inria.fr, wolff@lri.fr [Clean] title = Clean - An Abstract Imperative Programming Language and its Theory author = Frédéric Tuong , Burkhart Wolff topic = Computer science/Programming languages, Computer science/Semantics date = 2019-10-04 notify = wolff@lri.fr, ftuong@lri.fr abstract = Clean is based on a simple, abstract execution model for an imperative target language. “Abstract” is understood in contrast to “Concrete Semantics”; alternatively, the term “shallow-style embedding” could be used. It strives for a type-safe notion of program-variables, an incremental construction of the typed state-space, support of incremental verification, and open-world extensibility of new type definitions being intertwined with the program definitions. Clean is based on a “no-frills” state-exception monad with the usual definitions of bind and unit for the compositional glue of state-based computations. Clean offers conditionals and loops supporting C-like control-flow operators such as break and return. The state-space construction is based on the extensible record package. Direct recursion of procedures is supported. Clean’s design strives for extreme simplicity. It is geared towards symbolic execution and proven correct verification tools. The underlying libraries of this package, however, deliberately restrict themselves to the most elementary infrastructure for these tasks. The package is intended to serve as demonstrator semantic backend for Isabelle/C, or for the test-generation techniques. [PCF] title = Logical Relations for PCF author = Peter Gammie date = 2012-07-01 topic = Computer science/Programming languages/Lambda calculi abstract = We apply Andy Pitts's methods of defining relations over domains to several classical results in the literature. We show that the Y combinator coincides with the domain-theoretic fixpoint operator, that parallel-or and the Plotkin existential are not definable in PCF, that the continuation semantics for PCF coincides with the direct semantics, and that our domain-theoretic semantics for PCF is adequate for reasoning about contextual equivalence in an operational semantics. Our version of PCF is untyped and has both strict and non-strict function abstractions. The development is carried out in HOLCF. notify = peteg42@gmail.com [POPLmark-deBruijn] title = POPLmark Challenge Via de Bruijn Indices author = Stefan Berghofer date = 2007-08-02 topic = Computer science/Programming languages/Lambda calculi abstract = We present a solution to the POPLmark challenge designed by Aydemir et al., which has as a goal the formalization of the meta-theory of System F<:. The formalization is carried out in the theorem prover Isabelle/HOL using an encoding based on de Bruijn indices. We start with a relatively simple formalization covering only the basic features of System F<:, and explain how it can be extended to also cover records and more advanced binding constructs. notify = berghofe@in.tum.de [Lam-ml-Normalization] title = Strong Normalization of Moggis's Computational Metalanguage author = Christian Doczkal date = 2010-08-29 topic = Computer science/Programming languages/Lambda calculi abstract = Handling variable binding is one of the main difficulties in formal proofs. In this context, Moggi's computational metalanguage serves as an interesting case study. It features monadic types and a commuting conversion rule that rearranges the binding structure. Lindley and Stark have given an elegant proof of strong normalization for this calculus. The key construction in their proof is a notion of relational TT-lifting, using stacks of elimination contexts to obtain a Girard-Tait style logical relation. I give a formalization of their proof in Isabelle/HOL-Nominal with a particular emphasis on the treatment of bound variables. notify = doczkal@ps.uni-saarland.de, nipkow@in.tum.de [MiniML] title = Mini ML author = Wolfgang Naraschewski <>, Tobias Nipkow date = 2004-03-19 topic = Computer science/Programming languages/Type systems abstract = This theory defines the type inference rules and the type inference algorithm W for MiniML (simply-typed lambda terms with let) due to Milner. It proves the soundness and completeness of W w.r.t. the rules. notify = kleing@cse.unsw.edu.au [Simpl] title = A Sequential Imperative Programming Language Syntax, Semantics, Hoare Logics and Verification Environment author = Norbert Schirmer <> date = 2008-02-29 topic = Computer science/Programming languages/Language definitions, Computer science/Programming languages/Logics license = LGPL abstract = We present the theory of Simpl, a sequential imperative programming language. We introduce its syntax, its semantics (big and small-step operational semantics) and Hoare logics for both partial as well as total correctness. We prove soundness and completeness of the Hoare logic. We integrate and automate the Hoare logic in Isabelle/HOL to obtain a practically usable verification environment for imperative programs. Simpl is independent of a concrete programming language but expressive enough to cover all common language features: mutually recursive procedures, abrupt termination and exceptions, runtime faults, local and global variables, pointers and heap, expressions with side effects, pointers to procedures, partial application and closures, dynamic method invocation and also unbounded nondeterminism. notify = kleing@cse.unsw.edu.au, norbert.schirmer@web.de [Separation_Algebra] title = Separation Algebra author = Gerwin Klein , Rafal Kolanski , Andrew Boyton date = 2012-05-11 topic = Computer science/Programming languages/Logics license = BSD abstract = We present a generic type class implementation of separation algebra for Isabelle/HOL as well as lemmas and generic tactics which can be used directly for any instantiation of the type class.

The ex directory contains example instantiations that include structures such as a heap or virtual memory.

The abstract separation algebra is based upon "Abstract Separation Logic" by Calcagno et al. These theories are also the basis of the ITP 2012 rough diamond "Mechanised Separation Algebra" by the authors.

The aim of this work is to support and significantly reduce the effort for future separation logic developments in Isabelle/HOL by factoring out the part of separation logic that can be treated abstractly once and for all. This includes developing typical default rule sets for reasoning as well as automated tactic support for separation logic. notify = kleing@cse.unsw.edu.au, rafal.kolanski@nicta.com.au [Separation_Logic_Imperative_HOL] title = A Separation Logic Framework for Imperative HOL author = Peter Lammich , Rene Meis date = 2012-11-14 topic = Computer science/Programming languages/Logics license = BSD abstract = We provide a framework for separation-logic based correctness proofs of Imperative HOL programs. Our framework comes with a set of proof methods to automate canonical tasks such as verification condition generation and frame inference. Moreover, we provide a set of examples that show the applicability of our framework. The examples include algorithms on lists, hash-tables, and union-find trees. We also provide abstract interfaces for lists, maps, and sets, that allow to develop generic imperative algorithms and use data-refinement techniques.
As we target Imperative HOL, our programs can be translated to efficiently executable code in various target languages, including ML, OCaml, Haskell, and Scala. notify = lammich@in.tum.de [Inductive_Confidentiality] title = Inductive Study of Confidentiality author = Giampaolo Bella date = 2012-05-02 topic = Computer science/Security abstract = This document contains the full theory files accompanying article Inductive Study of Confidentiality --- for Everyone in Formal Aspects of Computing. They aim at an illustrative and didactic presentation of the Inductive Method of protocol analysis, focusing on the treatment of one of the main goals of security protocols: confidentiality against a threat model. The treatment of confidentiality, which in fact forms a key aspect of all protocol analysis tools, has been found cryptic by many learners of the Inductive Method, hence the motivation for this work. The theory files in this document guide the reader step by step towards design and proof of significant confidentiality theorems. These are developed against two threat models, the standard Dolev-Yao and a more audacious one, the General Attacker, which turns out to be particularly useful also for teaching purposes. notify = giamp@dmi.unict.it [Possibilistic_Noninterference] title = Possibilistic Noninterference author = Andrei Popescu , Johannes Hölzl date = 2012-09-10 topic = Computer science/Security, Computer science/Programming languages/Type systems abstract = We formalize a wide variety of Volpano/Smith-style noninterference notions for a while language with parallel composition. We systematize and classify these notions according to compositionality w.r.t. the language constructs. Compositionality yields sound syntactic criteria (a.k.a. type systems) in a uniform way.

An article about these proofs is published in the proceedings of the conference Certified Programs and Proofs 2012. notify = hoelzl@in.tum.de [SIFUM_Type_Systems] title = A Formalization of Assumptions and Guarantees for Compositional Noninterference author = Sylvia Grewe , Heiko Mantel , Daniel Schoepe date = 2014-04-23 topic = Computer science/Security, Computer science/Programming languages/Type systems abstract = Research in information-flow security aims at developing methods to identify undesired information leaks within programs from private (high) sources to public (low) sinks. For a concurrent system, it is desirable to have compositional analysis methods that allow for analyzing each thread independently and that nevertheless guarantee that the parallel composition of successfully analyzed threads satisfies a global security guarantee. However, such a compositional analysis should not be overly pessimistic about what an environment might do with shared resources. Otherwise, the analysis will reject many intuitively secure programs.

The paper "Assumptions and Guarantees for Compositional Noninterference" by Mantel et. al. presents one solution for this problem: an approach for compositionally reasoning about non-interference in concurrent programs via rely-guarantee-style reasoning. We present an Isabelle/HOL formalization of the concepts and proofs of this approach. notify = [Dependent_SIFUM_Type_Systems] title = A Dependent Security Type System for Concurrent Imperative Programs author = Toby Murray , Robert Sison<>, Edward Pierzchalski<>, Christine Rizkallah notify = toby.murray@unimelb.edu.au date = 2016-06-25 topic = Computer science/Security, Computer science/Programming languages/Type systems abstract = The paper "Compositional Verification and Refinement of Concurrent Value-Dependent Noninterference" by Murray et. al. (CSF 2016) presents a dependent security type system for compositionally verifying a value-dependent noninterference property, defined in (Murray, PLAS 2015), for concurrent programs. This development formalises that security definition, the type system and its soundness proof, and demonstrates its application on some small examples. It was derived from the SIFUM_Type_Systems AFP entry, by Sylvia Grewe, Heiko Mantel and Daniel Schoepe, and whose structure it inherits. extra-history = Change history: [2016-08-19]: Removed unused "stop" parameter and "stop_no_eval" assumption from the sifum_security locale. (revision dbc482d36372) [2016-09-27]: Added security locale support for the imposition of requirements on the initial memory. (revision cce4ceb74ddb) [Dependent_SIFUM_Refinement] title = Compositional Security-Preserving Refinement for Concurrent Imperative Programs author = Toby Murray , Robert Sison<>, Edward Pierzchalski<>, Christine Rizkallah notify = toby.murray@unimelb.edu.au date = 2016-06-28 topic = Computer science/Security abstract = The paper "Compositional Verification and Refinement of Concurrent Value-Dependent Noninterference" by Murray et. al. (CSF 2016) presents a compositional theory of refinement for a value-dependent noninterference property, defined in (Murray, PLAS 2015), for concurrent programs. This development formalises that refinement theory, and demonstrates its application on some small examples. extra-history = Change history: [2016-08-19]: Removed unused "stop" parameters from the sifum_refinement locale. (revision dbc482d36372) [2016-09-02]: TobyM extended "simple" refinement theory to be usable for all bisimulations. (revision 547f31c25f60) [Relational-Incorrectness-Logic] title = An Under-Approximate Relational Logic author = Toby Murray topic = Computer science/Programming languages/Logics, Computer science/Security date = 2020-03-12 notify = toby.murray@unimelb.edu.au abstract = Recently, authors have proposed under-approximate logics for reasoning about programs. So far, all such logics have been confined to reasoning about individual program behaviours. Yet there exist many over-approximate relational logics for reasoning about pairs of programs and relating their behaviours. We present the first under-approximate relational logic, for the simple imperative language IMP. We prove our logic is both sound and complete. Additionally, we show how reasoning in this logic can be decomposed into non-relational reasoning in an under-approximate Hoare logic, mirroring Beringer’s result for over-approximate relational logics. We illustrate the application of our logic on some small examples in which we provably demonstrate the presence of insecurity. [Strong_Security] title = A Formalization of Strong Security author = Sylvia Grewe , Alexander Lux , Heiko Mantel , Jens Sauer date = 2014-04-23 topic = Computer science/Security, Computer science/Programming languages/Type systems abstract = Research in information-flow security aims at developing methods to identify undesired information leaks within programs from private sources to public sinks. Noninterference captures this intuition. Strong security from Sabelfeld and Sands formalizes noninterference for concurrent systems.

We present an Isabelle/HOL formalization of strong security for arbitrary security lattices (Sabelfeld and Sands use a two-element security lattice in the original publication). The formalization includes compositionality proofs for strong security and a soundness proof for a security type system that checks strong security for programs in a simple while language with dynamic thread creation.

Our formalization of the security type system is abstract in the language for expressions and in the semantic side conditions for expressions. It can easily be instantiated with different syntactic approximations for these side conditions. The soundness proof of such an instantiation boils down to showing that these syntactic approximations imply the semantic side conditions. notify = [WHATandWHERE_Security] title = A Formalization of Declassification with WHAT-and-WHERE-Security author = Sylvia Grewe , Alexander Lux , Heiko Mantel , Jens Sauer date = 2014-04-23 topic = Computer science/Security, Computer science/Programming languages/Type systems abstract = Research in information-flow security aims at developing methods to identify undesired information leaks within programs from private sources to public sinks. Noninterference captures this intuition by requiring that no information whatsoever flows from private sources to public sinks. However, in practice this definition is often too strict: Depending on the intuitive desired security policy, the controlled declassification of certain private information (WHAT) at certain points in the program (WHERE) might not result in an undesired information leak.

We present an Isabelle/HOL formalization of such a security property for controlled declassification, namely WHAT&WHERE-security from "Scheduler-Independent Declassification" by Lux, Mantel, and Perner. The formalization includes compositionality proofs for and a soundness proof for a security type system that checks for programs in a simple while language with dynamic thread creation.

Our formalization of the security type system is abstract in the language for expressions and in the semantic side conditions for expressions. It can easily be instantiated with different syntactic approximations for these side conditions. The soundness proof of such an instantiation boils down to showing that these syntactic approximations imply the semantic side conditions.

This Isabelle/HOL formalization uses theories from the entry Strong Security. notify = [VolpanoSmith] title = A Correctness Proof for the Volpano/Smith Security Typing System author = Gregor Snelting , Daniel Wasserrab date = 2008-09-02 topic = Computer science/Programming languages/Type systems, Computer science/Security abstract = The Volpano/Smith/Irvine security type systems requires that variables are annotated as high (secret) or low (public), and provides typing rules which guarantee that secret values cannot leak to public output ports. This property of a program is called confidentiality. For a simple while-language without threads, our proof shows that typeability in the Volpano/Smith system guarantees noninterference. Noninterference means that if two initial states for program execution are low-equivalent, then the final states are low-equivalent as well. This indeed implies that secret values cannot leak to public ports. The proof defines an abstract syntax and operational semantics for programs, formalizes noninterference, and then proceeds by rule induction on the operational semantics. The mathematically most intricate part is the treatment of implicit flows. Note that the Volpano/Smith system is not flow-sensitive and thus quite unprecise, resulting in false alarms. However, due to the correctness property, all potential breaks of confidentiality are discovered. notify = [Abstract-Hoare-Logics] title = Abstract Hoare Logics author = Tobias Nipkow date = 2006-08-08 topic = Computer science/Programming languages/Logics abstract = These therories describe Hoare logics for a number of imperative language constructs, from while-loops to mutually recursive procedures. Both partial and total correctness are treated. In particular a proof system for total correctness of recursive procedures in the presence of unbounded nondeterminism is presented. notify = nipkow@in.tum.de [Stone_Algebras] title = Stone Algebras author = Walter Guttmann notify = walter.guttmann@canterbury.ac.nz date = 2016-09-06 topic = Mathematics/Order abstract = A range of algebras between lattices and Boolean algebras generalise the notion of a complement. We develop a hierarchy of these pseudo-complemented algebras that includes Stone algebras. Independently of this theory we study filters based on partial orders. Both theories are combined to prove Chen and Grätzer's construction theorem for Stone algebras. The latter involves extensive reasoning about algebraic structures in addition to reasoning in algebraic structures. [Kleene_Algebra] title = Kleene Algebra author = Alasdair Armstrong <>, Georg Struth , Tjark Weber date = 2013-01-15 topic = Computer science/Programming languages/Logics, Computer science/Automata and formal languages, Mathematics/Algebra abstract = These files contain a formalisation of variants of Kleene algebras and their most important models as axiomatic type classes in Isabelle/HOL. Kleene algebras are foundational structures in computing with applications ranging from automata and language theory to computational modeling, program construction and verification.

We start with formalising dioids, which are additively idempotent semirings, and expand them by axiomatisations of the Kleene star for finite iteration and an omega operation for infinite iteration. We show that powersets over a given monoid, (regular) languages, sets of paths in a graph, sets of computation traces, binary relations and formal power series form Kleene algebras, and consider further models based on lattices, max-plus semirings and min-plus semirings. We also demonstrate that dioids are closed under the formation of matrices (proofs for Kleene algebras remain to be completed).

On the one hand we have aimed at a reference formalisation of variants of Kleene algebras that covers a wide range of variants and the core theorems in a structured and modular way and provides readable proofs at text book level. On the other hand, we intend to use this algebraic hierarchy and its models as a generic algebraic middle-layer from which programming applications can quickly be explored, implemented and verified. notify = g.struth@sheffield.ac.uk, tjark.weber@it.uu.se [KAT_and_DRA] title = Kleene Algebra with Tests and Demonic Refinement Algebras author = Alasdair Armstrong <>, Victor B. F. Gomes , Georg Struth date = 2014-01-23 topic = Computer science/Programming languages/Logics, Computer science/Automata and formal languages, Mathematics/Algebra abstract = We formalise Kleene algebra with tests (KAT) and demonic refinement algebra (DRA) in Isabelle/HOL. KAT is relevant for program verification and correctness proofs in the partial correctness setting. While DRA targets similar applications in the context of total correctness. Our formalisation contains the two most important models of these algebras: binary relations in the case of KAT and predicate transformers in the case of DRA. In addition, we derive the inference rules for Hoare logic in KAT and its relational model and present a simple formally verified program verification tool prototype based on the algebraic approach. notify = g.struth@dcs.shef.ac.uk [KAD] title = Kleene Algebras with Domain author = Victor B. F. Gomes , Walter Guttmann , Peter Höfner , Georg Struth , Tjark Weber date = 2016-04-12 topic = Computer science/Programming languages/Logics, Computer science/Automata and formal languages, Mathematics/Algebra abstract = Kleene algebras with domain are Kleene algebras endowed with an operation that maps each element of the algebra to its domain of definition (or its complement) in abstract fashion. They form a simple algebraic basis for Hoare logics, dynamic logics or predicate transformer semantics. We formalise a modular hierarchy of algebras with domain and antidomain (domain complement) operations in Isabelle/HOL that ranges from domain and antidomain semigroups to modal Kleene algebras and divergence Kleene algebras. We link these algebras with models of binary relations and program traces. We include some examples from modal logics, termination and program analysis. notify = walter.guttman@canterbury.ac.nz, g.struth@sheffield.ac.uk, tjark.weber@it.uu.se [Regular_Algebras] title = Regular Algebras author = Simon Foster , Georg Struth date = 2014-05-21 topic = Computer science/Automata and formal languages, Mathematics/Algebra abstract = Regular algebras axiomatise the equational theory of regular expressions as induced by regular language identity. We use Isabelle/HOL for a detailed systematic study of regular algebras given by Boffa, Conway, Kozen and Salomaa. We investigate the relationships between these classes, formalise a soundness proof for the smallest class (Salomaa's) and obtain completeness of the largest one (Boffa's) relative to a deep result by Krob. In addition we provide a large collection of regular identities in the general setting of Boffa's axiom. Our regular algebra hierarchy is orthogonal to the Kleene algebra hierarchy in the Archive of Formal Proofs; we have not aimed at an integration for pragmatic reasons. notify = simon.foster@york.ac.uk, g.struth@sheffield.ac.uk [BytecodeLogicJmlTypes] title = A Bytecode Logic for JML and Types author = Lennart Beringer <>, Martin Hofmann date = 2008-12-12 topic = Computer science/Programming languages/Logics abstract = This document contains the Isabelle/HOL sources underlying the paper A bytecode logic for JML and types by Beringer and Hofmann, updated to Isabelle 2008. We present a program logic for a subset of sequential Java bytecode that is suitable for representing both, features found in high-level specification language JML as well as interpretations of high-level type systems. To this end, we introduce a fine-grained collection of assertions, including strong invariants, local annotations and VDM-reminiscent partial-correctness specifications. Thanks to a goal-oriented structure and interpretation of judgements, verification may proceed without recourse to an additional control flow analysis. The suitability for interpreting intensional type systems is illustrated by the proof-carrying-code style encoding of a type system for a first-order functional language which guarantees a constant upper bound on the number of objects allocated throughout an execution, be the execution terminating or non-terminating. Like the published paper, the formal development is restricted to a comparatively small subset of the JVML, lacking (among other features) exceptions, arrays, virtual methods, and static fields. This shortcoming has been overcome meanwhile, as our paper has formed the basis of the Mobius base logic, a program logic for the full sequential fragment of the JVML. Indeed, the present formalisation formed the basis of a subsequent formalisation of the Mobius base logic in the proof assistant Coq, which includes a proof of soundness with respect to the Bicolano operational semantics by Pichardie. notify = [DataRefinementIBP] title = Semantics and Data Refinement of Invariant Based Programs author = Viorel Preoteasa , Ralph-Johan Back date = 2010-05-28 topic = Computer science/Programming languages/Logics abstract = The invariant based programming is a technique of constructing correct programs by first identifying the basic situations (pre- and post-conditions and invariants) that can occur during the execution of the program, and then defining the transitions and proving that they preserve the invariants. Data refinement is a technique of building correct programs working on concrete datatypes as refinements of more abstract programs. In the theories presented here we formalize the predicate transformer semantics for invariant based programs and their data refinement. extra-history = Change history: [2012-01-05]: Moved some general complete lattice properties to the AFP entry Lattice Properties. Changed the definition of the data refinement relation to be more general and updated all corresponding theorems. Added new syntax for demonic and angelic update statements. notify = viorel.preoteasa@aalto.fi [RefinementReactive] title = Formalization of Refinement Calculus for Reactive Systems author = Viorel Preoteasa date = 2014-10-08 topic = Computer science/Programming languages/Logics abstract = We present a formalization of refinement calculus for reactive systems. Refinement calculus is based on monotonic predicate transformers (monotonic functions from sets of post-states to sets of pre-states), and it is a powerful formalism for reasoning about imperative programs. We model reactive systems as monotonic property transformers that transform sets of output infinite sequences into sets of input infinite sequences. Within this semantics we can model refinement of reactive systems, (unbounded) angelic and demonic nondeterminism, sequential composition, and other semantic properties. We can model systems that may fail for some inputs, and we can model compatibility of systems. We can specify systems that have liveness properties using linear temporal logic, and we can refine system specifications into systems based on symbolic transitions systems, suitable for implementations. notify = viorel.preoteasa@aalto.fi [SIFPL] title = Secure information flow and program logics author = Lennart Beringer <>, Martin Hofmann date = 2008-11-10 topic = Computer science/Programming languages/Logics, Computer science/Security abstract = We present interpretations of type systems for secure information flow in Hoare logic, complementing previous encodings in relational program logics. We first treat the imperative language IMP, extended by a simple procedure call mechanism. For this language we consider base-line non-interference in the style of Volpano et al. and the flow-sensitive type system by Hunt and Sands. In both cases, we show how typing derivations may be used to automatically generate proofs in the program logic that certify the absence of illicit flows. We then add instructions for object creation and manipulation, and derive appropriate proof rules for base-line non-interference. As a consequence of our work, standard verification technology may be used for verifying that a concrete program satisfies the non-interference property.

The present proof development represents an update of the formalisation underlying our paper [CSF 2007] and is intended to resolve any ambiguities that may be present in the paper. notify = lennart.beringer@ifi.lmu.de [TLA] title = A Definitional Encoding of TLA* in Isabelle/HOL author = Gudmund Grov , Stephan Merz date = 2011-11-19 topic = Computer science/Programming languages/Logics abstract = We mechanise the logic TLA* [Merz 1999], an extension of Lamport's Temporal Logic of Actions (TLA) [Lamport 1994] for specifying and reasoning about concurrent and reactive systems. Aiming at a framework for mechanising] the verification of TLA (or TLA*) specifications, this contribution reuses some elements from a previous axiomatic encoding of TLA in Isabelle/HOL by the second author [Merz 1998], which has been part of the Isabelle distribution. In contrast to that previous work, we give here a shallow, definitional embedding, with the following highlights:

  • a theory of infinite sequences, including a formalisation of the concepts of stuttering invariance central to TLA and TLA*;
  • a definition of the semantics of TLA*, which extends TLA by a mutually-recursive definition of formulas and pre-formulas, generalising TLA action formulas;
  • a substantial set of derived proof rules, including the TLA* axioms and Lamport's proof rules for system verification;
  • a set of examples illustrating the usage of Isabelle/TLA* for reasoning about systems.
Note that this work is unrelated to the ongoing development of a proof system for the specification language TLA+, which includes an encoding of TLA+ as a new Isabelle object logic [Chaudhuri et al 2010]. notify = ggrov@inf.ed.ac.uk [Compiling-Exceptions-Correctly] title = Compiling Exceptions Correctly author = Tobias Nipkow date = 2004-07-09 topic = Computer science/Programming languages/Compiling abstract = An exception compilation scheme that dynamically creates and removes exception handler entries on the stack. A formalization of an article of the same name by Hutton and Wright. notify = nipkow@in.tum.de [NormByEval] title = Normalization by Evaluation author = Klaus Aehlig , Tobias Nipkow date = 2008-02-18 topic = Computer science/Programming languages/Compiling abstract = This article formalizes normalization by evaluation as implemented in Isabelle. Lambda calculus plus term rewriting is compiled into a functional program with pattern matching. It is proved that the result of a successful evaluation is a) correct, i.e. equivalent to the input, and b) in normal form. notify = nipkow@in.tum.de [Program-Conflict-Analysis] title = Formalization of Conflict Analysis of Programs with Procedures, Thread Creation, and Monitors topic = Computer science/Programming languages/Static analysis author = Peter Lammich , Markus Müller-Olm date = 2007-12-14 abstract = In this work we formally verify the soundness and precision of a static program analysis that detects conflicts (e. g. data races) in programs with procedures, thread creation and monitors with the Isabelle theorem prover. As common in static program analysis, our program model abstracts guarded branching by nondeterministic branching, but completely interprets the call-/return behavior of procedures, synchronization by monitors, and thread creation. The analysis is based on the observation that all conflicts already occur in a class of particularly restricted schedules. These restricted schedules are suited to constraint-system-based program analysis. The formalization is based upon a flowgraph-based program model with an operational semantics as reference point. notify = peter.lammich@uni-muenster.de [Shivers-CFA] title = Shivers' Control Flow Analysis topic = Computer science/Programming languages/Static analysis author = Joachim Breitner date = 2010-11-16 abstract = In his dissertation, Olin Shivers introduces a concept of control flow graphs for functional languages, provides an algorithm to statically derive a safe approximation of the control flow graph and proves this algorithm correct. In this research project, Shivers' algorithms and proofs are formalized in the HOLCF extension of HOL. notify = mail@joachim-breitner.de, nipkow@in.tum.de [Slicing] title = Towards Certified Slicing author = Daniel Wasserrab date = 2008-09-16 topic = Computer science/Programming languages/Static analysis abstract = Slicing is a widely-used technique with applications in e.g. compiler technology and software security. Thus verification of algorithms in these areas is often based on the correctness of slicing, which should ideally be proven independent of concrete programming languages and with the help of well-known verifying techniques such as proof assistants. As a first step in this direction, this contribution presents a framework for dynamic and static intraprocedural slicing based on control flow and program dependence graphs. Abstracting from concrete syntax we base the framework on a graph representation of the program fulfilling certain structural and well-formedness properties.

The formalization consists of the basic framework (in subdirectory Basic/), the correctness proof for dynamic slicing (in subdirectory Dynamic/), the correctness proof for static intraprocedural slicing (in subdirectory StaticIntra/) and instantiations of the framework with a simple While language (in subdirectory While/) and the sophisticated object-oriented bytecode language of Jinja (in subdirectory JinjaVM/). For more information on the framework, see the TPHOLS 2008 paper by Wasserrab and Lochbihler and the PLAS 2009 paper by Wasserrab et al. notify = [HRB-Slicing] title = Backing up Slicing: Verifying the Interprocedural Two-Phase Horwitz-Reps-Binkley Slicer author = Daniel Wasserrab date = 2009-11-13 topic = Computer science/Programming languages/Static analysis abstract = After verifying dynamic and static interprocedural slicing, we present a modular framework for static interprocedural slicing. To this end, we formalized the standard two-phase slicer from Horwitz, Reps and Binkley (see their TOPLAS 12(1) 1990 paper) together with summary edges as presented by Reps et al. (see FSE 1994). The framework is again modular in the programming language by using an abstract CFG, defined via structural and well-formedness properties. Using a weak simulation between the original and sliced graph, we were able to prove the correctness of static interprocedural slicing. We also instantiate our framework with a simple While language with procedures. This shows that the chosen abstractions are indeed valid. notify = nipkow@in.tum.de [WorkerWrapper] title = The Worker/Wrapper Transformation author = Peter Gammie date = 2009-10-30 topic = Computer science/Programming languages/Transformations abstract = Gill and Hutton formalise the worker/wrapper transformation, building on the work of Launchbury and Peyton-Jones who developed it as a way of changing the type at which a recursive function operates. This development establishes the soundness of the technique and several examples of its use. notify = peteg42@gmail.com, nipkow@in.tum.de [JiveDataStoreModel] title = Jive Data and Store Model author = Nicole Rauch , Norbert Schirmer <> date = 2005-06-20 license = LGPL topic = Computer science/Programming languages/Misc abstract = This document presents the formalization of an object-oriented data and store model in Isabelle/HOL. This model is being used in the Java Interactive Verification Environment, Jive. notify = kleing@cse.unsw.edu.au, schirmer@in.tum.de [HotelKeyCards] title = Hotel Key Card System author = Tobias Nipkow date = 2006-09-09 topic = Computer science/Security abstract = Two models of an electronic hotel key card system are contrasted: a state based and a trace based one. Both are defined, verified, and proved equivalent in the theorem prover Isabelle/HOL. It is shown that if a guest follows a certain safety policy regarding her key cards, she can be sure that nobody but her can enter her room. notify = nipkow@in.tum.de [RSAPSS] title = SHA1, RSA, PSS and more author = Christina Lindenberg <>, Kai Wirt <> date = 2005-05-02 topic = Computer science/Security/Cryptography abstract = Formal verification is getting more and more important in computer science. However the state of the art formal verification methods in cryptography are very rudimentary. These theories are one step to provide a tool box allowing the use of formal methods in every aspect of cryptography. Moreover we present a proof of concept for the feasibility of verification techniques to a standard signature algorithm. notify = nipkow@in.tum.de [InformationFlowSlicing] title = Information Flow Noninterference via Slicing author = Daniel Wasserrab date = 2010-03-23 topic = Computer science/Security abstract =

In this contribution, we show how correctness proofs for intra- and interprocedural slicing can be used to prove that slicing is able to guarantee information flow noninterference. Moreover, we also illustrate how to lift the control flow graphs of the respective frameworks such that they fulfil the additional assumptions needed in the noninterference proofs. A detailed description of the intraprocedural proof and its interplay with the slicing framework can be found in the PLAS'09 paper by Wasserrab et al.

This entry contains the part for intra-procedural slicing. See entry InformationFlowSlicing_Inter for the inter-procedural part.

extra-history = Change history: [2016-06-10]: The original entry InformationFlowSlicing contained both the inter- and intra-procedural case was split into two for easier maintenance. notify = [InformationFlowSlicing_Inter] title = Inter-Procedural Information Flow Noninterference via Slicing author = Daniel Wasserrab date = 2010-03-23 topic = Computer science/Security abstract =

In this contribution, we show how correctness proofs for intra- and interprocedural slicing can be used to prove that slicing is able to guarantee information flow noninterference. Moreover, we also illustrate how to lift the control flow graphs of the respective frameworks such that they fulfil the additional assumptions needed in the noninterference proofs. A detailed description of the intraprocedural proof and its interplay with the slicing framework can be found in the PLAS'09 paper by Wasserrab et al.

This entry contains the part for inter-procedural slicing. See entry InformationFlowSlicing for the intra-procedural part.

extra-history = Change history: [2016-06-10]: The original entry InformationFlowSlicing contained both the inter- and intra-procedural case was split into two for easier maintenance. notify = [ComponentDependencies] title = Formalisation and Analysis of Component Dependencies author = Maria Spichkova date = 2014-04-28 topic = Computer science/System description languages abstract = This set of theories presents a formalisation in Isabelle/HOL of data dependencies between components. The approach allows to analyse system structure oriented towards efficient checking of system: it aims at elaborating for a concrete system, which parts of the system are necessary to check a given property. notify = maria.spichkova@rmit.edu.au [Verified-Prover] title = A Mechanically Verified, Efficient, Sound and Complete Theorem Prover For First Order Logic author = Tom Ridge <> date = 2004-09-28 topic = Logic/General logic/Mechanization of proofs abstract = Soundness and completeness for a system of first order logic are formally proved, building on James Margetson's formalization of work by Wainer and Wallen. The completeness proofs naturally suggest an algorithm to derive proofs. This algorithm, which can be implemented tail recursively, is formalized in Isabelle/HOL. The algorithm can be executed via the rewriting tactics of Isabelle. Alternatively, the definitions can be exported to OCaml, yielding a directly executable program. notify = lp15@cam.ac.uk [Completeness] title = Completeness theorem author = James Margetson <>, Tom Ridge <> date = 2004-09-20 topic = Logic/Proof theory abstract = The completeness of first-order logic is proved, following the first five pages of Wainer and Wallen's chapter of the book Proof Theory by Aczel et al., CUP, 1992. Their presentation of formulas allows the proofs to use symmetry arguments. Margetson formalized this theorem by early 2000. The Isar conversion is thanks to Tom Ridge. A paper describing the formalization is available [pdf]. notify = lp15@cam.ac.uk [Ordinal] title = Countable Ordinals author = Brian Huffman date = 2005-11-11 topic = Logic/Set theory abstract = This development defines a well-ordered type of countable ordinals. It includes notions of continuous and normal functions, recursively defined functions over ordinals, least fixed-points, and derivatives. Much of ordinal arithmetic is formalized, including exponentials and logarithms. The development concludes with formalizations of Cantor Normal Form and Veblen hierarchies over normal functions. notify = lcp@cl.cam.ac.uk [Ordinals_and_Cardinals] title = Ordinals and Cardinals author = Andrei Popescu date = 2009-09-01 topic = Logic/Set theory abstract = We develop a basic theory of ordinals and cardinals in Isabelle/HOL, up to the point where some cardinality facts relevant for the ``working mathematician" become available. Unlike in set theory, here we do not have at hand canonical notions of ordinal and cardinal. Therefore, here an ordinal is merely a well-order relation and a cardinal is an ordinal minim w.r.t. order embedding on its field. extra-history = Change history: [2012-09-25]: This entry has been discontinued because it is now part of the Isabelle distribution. notify = uuomul@yahoo.com, nipkow@in.tum.de [FOL-Fitting] title = First-Order Logic According to Fitting author = Stefan Berghofer contributors = Asta Halkjær From date = 2007-08-02 topic = Logic/General logic/Classical first-order logic abstract = We present a formalization of parts of Melvin Fitting's book "First-Order Logic and Automated Theorem Proving". The formalization covers the syntax of first-order logic, its semantics, the model existence theorem, a natural deduction proof calculus together with a proof of correctness and completeness, as well as the Löwenheim-Skolem theorem. extra-history = Change history: [2018-07-21]: Proved completeness theorem for open formulas. Proofs are now written in the declarative style. Enumeration of pairs and datatypes is automated using the Countable theory. notify = berghofe@in.tum.de [Epistemic_Logic] title = Epistemic Logic author = Asta Halkjær From topic = Logic/General logic/Logics of knowledge and belief date = 2018-10-29 notify = ahfrom@dtu.dk abstract = This work is a formalization of epistemic logic with countably many agents. It includes proofs of soundness and completeness for the axiom system K. The completeness proof is based on the textbook "Reasoning About Knowledge" by Fagin, Halpern, Moses and Vardi (MIT Press 1995). [SequentInvertibility] title = Invertibility in Sequent Calculi author = Peter Chapman <> date = 2009-08-28 topic = Logic/Proof theory license = LGPL abstract = The invertibility of the rules of a sequent calculus is important for guiding proof search and can be used in some formalised proofs of Cut admissibility. We present sufficient conditions for when a rule is invertible with respect to a calculus. We illustrate the conditions with examples. It must be noted we give purely syntactic criteria; no guarantees are given as to the suitability of the rules. notify = pc@cs.st-andrews.ac.uk, nipkow@in.tum.de [LinearQuantifierElim] title = Quantifier Elimination for Linear Arithmetic author = Tobias Nipkow date = 2008-01-11 topic = Logic/General logic/Decidability of theories abstract = This article formalizes quantifier elimination procedures for dense linear orders, linear real arithmetic and Presburger arithmetic. In each case both a DNF-based non-elementary algorithm and one or more (doubly) exponential NNF-based algorithms are formalized, including the well-known algorithms by Ferrante and Rackoff and by Cooper. The NNF-based algorithms for dense linear orders are new but based on Ferrante and Rackoff and on an algorithm by Loos and Weisspfenning which simulates infenitesimals. All algorithms are directly executable. In particular, they yield reflective quantifier elimination procedures for HOL itself. The formalization makes heavy use of locales and is therefore highly modular. notify = nipkow@in.tum.de [Nat-Interval-Logic] title = Interval Temporal Logic on Natural Numbers author = David Trachtenherz <> date = 2011-02-23 topic = Logic/General logic/Temporal logic abstract = We introduce a theory of temporal logic operators using sets of natural numbers as time domain, formalized in a shallow embedding manner. The theory comprises special natural intervals (theory IL_Interval: open and closed intervals, continuous and modulo intervals, interval traversing results), operators for shifting intervals to left/right on the number axis as well as expanding/contracting intervals by constant factors (theory IL_IntervalOperators.thy), and ultimately definitions and results for unary and binary temporal operators on arbitrary natural sets (theory IL_TemporalOperators). notify = nipkow@in.tum.de [Recursion-Theory-I] title = Recursion Theory I author = Michael Nedzelsky <> date = 2008-04-05 topic = Logic/Computability abstract = This document presents the formalization of introductory material from recursion theory --- definitions and basic properties of primitive recursive functions, Cantor pairing function and computably enumerable sets (including a proof of existence of a one-complete computably enumerable set and a proof of the Rice's theorem). notify = MichaelNedzelsky@yandex.ru [Free-Boolean-Algebra] topic = Logic/General logic/Classical propositional logic title = Free Boolean Algebra author = Brian Huffman date = 2010-03-29 abstract = This theory defines a type constructor representing the free Boolean algebra over a set of generators. Values of type (α)formula represent propositional formulas with uninterpreted variables from type α, ordered by implication. In addition to all the standard Boolean algebra operations, the library also provides a function for building homomorphisms to any other Boolean algebra type. notify = brianh@cs.pdx.edu [Sort_Encodings] title = Sound and Complete Sort Encodings for First-Order Logic author = Jasmin Christian Blanchette , Andrei Popescu date = 2013-06-27 topic = Logic/General logic/Mechanization of proofs abstract = This is a formalization of the soundness and completeness properties for various efficient encodings of sorts in unsorted first-order logic used by Isabelle's Sledgehammer tool.

Essentially, the encodings proceed as follows: a many-sorted problem is decorated with (as few as possible) tags or guards that make the problem monotonic; then sorts can be soundly erased.

The development employs a formalization of many-sorted first-order logic in clausal form (clauses, structures and the basic properties of the satisfaction relation), which could be of interest as the starting point for other formalizations of first-order logic metatheory. notify = uuomul@yahoo.com [Lambda_Free_RPOs] title = Formalization of Recursive Path Orders for Lambda-Free Higher-Order Terms author = Jasmin Christian Blanchette , Uwe Waldmann , Daniel Wand date = 2016-09-23 topic = Logic/Rewriting abstract = This Isabelle/HOL formalization defines recursive path orders (RPOs) for higher-order terms without lambda-abstraction and proves many useful properties about them. The main order fully coincides with the standard RPO on first-order terms also in the presence of currying, distinguishing it from previous work. An optimized variant is formalized as well. It appears promising as the basis of a higher-order superposition calculus. notify = jasmin.blanchette@gmail.com [Lambda_Free_KBOs] title = Formalization of Knuth–Bendix Orders for Lambda-Free Higher-Order Terms author = Heiko Becker , Jasmin Christian Blanchette , Uwe Waldmann , Daniel Wand date = 2016-11-12 topic = Logic/Rewriting abstract = This Isabelle/HOL formalization defines Knuth–Bendix orders for higher-order terms without lambda-abstraction and proves many useful properties about them. The main order fully coincides with the standard transfinite KBO with subterm coefficients on first-order terms. It appears promising as the basis of a higher-order superposition calculus. notify = jasmin.blanchette@gmail.com [Lambda_Free_EPO] title = Formalization of the Embedding Path Order for Lambda-Free Higher-Order Terms author = Alexander Bentkamp topic = Logic/Rewriting date = 2018-10-19 notify = a.bentkamp@vu.nl abstract = This Isabelle/HOL formalization defines the Embedding Path Order (EPO) for higher-order terms without lambda-abstraction and proves many useful properties about it. In contrast to the lambda-free recursive path orders, it does not fully coincide with RPO on first-order terms, but it is compatible with arbitrary higher-order contexts. [Nested_Multisets_Ordinals] title = Formalization of Nested Multisets, Hereditary Multisets, and Syntactic Ordinals author = Jasmin Christian Blanchette , Mathias Fleury , Dmitriy Traytel date = 2016-11-12 topic = Logic/Rewriting abstract = This Isabelle/HOL formalization introduces a nested multiset datatype and defines Dershowitz and Manna's nested multiset order. The order is proved well founded and linear. By removing one constructor, we transform the nested multisets into hereditary multisets. These are isomorphic to the syntactic ordinals—the ordinals can be recursively expressed in Cantor normal form. Addition, subtraction, multiplication, and linear orders are provided on this type. notify = jasmin.blanchette@gmail.com [Abstract-Rewriting] title = Abstract Rewriting topic = Logic/Rewriting date = 2010-06-14 author = Christian Sternagel , René Thiemann license = LGPL abstract = We present an Isabelle formalization of abstract rewriting (see, e.g., the book by Baader and Nipkow). First, we define standard relations like joinability, meetability, conversion, etc. Then, we formalize important properties of abstract rewrite systems, e.g., confluence and strong normalization. Our main concern is on strong normalization, since this formalization is the basis of CeTA (which is mainly about strong normalization of term rewrite systems). Hence lemmas involving strong normalization constitute by far the biggest part of this theory. One of those is Newman's lemma. extra-history = Change history: [2010-09-17]: Added theories defining several (ordered) semirings related to strong normalization and giving some standard instances.
[2013-10-16]: Generalized delta-orders from rationals to Archimedean fields. notify = christian.sternagel@uibk.ac.at, rene.thiemann@uibk.ac.at [First_Order_Terms] title = First-Order Terms author = Christian Sternagel , René Thiemann topic = Logic/Rewriting, Computer science/Algorithms license = LGPL date = 2018-02-06 notify = c.sternagel@gmail.com, rene.thiemann@uibk.ac.at abstract = We formalize basic results on first-order terms, including matching and a first-order unification algorithm, as well as well-foundedness of the subsumption order. This entry is part of the Isabelle Formalization of Rewriting IsaFoR, where first-order terms are omni-present: the unification algorithm is used to certify several confluence and termination techniques, like critical-pair computation and dependency graph approximations; and the subsumption order is a crucial ingredient for completion. [Free-Groups] title = Free Groups author = Joachim Breitner date = 2010-06-24 topic = Mathematics/Algebra abstract = Free Groups are, in a sense, the most generic kind of group. They are defined over a set of generators with no additional relations in between them. They play an important role in the definition of group presentations and in other fields. This theory provides the definition of Free Group as the set of fully canceled words in the generators. The universal property is proven, as well as some isomorphisms results about Free Groups. extra-history = Change history: [2011-12-11]: Added the Ping Pong Lemma. notify = [CofGroups] title = An Example of a Cofinitary Group in Isabelle/HOL author = Bart Kastermans date = 2009-08-04 topic = Mathematics/Algebra abstract = We formalize the usual proof that the group generated by the function k -> k + 1 on the integers gives rise to a cofinitary group. notify = nipkow@in.tum.de [Group-Ring-Module] title = Groups, Rings and Modules author = Hidetsune Kobayashi <>, L. Chen <>, H. Murao <> date = 2004-05-18 topic = Mathematics/Algebra abstract = The theory of groups, rings and modules is developed to a great depth. Group theory results include Zassenhaus's theorem and the Jordan-Hoelder theorem. The ring theory development includes ideals, quotient rings and the Chinese remainder theorem. The module development includes the Nakayama lemma, exact sequences and Tensor products. notify = lp15@cam.ac.uk [Robbins-Conjecture] title = A Complete Proof of the Robbins Conjecture author = Matthew Wampler-Doty <> date = 2010-05-22 topic = Mathematics/Algebra abstract = This document gives a formalization of the proof of the Robbins conjecture, following A. Mann, A Complete Proof of the Robbins Conjecture, 2003. notify = nipkow@in.tum.de [Valuation] title = Fundamental Properties of Valuation Theory and Hensel's Lemma author = Hidetsune Kobayashi <> date = 2007-08-08 topic = Mathematics/Algebra abstract = Convergence with respect to a valuation is discussed as convergence of a Cauchy sequence. Cauchy sequences of polynomials are defined. They are used to formalize Hensel's lemma. notify = lp15@cam.ac.uk [Rank_Nullity_Theorem] title = Rank-Nullity Theorem in Linear Algebra author = Jose Divasón , Jesús Aransay topic = Mathematics/Algebra date = 2013-01-16 abstract = In this contribution, we present some formalizations based on the HOL-Multivariate-Analysis session of Isabelle. Firstly, a generalization of several theorems of such library are presented. Secondly, some definitions and proofs involving Linear Algebra and the four fundamental subspaces of a matrix are shown. Finally, we present a proof of the result known in Linear Algebra as the ``Rank-Nullity Theorem'', which states that, given any linear map f from a finite dimensional vector space V to a vector space W, then the dimension of V is equal to the dimension of the kernel of f (which is a subspace of V) and the dimension of the range of f (which is a subspace of W). The proof presented here is based on the one given by Sheldon Axler in his book Linear Algebra Done Right. As a corollary of the previous theorem, and taking advantage of the relationship between linear maps and matrices, we prove that, for every matrix A (which has associated a linear map between finite dimensional vector spaces), the sum of its null space and its column space (which is equal to the range of the linear map) is equal to the number of columns of A. extra-history = Change history: [2014-07-14]: Added some generalizations that allow us to formalize the Rank-Nullity Theorem over finite dimensional vector spaces, instead of over the more particular euclidean spaces. Updated abstract. notify = jose.divasonm@unirioja.es, jesus-maria.aransay@unirioja.es [Affine_Arithmetic] title = Affine Arithmetic author = Fabian Immler date = 2014-02-07 topic = Mathematics/Analysis abstract = We give a formalization of affine forms as abstract representations of zonotopes. We provide affine operations as well as overapproximations of some non-affine operations like multiplication and division. Expressions involving those operations can automatically be turned into (executable) functions approximating the original expression in affine arithmetic. extra-history = Change history: [2015-01-31]: added algorithm for zonotope/hyperplane intersection
[2017-09-20]: linear approximations for all symbols from the floatarith data type notify = immler@in.tum.de [Laplace_Transform] title = Laplace Transform author = Fabian Immler topic = Mathematics/Analysis date = 2019-08-14 notify = fimmler@cs.cmu.edu abstract = This entry formalizes the Laplace transform and concrete Laplace transforms for arithmetic functions, frequency shift, integration and (higher) differentiation in the time domain. It proves Lerch's lemma and uniqueness of the Laplace transform for continuous functions. In order to formalize the foundational assumptions, this entry contains a formalization of piecewise continuous functions and functions of exponential order. [Cauchy] title = Cauchy's Mean Theorem and the Cauchy-Schwarz Inequality author = Benjamin Porter <> date = 2006-03-14 topic = Mathematics/Analysis abstract = This document presents the mechanised proofs of two popular theorems attributed to Augustin Louis Cauchy - Cauchy's Mean Theorem and the Cauchy-Schwarz Inequality. notify = kleing@cse.unsw.edu.au [Integration] title = Integration theory and random variables author = Stefan Richter date = 2004-11-19 topic = Mathematics/Analysis abstract = Lebesgue-style integration plays a major role in advanced probability. We formalize concepts of elementary measure theory, real-valued random variables as Borel-measurable functions, and a stepwise inductive definition of the integral itself. All proofs are carried out in human readable style using the Isar language. extra-note = Note: This article is of historical interest only. Lebesgue-style integration and probability theory are now available as part of the Isabelle/HOL distribution (directory Probability). notify = richter@informatik.rwth-aachen.de, nipkow@in.tum.de, hoelzl@in.tum.de [Ordinary_Differential_Equations] title = Ordinary Differential Equations author = Fabian Immler , Johannes Hölzl topic = Mathematics/Analysis date = 2012-04-26 abstract =

Session Ordinary-Differential-Equations formalizes ordinary differential equations (ODEs) and initial value problems. This work comprises proofs for local and global existence of unique solutions (Picard-Lindelöf theorem). Moreover, it contains a formalization of the (continuous or even differentiable) dependency of the flow on initial conditions as the flow of ODEs.

Not in the generated document are the following sessions:

  • HOL-ODE-Numerics: Rigorous numerical algorithms for computing enclosures of solutions based on Runge-Kutta methods and affine arithmetic. Reachability analysis with splitting and reduction at hyperplanes.
  • HOL-ODE-Examples: Applications of the numerical algorithms to concrete systems of ODEs.
  • Lorenz_C0, Lorenz_C1: Verified algorithms for checking C1-information according to Tucker's proof, computation of C0-information.

extra-history = Change history: [2014-02-13]: added an implementation of the Euler method based on affine arithmetic
[2016-04-14]: added flow and variational equation
[2016-08-03]: numerical algorithms for reachability analysis (using second-order Runge-Kutta methods, splitting, and reduction) implemented using Lammich's framework for automatic refinement
[2017-09-20]: added Poincare map and propagation of variational equation in reachability analysis, verified algorithms for C1-information and computations for C0-information of the Lorenz attractor. notify = immler@in.tum.de, hoelzl@in.tum.de [Polynomials] title = Executable Multivariate Polynomials author = Christian Sternagel , René Thiemann , Alexander Maletzky , Fabian Immler , Florian Haftmann , Andreas Lochbihler , Alexander Bentkamp date = 2010-08-10 topic = Mathematics/Analysis, Mathematics/Algebra, Computer science/Algorithms/Mathematical license = LGPL abstract = We define multivariate polynomials over arbitrary (ordered) semirings in combination with (executable) operations like addition, multiplication, and substitution. We also define (weak) monotonicity of polynomials and comparison of polynomials where we provide standard estimations like absolute positiveness or the more recent approach of Neurauter, Zankl, and Middeldorp. Moreover, it is proven that strongly normalizing (monotone) orders can be lifted to strongly normalizing (monotone) orders over polynomials. Our formalization was performed as part of the IsaFoR/CeTA-system which contains several termination techniques. The provided theories have been essential to formalize polynomial interpretations.

This formalization also contains an abstract representation as coefficient functions with finite support and a type of power-products. If this type is ordered by a linear (term) ordering, various additional notions, such as leading power-product, leading coefficient etc., are introduced as well. Furthermore, a lot of generic properties of, and functions on, multivariate polynomials are formalized, including the substitution and evaluation homomorphisms, embeddings of polynomial rings into larger rings (i.e. with one additional indeterminate), homogenization and dehomogenization of polynomials, and the canonical isomorphism between R[X,Y] and R[X][Y]. extra-history = Change history: [2010-09-17]: Moved theories on arbitrary (ordered) semirings to Abstract Rewriting.
[2016-10-28]: Added abstract representation of polynomials and authors Maletzky/Immler.
[2018-01-23]: Added authors Haftmann, Lochbihler after incorporating their formalization of multivariate polynomials based on Polynomial mappings. Moved material from Bentkamp's entry "Deep Learning".
[2019-04-18]: Added material about polynomials whose power-products are represented themselves by polynomial mappings. notify = rene.thiemann@uibk.ac.at, christian.sternagel@uibk.ac.at, alexander.maletzky@risc.jku.at, immler@in.tum.de [Sqrt_Babylonian] title = Computing N-th Roots using the Babylonian Method author = René Thiemann date = 2013-01-03 topic = Mathematics/Analysis license = LGPL abstract = We implement the Babylonian method to compute n-th roots of numbers. We provide precise algorithms for naturals, integers and rationals, and offer an approximation algorithm for square roots over linear ordered fields. Moreover, there are precise algorithms to compute the floor and the ceiling of n-th roots. extra-history = Change history: [2013-10-16]: Added algorithms to compute floor and ceiling of sqrt of integers. [2014-07-11]: Moved NthRoot_Impl from Real-Impl to this entry. notify = rene.thiemann@uibk.ac.at [Sturm_Sequences] title = Sturm's Theorem author = Manuel Eberl date = 2014-01-11 topic = Mathematics/Analysis abstract = Sturm's Theorem states that polynomial sequences with certain properties, so-called Sturm sequences, can be used to count the number of real roots of a real polynomial. This work contains a proof of Sturm's Theorem and code for constructing Sturm sequences efficiently. It also provides the “sturm” proof method, which can decide certain statements about the roots of real polynomials, such as “the polynomial P has exactly n roots in the interval I” or “P(x) > Q(x) for all x ∈ ℝ”. notify = eberlm@in.tum.de [Sturm_Tarski] title = The Sturm-Tarski Theorem author = Wenda Li date = 2014-09-19 topic = Mathematics/Analysis abstract = We have formalized the Sturm-Tarski theorem (also referred as the Tarski theorem), which generalizes Sturm's theorem. Sturm's theorem is usually used as a way to count distinct real roots, while the Sturm-Tarksi theorem forms the basis for Tarski's classic quantifier elimination for real closed field. notify = wl302@cam.ac.uk [Markov_Models] title = Markov Models author = Johannes Hölzl , Tobias Nipkow date = 2012-01-03 topic = Mathematics/Probability theory, Computer science/Automata and formal languages abstract = This is a formalization of Markov models in Isabelle/HOL. It builds on Isabelle's probability theory. The available models are currently Discrete-Time Markov Chains and a extensions of them with rewards.

As application of these models we formalize probabilistic model checking of pCTL formulas, analysis of IPv4 address allocation in ZeroConf and an analysis of the anonymity of the Crowds protocol. See here for the corresponding paper. notify = hoelzl@in.tum.de [Probabilistic_System_Zoo] title = A Zoo of Probabilistic Systems author = Johannes Hölzl , Andreas Lochbihler , Dmitriy Traytel date = 2015-05-27 topic = Computer science/Automata and formal languages abstract = Numerous models of probabilistic systems are studied in the literature. Coalgebra has been used to classify them into system types and compare their expressiveness. We formalize the resulting hierarchy of probabilistic system types by modeling the semantics of the different systems as codatatypes. This approach yields simple and concise proofs, as bisimilarity coincides with equality for codatatypes.

This work is described in detail in the ITP 2015 publication by the authors. notify = traytel@in.tum.de [Density_Compiler] title = A Verified Compiler for Probability Density Functions author = Manuel Eberl , Johannes Hölzl , Tobias Nipkow date = 2014-10-09 topic = Mathematics/Probability theory, Computer science/Programming languages/Compiling abstract = Bhat et al. [TACAS 2013] developed an inductive compiler that computes density functions for probability spaces described by programs in a probabilistic functional language. In this work, we implement such a compiler for a modified version of this language within the theorem prover Isabelle and give a formal proof of its soundness w.r.t. the semantics of the source and target language. Together with Isabelle's code generation for inductive predicates, this yields a fully verified, executable density compiler. The proof is done in two steps: First, an abstract compiler working with abstract functions modelled directly in the theorem prover's logic is defined and proved sound. Then, this compiler is refined to a concrete version that returns a target-language expression.

An article with the same title and authors is published in the proceedings of ESOP 2015. A detailed presentation of this work can be found in the first author's master's thesis. notify = hoelzl@in.tum.de [CAVA_Automata] title = The CAVA Automata Library author = Peter Lammich date = 2014-05-28 topic = Computer science/Automata and formal languages abstract = We report on the graph and automata library that is used in the fully verified LTL model checker CAVA. As most components of CAVA use some type of graphs or automata, a common automata library simplifies assembly of the components and reduces redundancy.

The CAVA Automata Library provides a hierarchy of graph and automata classes, together with some standard algorithms. Its object oriented design allows for sharing of algorithms, theorems, and implementations between its classes, and also simplifies extensions of the library. Moreover, it is integrated into the Automatic Refinement Framework, supporting automatic refinement of the abstract automata types to efficient data structures.

Note that the CAVA Automata Library is work in progress. Currently, it is very specifically tailored towards the requirements of the CAVA model checker. Nevertheless, the formalization techniques presented here allow an extension of the library to a wider scope. Moreover, they are not limited to graph libraries, but apply to class hierarchies in general.

The CAVA Automata Library is described in the paper: Peter Lammich, The CAVA Automata Library, Isabelle Workshop 2014. notify = lammich@in.tum.de [LTL] title = Linear Temporal Logic author = Salomon Sickert contributors = Benedikt Seidl date = 2016-03-01 topic = Logic/General logic/Temporal logic, Computer science/Automata and formal languages abstract = This theory provides a formalisation of linear temporal logic (LTL) and unifies previous formalisations within the AFP. This entry establishes syntax and semantics for this logic and decouples it from existing entries, yielding a common environment for theories reasoning about LTL. Furthermore a parser written in SML and an executable simplifier are provided. extra-history = Change history: [2019-03-12]: Support for additional operators, implementation of common equivalence relations, definition of syntactic fragments of LTL and the minimal disjunctive normal form.
notify = sickert@in.tum.de [LTL_to_GBA] title = Converting Linear-Time Temporal Logic to Generalized Büchi Automata author = Alexander Schimpf , Peter Lammich date = 2014-05-28 topic = Computer science/Automata and formal languages abstract = We formalize linear-time temporal logic (LTL) and the algorithm by Gerth et al. to convert LTL formulas to generalized Büchi automata. We also formalize some syntactic rewrite rules that can be applied to optimize the LTL formula before conversion. Moreover, we integrate the Stuttering Equivalence AFP-Entry by Stefan Merz, adapting the lemma that next-free LTL formula cannot distinguish between stuttering equivalent runs to our setting.

We use the Isabelle Refinement and Collection framework, as well as the Autoref tool, to obtain a refined version of our algorithm, from which efficiently executable code can be extracted. notify = lammich@in.tum.de [Gabow_SCC] title = Verified Efficient Implementation of Gabow's Strongly Connected Components Algorithm author = Peter Lammich date = 2014-05-28 topic = Computer science/Algorithms/Graph, Mathematics/Graph theory abstract = We present an Isabelle/HOL formalization of Gabow's algorithm for finding the strongly connected components of a directed graph. Using data refinement techniques, we extract efficient code that performs comparable to a reference implementation in Java. Our style of formalization allows for re-using large parts of the proofs when defining variants of the algorithm. We demonstrate this by verifying an algorithm for the emptiness check of generalized Büchi automata, re-using most of the existing proofs. notify = lammich@in.tum.de [Promela] title = Promela Formalization author = René Neumann date = 2014-05-28 topic = Computer science/System description languages abstract = We present an executable formalization of the language Promela, the description language for models of the model checker SPIN. This formalization is part of the work for a completely verified model checker (CAVA), but also serves as a useful (and executable!) description of the semantics of the language itself, something that is currently missing. The formalization uses three steps: It takes an abstract syntax tree generated from an SML parser, removes syntactic sugar and enriches it with type information. This further gets translated into a transition system, on which the semantic engine (read: successor function) operates. notify = [CAVA_LTL_Modelchecker] title = A Fully Verified Executable LTL Model Checker author = Javier Esparza , Peter Lammich , René Neumann , Tobias Nipkow , Alexander Schimpf , Jan-Georg Smaus date = 2014-05-28 topic = Computer science/Automata and formal languages abstract = We present an LTL model checker whose code has been completely verified using the Isabelle theorem prover. The checker consists of over 4000 lines of ML code. The code is produced using the Isabelle Refinement Framework, which allows us to split its correctness proof into (1) the proof of an abstract version of the checker, consisting of a few hundred lines of ``formalized pseudocode'', and (2) a verified refinement step in which mathematical sets and other abstract structures are replaced by implementations of efficient structures like red-black trees and functional arrays. This leads to a checker that, while still slower than unverified checkers, can already be used as a trusted reference implementation against which advanced implementations can be tested.

An early version of this model checker is described in the CAV 2013 paper with the same title. notify = lammich@in.tum.de [Fermat3_4] title = Fermat's Last Theorem for Exponents 3 and 4 and the Parametrisation of Pythagorean Triples author = Roelof Oosterhuis <> date = 2007-08-12 topic = Mathematics/Number theory abstract = This document presents the mechanised proofs of

  • Fermat's Last Theorem for exponents 3 and 4 and
  • the parametrisation of Pythagorean Triples.
notify = nipkow@in.tum.de, roelofoosterhuis@gmail.com [Perfect-Number-Thm] title = Perfect Number Theorem author = Mark Ijbema date = 2009-11-22 topic = Mathematics/Number theory abstract = These theories present the mechanised proof of the Perfect Number Theorem. notify = nipkow@in.tum.de [SumSquares] title = Sums of Two and Four Squares author = Roelof Oosterhuis <> date = 2007-08-12 topic = Mathematics/Number theory abstract = This document presents the mechanised proofs of the following results:
  • any prime number of the form 4m+1 can be written as the sum of two squares;
  • any natural number can be written as the sum of four squares
notify = nipkow@in.tum.de, roelofoosterhuis@gmail.com [Lehmer] title = Lehmer's Theorem author = Simon Wimmer , Lars Noschinski date = 2013-07-22 topic = Mathematics/Number theory abstract = In 1927, Lehmer presented criterions for primality, based on the converse of Fermat's litte theorem. This work formalizes the second criterion from Lehmer's paper, a necessary and sufficient condition for primality.

As a side product we formalize some properties of Euler's phi-function, the notion of the order of an element of a group, and the cyclicity of the multiplicative group of a finite field. notify = noschinl@gmail.com, simon.wimmer@tum.de [Pratt_Certificate] title = Pratt's Primality Certificates author = Simon Wimmer , Lars Noschinski date = 2013-07-22 topic = Mathematics/Number theory abstract = In 1975, Pratt introduced a proof system for certifying primes. He showed that a number p is prime iff a primality certificate for p exists. By showing a logarithmic upper bound on the length of the certificates in size of the prime number, he concluded that the decision problem for prime numbers is in NP. This work formalizes soundness and completeness of Pratt's proof system as well as an upper bound for the size of the certificate. notify = noschinl@gmail.com, simon.wimmer@tum.de [Monad_Memo_DP] title = Monadification, Memoization and Dynamic Programming author = Simon Wimmer , Shuwei Hu , Tobias Nipkow topic = Computer science/Programming languages/Transformations, Computer science/Algorithms, Computer science/Functional programming date = 2018-05-22 notify = wimmers@in.tum.de abstract = We present a lightweight framework for the automatic verified (functional or imperative) memoization of recursive functions. Our tool can turn a pure Isabelle/HOL function definition into a monadified version in a state monad or the Imperative HOL heap monad, and prove a correspondence theorem. We provide a variety of memory implementations for the two types of monads. A number of simple techniques allow us to achieve bottom-up computation and space-efficient memoization. The framework’s utility is demonstrated on a number of representative dynamic programming problems. A detailed description of our work can be found in the accompanying paper [2]. [Probabilistic_Timed_Automata] title = Probabilistic Timed Automata author = Simon Wimmer , Johannes Hölzl topic = Mathematics/Probability theory, Computer science/Automata and formal languages date = 2018-05-24 notify = wimmers@in.tum.de, hoelzl@in.tum.de abstract = We present a formalization of probabilistic timed automata (PTA) for which we try to follow the formula MDP + TA = PTA as far as possible: our work starts from our existing formalizations of Markov decision processes (MDP) and timed automata (TA) and combines them modularly. We prove the fundamental result for probabilistic timed automata: the region construction that is known from timed automata carries over to the probabilistic setting. In particular, this allows us to prove that minimum and maximum reachability probabilities can be computed via a reduction to MDP model checking, including the case where one wants to disregard unrealizable behavior. Further information can be found in our ITP paper [2]. [Hidden_Markov_Models] title = Hidden Markov Models author = Simon Wimmer topic = Mathematics/Probability theory, Computer science/Algorithms date = 2018-05-25 notify = wimmers@in.tum.de abstract = This entry contains a formalization of hidden Markov models [3] based on Johannes Hölzl's formalization of discrete time Markov chains [1]. The basic definitions are provided and the correctness of two main (dynamic programming) algorithms for hidden Markov models is proved: the forward algorithm for computing the likelihood of an observed sequence, and the Viterbi algorithm for decoding the most probable hidden state sequence. The Viterbi algorithm is made executable including memoization. Hidden markov models have various applications in natural language processing. For an introduction see Jurafsky and Martin [2]. [ArrowImpossibilityGS] title = Arrow and Gibbard-Satterthwaite author = Tobias Nipkow date = 2008-09-01 topic = Mathematics/Games and economics abstract = This article formalizes two proofs of Arrow's impossibility theorem due to Geanakoplos and derives the Gibbard-Satterthwaite theorem as a corollary. One formalization is based on utility functions, the other one on strict partial orders.

An article about these proofs is found here. notify = nipkow@in.tum.de [SenSocialChoice] title = Some classical results in Social Choice Theory author = Peter Gammie date = 2008-11-09 topic = Mathematics/Games and economics abstract = Drawing on Sen's landmark work "Collective Choice and Social Welfare" (1970), this development proves Arrow's General Possibility Theorem, Sen's Liberal Paradox and May's Theorem in a general setting. The goal was to make precise the classical statements and proofs of these results, and to provide a foundation for more recent results such as the Gibbard-Satterthwaite and Duggan-Schwartz theorems. notify = nipkow@in.tum.de [Vickrey_Clarke_Groves] title = VCG - Combinatorial Vickrey-Clarke-Groves Auctions author = Marco B. Caminati <>, Manfred Kerber , Christoph Lange, Colin Rowat date = 2015-04-30 topic = Mathematics/Games and economics abstract = A VCG auction (named after their inventors Vickrey, Clarke, and Groves) is a generalization of the single-good, second price Vickrey auction to the case of a combinatorial auction (multiple goods, from which any participant can bid on each possible combination). We formalize in this entry VCG auctions, including tie-breaking and prove that the functions for the allocation and the price determination are well-defined. Furthermore we show that the allocation function allocates goods only to participants, only goods in the auction are allocated, and no good is allocated twice. We also show that the price function is non-negative. These properties also hold for the automatically extracted Scala code. notify = mnfrd.krbr@gmail.com [Topology] title = Topology author = Stefan Friedrich <> date = 2004-04-26 topic = Mathematics/Topology abstract = This entry contains two theories. The first, Topology, develops the basic notions of general topology. The second, which can be viewed as a demonstration of the first, is called LList_Topology. It develops the topology of lazy lists. notify = lcp@cl.cam.ac.uk [Knot_Theory] title = Knot Theory author = T.V.H. Prathamesh date = 2016-01-20 topic = Mathematics/Topology abstract = This work contains a formalization of some topics in knot theory. The concepts that were formalized include definitions of tangles, links, framed links and link/tangle equivalence. The formalization is based on a formulation of links in terms of tangles. We further construct and prove the invariance of the Bracket polynomial. Bracket polynomial is an invariant of framed links closely linked to the Jones polynomial. This is perhaps the first attempt to formalize any aspect of knot theory in an interactive proof assistant. notify = prathamesh@imsc.res.in [Graph_Theory] title = Graph Theory author = Lars Noschinski date = 2013-04-28 topic = Mathematics/Graph theory abstract = This development provides a formalization of directed graphs, supporting (labelled) multi-edges and infinite graphs. A polymorphic edge type allows edges to be treated as pairs of vertices, if multi-edges are not required. Formalized properties are i.a. walks (and related concepts), connectedness and subgraphs and basic properties of isomorphisms.

This formalization is used to prove characterizations of Euler Trails, Shortest Paths and Kuratowski subgraphs. notify = noschinl@gmail.com [Planarity_Certificates] title = Planarity Certificates author = Lars Noschinski date = 2015-11-11 topic = Mathematics/Graph theory abstract = This development provides a formalization of planarity based on combinatorial maps and proves that Kuratowski's theorem implies combinatorial planarity. Moreover, it contains verified implementations of programs checking certificates for planarity (i.e., a combinatorial map) or non-planarity (i.e., a Kuratowski subgraph). notify = noschinl@gmail.com [Max-Card-Matching] title = Maximum Cardinality Matching author = Christine Rizkallah date = 2011-07-21 topic = Mathematics/Graph theory abstract =

A matching in a graph G is a subset M of the edges of G such that no two share an endpoint. A matching has maximum cardinality if its cardinality is at least as large as that of any other matching. An odd-set cover OSC of a graph G is a labeling of the nodes of G with integers such that every edge of G is either incident to a node labeled 1 or connects two nodes labeled with the same number i ≥ 2.

This article proves Edmonds theorem:
Let M be a matching in a graph G and let OSC be an odd-set cover of G. For any i ≥ 0, let n(i) be the number of nodes labeled i. If |M| = n(1) + ∑i ≥ 2(n(i) div 2), then M is a maximum cardinality matching.

notify = nipkow@in.tum.de [Girth_Chromatic] title = A Probabilistic Proof of the Girth-Chromatic Number Theorem author = Lars Noschinski date = 2012-02-06 topic = Mathematics/Graph theory abstract = This works presents a formalization of the Girth-Chromatic number theorem in graph theory, stating that graphs with arbitrarily large girth and chromatic number exist. The proof uses the theory of Random Graphs to prove the existence with probabilistic arguments. notify = noschinl@gmail.com [Random_Graph_Subgraph_Threshold] title = Properties of Random Graphs -- Subgraph Containment author = Lars Hupel date = 2014-02-13 topic = Mathematics/Graph theory, Mathematics/Probability theory abstract = Random graphs are graphs with a fixed number of vertices, where each edge is present with a fixed probability. We are interested in the probability that a random graph contains a certain pattern, for example a cycle or a clique. A very high edge probability gives rise to perhaps too many edges (which degrades performance for many algorithms), whereas a low edge probability might result in a disconnected graph. We prove a theorem about a threshold probability such that a higher edge probability will asymptotically almost surely produce a random graph with the desired subgraph. notify = hupel@in.tum.de [Flyspeck-Tame] title = Flyspeck I: Tame Graphs author = Gertrud Bauer <>, Tobias Nipkow date = 2006-05-22 topic = Mathematics/Graph theory abstract = These theories present the verified enumeration of tame plane graphs as defined by Thomas C. Hales in his proof of the Kepler Conjecture in his book Dense Sphere Packings. A Blueprint for Formal Proofs. [CUP 2012]. The values of the constants in the definition of tameness are identical to those in the Flyspeck project. The IJCAR 2006 paper by Nipkow, Bauer and Schultz refers to the original version of Hales' proof, the ITP 2011 paper by Nipkow refers to the Blueprint version of the proof. extra-history = Change history: [2010-11-02]: modified theories to reflect the modified definition of tameness in Hales' revised proof.
[2014-07-03]: modified constants in def of tameness and Archive according to the final state of the Flyspeck proof. notify = nipkow@in.tum.de [Well_Quasi_Orders] title = Well-Quasi-Orders author = Christian Sternagel date = 2012-04-13 topic = Mathematics/Combinatorics abstract = Based on Isabelle/HOL's type class for preorders, we introduce a type class for well-quasi-orders (wqo) which is characterized by the absence of "bad" sequences (our proofs are along the lines of the proof of Nash-Williams, from which we also borrow terminology). Our main results are instantiations for the product type, the list type, and a type of finite trees, which (almost) directly follow from our proofs of (1) Dickson's Lemma, (2) Higman's Lemma, and (3) Kruskal's Tree Theorem. More concretely:
  • If the sets A and B are wqo then their Cartesian product is wqo.
  • If the set A is wqo then the set of finite lists over A is wqo.
  • If the set A is wqo then the set of finite trees over A is wqo.
The research was funded by the Austrian Science Fund (FWF): J3202. extra-history = Change history: [2012-06-11]: Added Kruskal's Tree Theorem.
[2012-12-19]: New variant of Kruskal's tree theorem for terms (as opposed to variadic terms, i.e., trees), plus finite version of the tree theorem as corollary.
[2013-05-16]: Simplified construction of minimal bad sequences.
[2014-07-09]: Simplified proofs of Higman's lemma and Kruskal's tree theorem, based on homogeneous sequences.
[2016-01-03]: An alternative proof of Higman's lemma by open induction.
[2017-06-08]: Proved (classical) equivalence to inductive definition of almost-full relations according to the ITP 2012 paper "Stop When You Are Almost-Full" by Vytiniotis, Coquand, and Wahlstedt. notify = c.sternagel@gmail.com [Marriage] title = Hall's Marriage Theorem author = Dongchen Jiang , Tobias Nipkow date = 2010-12-17 topic = Mathematics/Combinatorics abstract = Two proofs of Hall's Marriage Theorem: one due to Halmos and Vaughan, one due to Rado. extra-history = Change history: [2011-09-09]: Added Rado's proof notify = nipkow@in.tum.de [Bondy] title = Bondy's Theorem author = Jeremy Avigad , Stefan Hetzl date = 2012-10-27 topic = Mathematics/Combinatorics abstract = A proof of Bondy's theorem following B. Bollabas, Combinatorics, 1986, Cambridge University Press. notify = avigad@cmu.edu, hetzl@logic.at [Ramsey-Infinite] title = Ramsey's theorem, infinitary version author = Tom Ridge <> date = 2004-09-20 topic = Mathematics/Combinatorics abstract = This formalization of Ramsey's theorem (infinitary version) is taken from Boolos and Jeffrey, Computability and Logic, 3rd edition, Chapter 26. It differs slightly from the text by assuming a slightly stronger hypothesis. In particular, the induction hypothesis is stronger, holding for any infinite subset of the naturals. This avoids the rather peculiar mapping argument between kj and aikj on p.263, which is unnecessary and slightly mars this really beautiful result. notify = lp15@cam.ac.uk [Derangements] title = Derangements Formula author = Lukas Bulwahn date = 2015-06-27 topic = Mathematics/Combinatorics abstract = The Derangements Formula describes the number of fixpoint-free permutations as a closed formula. This theorem is the 88th theorem in a list of the ``Top 100 Mathematical Theorems''. notify = lukas.bulwahn@gmail.com [Euler_Partition] title = Euler's Partition Theorem author = Lukas Bulwahn date = 2015-11-19 topic = Mathematics/Combinatorics abstract = Euler's Partition Theorem states that the number of partitions with only distinct parts is equal to the number of partitions with only odd parts. The combinatorial proof follows John Harrison's HOL Light formalization. This theorem is the 45th theorem of the Top 100 Theorems list. notify = lukas.bulwahn@gmail.com [Discrete_Summation] title = Discrete Summation author = Florian Haftmann contributors = Amine Chaieb <> date = 2014-04-13 topic = Mathematics/Combinatorics abstract = These theories introduce basic concepts and proofs about discrete summation: shifts, formal summation, falling factorials and stirling numbers. As proof of concept, a simple summation conversion is provided. notify = florian.haftmann@informatik.tu-muenchen.de [Open_Induction] title = Open Induction author = Mizuhito Ogawa <>, Christian Sternagel date = 2012-11-02 topic = Mathematics/Combinatorics abstract = A proof of the open induction schema based on J.-C. Raoult, Proving open properties by induction, Information Processing Letters 29, 1988, pp.19-23.

This research was supported by the Austrian Science Fund (FWF): J3202.

notify = c.sternagel@gmail.com [Category] title = Category Theory to Yoneda's Lemma author = Greg O'Keefe date = 2005-04-21 topic = Mathematics/Category theory license = LGPL abstract = This development proves Yoneda's lemma and aims to be readable by humans. It only defines what is needed for the lemma: categories, functors and natural transformations. Limits, adjunctions and other important concepts are not included. extra-history = Change history: [2010-04-23]: The definition of the constant equinumerous was slightly too weak in the original submission and has been fixed in revision 8c2b5b3c995f. notify = lcp@cl.cam.ac.uk [Category2] title = Category Theory author = Alexander Katovsky date = 2010-06-20 topic = Mathematics/Category theory abstract = This article presents a development of Category Theory in Isabelle/HOL. A Category is defined using records and locales. Functors and Natural Transformations are also defined. The main result that has been formalized is that the Yoneda functor is a full and faithful embedding. We also formalize the completeness of many sorted monadic equational logic. Extensive use is made of the HOLZF theory in both cases. For an informal description see here [pdf]. notify = alexander.katovsky@cantab.net [FunWithFunctions] title = Fun With Functions author = Tobias Nipkow date = 2008-08-26 topic = Mathematics/Misc abstract = This is a collection of cute puzzles of the form ``Show that if a function satisfies the following constraints, it must be ...'' Please add further examples to this collection! notify = nipkow@in.tum.de [FunWithTilings] title = Fun With Tilings author = Tobias Nipkow , Lawrence C. Paulson date = 2008-11-07 topic = Mathematics/Misc abstract = Tilings are defined inductively. It is shown that one form of mutilated chess board cannot be tiled with dominoes, while another one can be tiled with L-shaped tiles. Please add further fun examples of this kind! notify = nipkow@in.tum.de [Lazy-Lists-II] title = Lazy Lists II author = Stefan Friedrich <> date = 2004-04-26 topic = Computer science/Data structures abstract = This theory contains some useful extensions to the LList (lazy list) theory by Larry Paulson, including finite, infinite, and positive llists over an alphabet, as well as the new constants take and drop and the prefix order of llists. Finally, the notions of safety and liveness in the sense of Alpern and Schneider (1985) are defined. notify = lcp@cl.cam.ac.uk [Ribbon_Proofs] title = Ribbon Proofs author = John Wickerson <> date = 2013-01-19 topic = Computer science/Programming languages/Logics abstract = This document concerns the theory of ribbon proofs: a diagrammatic proof system, based on separation logic, for verifying program correctness. We include the syntax, proof rules, and soundness results for two alternative formalisations of ribbon proofs.

Compared to traditional proof outlines, ribbon proofs emphasise the structure of a proof, so are intelligible and pedagogical. Because they contain less redundancy than proof outlines, and allow each proof step to be checked locally, they may be more scalable. Where proof outlines are cumbersome to modify, ribbon proofs can be visually manoeuvred to yield proofs of variant programs. notify = [Koenigsberg_Friendship] title = The Königsberg Bridge Problem and the Friendship Theorem author = Wenda Li date = 2013-07-19 topic = Mathematics/Graph theory abstract = This development provides a formalization of undirected graphs and simple graphs, which are based on Benedikt Nordhoff and Peter Lammich's simple formalization of labelled directed graphs in the archive. Then, with our formalization of graphs, we show both necessary and sufficient conditions for Eulerian trails and circuits as well as the fact that the Königsberg Bridge Problem does not have a solution. In addition, we show the Friendship Theorem in simple graphs. notify = [Tree_Decomposition] title = Tree Decomposition author = Christoph Dittmann notify = date = 2016-05-31 topic = Mathematics/Graph theory abstract = We formalize tree decompositions and tree width in Isabelle/HOL, proving that trees have treewidth 1. We also show that every edge of a tree decomposition is a separation of the underlying graph. As an application of this theorem we prove that complete graphs of size n have treewidth n-1. [Menger] title = Menger's Theorem author = Christoph Dittmann topic = Mathematics/Graph theory date = 2017-02-26 notify = isabelle@christoph-d.de abstract = We present a formalization of Menger's Theorem for directed and undirected graphs in Isabelle/HOL. This well-known result shows that if two non-adjacent distinct vertices u, v in a directed graph have no separator smaller than n, then there exist n internally vertex-disjoint paths from u to v. The version for undirected graphs follows immediately because undirected graphs are a special case of directed graphs. [IEEE_Floating_Point] title = A Formal Model of IEEE Floating Point Arithmetic author = Lei Yu contributors = Fabian Hellauer , Fabian Immler date = 2013-07-27 topic = Computer science/Data structures abstract = This development provides a formal model of IEEE-754 floating-point arithmetic. This formalization, including formal specification of the standard and proofs of important properties of floating-point arithmetic, forms the foundation for verifying programs with floating-point computation. There is also a code generation setup for floats so that we can execute programs using this formalization in functional programming languages. notify = lp15@cam.ac.uk, immler@in.tum.de extra-history = Change history: [2017-09-25]: Added conversions from and to software floating point numbers (by Fabian Hellauer and Fabian Immler).
[2018-02-05]: 'Modernized' representation following the formalization in HOL4: former "float_format" and predicate "is_valid" is now encoded in a type "('e, 'f) float" where 'e and 'f encode the size of exponent and fraction. [Native_Word] title = Native Word author = Andreas Lochbihler contributors = Peter Lammich date = 2013-09-17 topic = Computer science/Data structures abstract = This entry makes machine words and machine arithmetic available for code generation from Isabelle/HOL. It provides a common abstraction that hides the differences between the different target languages. The code generator maps these operations to the APIs of the target languages. Apart from that, we extend the available bit operations on types int and integer, and map them to the operations in the target languages. extra-history = Change history: [2013-11-06]: added conversion function between native words and characters (revision fd23d9a7fe3a)
[2014-03-31]: added words of default size in the target language (by Peter Lammich) (revision 25caf5065833)
[2014-10-06]: proper test setup with compilation and execution of tests in all target languages (revision 5d7a1c9ae047)
[2017-09-02]: added 64-bit words (revision c89f86244e3c)
[2018-07-15]: added cast operators for default-size words (revision fc1f1fb8dd30)
notify = mail@andreas-lochbihler.de [XML] title = XML author = Christian Sternagel , René Thiemann date = 2014-10-03 topic = Computer science/Functional programming, Computer science/Data structures abstract = This entry provides an XML library for Isabelle/HOL. This includes parsing and pretty printing of XML trees as well as combinators for transforming XML trees into arbitrary user-defined data. The main contribution of this entry is an interface (fit for code generation) that allows for communication between verified programs formalized in Isabelle/HOL and the outside world via XML. This library was developed as part of the IsaFoR/CeTA project to which we refer for examples of its usage. notify = c.sternagel@gmail.com, rene.thiemann@uibk.ac.at [HereditarilyFinite] title = The Hereditarily Finite Sets author = Lawrence C. Paulson date = 2013-11-17 topic = Logic/Set theory abstract = The theory of hereditarily finite sets is formalised, following the development of Swierczkowski. An HF set is a finite collection of other HF sets; they enjoy an induction principle and satisfy all the axioms of ZF set theory apart from the axiom of infinity, which is negated. All constructions that are possible in ZF set theory (Cartesian products, disjoint sums, natural numbers, functions) without using infinite sets are possible here. The definition of addition for the HF sets follows Kirby. This development forms the foundation for the Isabelle proof of Gödel's incompleteness theorems, which has been formalised separately. extra-history = Change history: [2015-02-23]: Added the theory "Finitary" defining the class of types that can be embedded in hf, including int, char, option, list, etc. notify = lp15@cam.ac.uk [Incompleteness] title = Gödel's Incompleteness Theorems author = Lawrence C. Paulson date = 2013-11-17 topic = Logic/Proof theory abstract = Gödel's two incompleteness theorems are formalised, following a careful presentation by Swierczkowski, in the theory of hereditarily finite sets. This represents the first ever machine-assisted proof of the second incompleteness theorem. Compared with traditional formalisations using Peano arithmetic (see e.g. Boolos), coding is simpler, with no need to formalise the notion of multiplication (let alone that of a prime number) in the formalised calculus upon which the theorem is based. However, other technical problems had to be solved in order to complete the argument. notify = lp15@cam.ac.uk [Finite_Automata_HF] title = Finite Automata in Hereditarily Finite Set Theory author = Lawrence C. Paulson date = 2015-02-05 topic = Computer science/Automata and formal languages abstract = Finite Automata, both deterministic and non-deterministic, for regular languages. The Myhill-Nerode Theorem. Closure under intersection, concatenation, etc. Regular expressions define regular languages. Closure under reversal; the powerset construction mapping NFAs to DFAs. Left and right languages; minimal DFAs. Brzozowski's minimization algorithm. Uniqueness up to isomorphism of minimal DFAs. notify = lp15@cam.ac.uk [Decreasing-Diagrams] title = Decreasing Diagrams author = Harald Zankl license = LGPL date = 2013-11-01 topic = Logic/Rewriting abstract = This theory contains a formalization of decreasing diagrams showing that any locally decreasing abstract rewrite system is confluent. We consider the valley (van Oostrom, TCS 1994) and the conversion version (van Oostrom, RTA 2008) and closely follow the original proofs. As an application we prove Newman's lemma. notify = Harald.Zankl@uibk.ac.at [Decreasing-Diagrams-II] title = Decreasing Diagrams II author = Bertram Felgenhauer license = LGPL date = 2015-08-20 topic = Logic/Rewriting abstract = This theory formalizes the commutation version of decreasing diagrams for Church-Rosser modulo. The proof follows Felgenhauer and van Oostrom (RTA 2013). The theory also provides important specializations, in particular van Oostrom’s conversion version (TCS 2008) of decreasing diagrams. notify = bertram.felgenhauer@uibk.ac.at [GoedelGod] title = Gödel's God in Isabelle/HOL author = Christoph Benzmüller , Bruno Woltzenlogel Paleo date = 2013-11-12 topic = Logic/Philosophical aspects abstract = Dana Scott's version of Gödel's proof of God's existence is formalized in quantified modal logic KB (QML KB). QML KB is modeled as a fragment of classical higher-order logic (HOL); thus, the formalization is essentially a formalization in HOL. notify = lp15@cam.ac.uk, c.benzmueller@fu-berlin.de [Types_Tableaus_and_Goedels_God] title = Types, Tableaus and Gödel’s God in Isabelle/HOL author = David Fuenmayor , Christoph Benzmüller topic = Logic/Philosophical aspects date = 2017-05-01 notify = davfuenmayor@gmail.com, c.benzmueller@gmail.com abstract = A computer-formalisation of the essential parts of Fitting's textbook "Types, Tableaus and Gödel's God" in Isabelle/HOL is presented. In particular, Fitting's (and Anderson's) variant of the ontological argument is verified and confirmed. This variant avoids the modal collapse, which has been criticised as an undesirable side-effect of Kurt Gödel's (and Dana Scott's) versions of the ontological argument. Fitting's work is employing an intensional higher-order modal logic, which we shallowly embed here in classical higher-order logic. We then utilize the embedded logic for the formalisation of Fitting's argument. (See also the earlier AFP entry ``Gödel's God in Isabelle/HOL''.) [GewirthPGCProof] title = Formalisation and Evaluation of Alan Gewirth's Proof for the Principle of Generic Consistency in Isabelle/HOL author = David Fuenmayor , Christoph Benzmüller topic = Logic/Philosophical aspects date = 2018-10-30 notify = davfuenmayor@gmail.com, c.benzmueller@gmail.com abstract = An ambitious ethical theory ---Alan Gewirth's "Principle of Generic Consistency"--- is encoded and analysed in Isabelle/HOL. Gewirth's theory has stirred much attention in philosophy and ethics and has been proposed as a potential means to bound the impact of artificial general intelligence. extra-history = Change history: [2019-04-09]: added proof for a stronger variant of the PGC and examplary inferences (revision 88182cb0a2f6)
[Lowe_Ontological_Argument] title = Computer-assisted Reconstruction and Assessment of E. J. Lowe's Modal Ontological Argument author = David Fuenmayor , Christoph Benzmüller topic = Logic/Philosophical aspects date = 2017-09-21 notify = davfuenmayor@gmail.com, c.benzmueller@gmail.com abstract = Computers may help us to understand --not just verify-- philosophical arguments. By utilizing modern proof assistants in an iterative interpretive process, we can reconstruct and assess an argument by fully formal means. Through the mechanization of a variant of St. Anselm's ontological argument by E. J. Lowe, which is a paradigmatic example of a natural-language argument with strong ties to metaphysics and religion, we offer an ideal showcase for our computer-assisted interpretive method. [AnselmGod] title = Anselm's God in Isabelle/HOL author = Ben Blumson topic = Logic/Philosophical aspects date = 2017-09-06 notify = benblumson@gmail.com abstract = Paul Oppenheimer and Edward Zalta's formalisation of Anselm's ontological argument for the existence of God is automated by embedding a free logic for definite descriptions within Isabelle/HOL. [Tail_Recursive_Functions] title = A General Method for the Proof of Theorems on Tail-recursive Functions author = Pasquale Noce date = 2013-12-01 topic = Computer science/Functional programming abstract =

Tail-recursive function definitions are sometimes more straightforward than alternatives, but proving theorems on them may be roundabout because of the peculiar form of the resulting recursion induction rules.

This paper describes a proof method that provides a general solution to this problem by means of suitable invariants over inductive sets, and illustrates the application of such method by examining two case studies.

notify = pasquale.noce.lavoro@gmail.com [CryptoBasedCompositionalProperties] title = Compositional Properties of Crypto-Based Components author = Maria Spichkova date = 2014-01-11 topic = Computer science/Security abstract = This paper presents an Isabelle/HOL set of theories which allows the specification of crypto-based components and the verification of their composition properties wrt. cryptographic aspects. We introduce a formalisation of the security property of data secrecy, the corresponding definitions and proofs. Please note that here we import the Isabelle/HOL theory ListExtras.thy, presented in the AFP entry FocusStreamsCaseStudies-AFP. notify = maria.spichkova@rmit.edu.au [Featherweight_OCL] title = Featherweight OCL: A Proposal for a Machine-Checked Formal Semantics for OCL 2.5 author = Achim D. Brucker , Frédéric Tuong , Burkhart Wolff date = 2014-01-16 topic = Computer science/System description languages abstract = The Unified Modeling Language (UML) is one of the few modeling languages that is widely used in industry. While UML is mostly known as diagrammatic modeling language (e.g., visualizing class models), it is complemented by a textual language, called Object Constraint Language (OCL). The current version of OCL is based on a four-valued logic that turns UML into a formal language. Any type comprises the elements "invalid" and "null" which are propagated as strict and non-strict, respectively. Unfortunately, the former semi-formal semantics of this specification language, captured in the "Annex A" of the OCL standard, leads to different interpretations of corner cases. We formalize the core of OCL: denotational definitions, a logical calculus and operational rules that allow for the execution of OCL expressions by a mixture of term rewriting and code compilation. Our formalization reveals several inconsistencies and contradictions in the current version of the OCL standard. Overall, this document is intended to provide the basis for a machine-checked text "Annex A" of the OCL standard targeting at tool implementors. extra-history = Change history: [2015-10-13]: afp-devel@ea3b38fc54d6 and hol-testgen@12148
   Update of Featherweight OCL including a change in the abstract.
[2014-01-16]: afp-devel@9091ce05cb20 and hol-testgen@10241
   New Entry: Featherweight OCL notify = brucker@spamfence.net, tuong@users.gforge.inria.fr, wolff@lri.fr [Relation_Algebra] title = Relation Algebra author = Alasdair Armstrong <>, Simon Foster , Georg Struth , Tjark Weber date = 2014-01-25 topic = Mathematics/Algebra abstract = Tarski's algebra of binary relations is formalised along the lines of the standard textbooks of Maddux and Schmidt and Ströhlein. This includes relation-algebraic concepts such as subidentities, vectors and a domain operation as well as various notions associated to functions. Relation algebras are also expanded by a reflexive transitive closure operation, and they are linked with Kleene algebras and models of binary relations and Boolean matrices. notify = g.struth@sheffield.ac.uk, tjark.weber@it.uu.se [PSemigroupsConvolution] title = Partial Semigroups and Convolution Algebras author = Brijesh Dongol , Victor B. F. Gomes , Ian J. Hayes , Georg Struth topic = Mathematics/Algebra date = 2017-06-13 notify = g.struth@sheffield.ac.uk, victor.gomes@cl.cam.ac.uk abstract = Partial Semigroups are relevant to the foundations of quantum mechanics and combinatorics as well as to interval and separation logics. Convolution algebras can be understood either as algebras of generalised binary modalities over ternary Kripke frames, in particular over partial semigroups, or as algebras of quantale-valued functions which are equipped with a convolution-style operation of multiplication that is parametrised by a ternary relation. Convolution algebras provide algebraic semantics for various substructural logics, including categorial, relevance and linear logics, for separation logic and for interval logics; they cover quantitative and qualitative applications. These mathematical components for partial semigroups and convolution algebras provide uniform foundations from which models of computation based on relations, program traces or pomsets, and verification components for separation or interval temporal logics can be built with little effort. [Secondary_Sylow] title = Secondary Sylow Theorems author = Jakob von Raumer date = 2014-01-28 topic = Mathematics/Algebra abstract = These theories extend the existing proof of the first Sylow theorem (written by Florian Kammueller and L. C. Paulson) by what are often called the second, third and fourth Sylow theorems. These theorems state propositions about the number of Sylow p-subgroups of a group and the fact that they are conjugate to each other. The proofs make use of an implementation of group actions and their properties. notify = psxjv4@nottingham.ac.uk [Jordan_Hoelder] title = The Jordan-Hölder Theorem author = Jakob von Raumer date = 2014-09-09 topic = Mathematics/Algebra abstract = This submission contains theories that lead to a formalization of the proof of the Jordan-Hölder theorem about composition series of finite groups. The theories formalize the notions of isomorphism classes of groups, simple groups, normal series, composition series, maximal normal subgroups. Furthermore, they provide proofs of the second isomorphism theorem for groups, the characterization theorem for maximal normal subgroups as well as many useful lemmas about normal subgroups and factor groups. The proof is inspired by course notes of Stuart Rankin. notify = psxjv4@nottingham.ac.uk [Cayley_Hamilton] title = The Cayley-Hamilton Theorem author = Stephan Adelsberger , Stefan Hetzl , Florian Pollak date = 2014-09-15 topic = Mathematics/Algebra abstract = This document contains a proof of the Cayley-Hamilton theorem based on the development of matrices in HOL/Multivariate Analysis. notify = stvienna@gmail.com [Probabilistic_Noninterference] title = Probabilistic Noninterference author = Andrei Popescu , Johannes Hölzl date = 2014-03-11 topic = Computer science/Security abstract = We formalize a probabilistic noninterference for a multi-threaded language with uniform scheduling, where probabilistic behaviour comes from both the scheduler and the individual threads. We define notions probabilistic noninterference in two variants: resumption-based and trace-based. For the resumption-based notions, we prove compositionality w.r.t. the language constructs and establish sound type-system-like syntactic criteria. This is a formalization of the mathematical development presented at CPP 2013 and CALCO 2013. It is the probabilistic variant of the Possibilistic Noninterference AFP entry. notify = hoelzl@in.tum.de [HyperCTL] title = A shallow embedding of HyperCTL* author = Markus N. Rabe , Peter Lammich , Andrei Popescu date = 2014-04-16 topic = Computer science/Security, Logic/General logic/Temporal logic abstract = We formalize HyperCTL*, a temporal logic for expressing security properties. We first define a shallow embedding of HyperCTL*, within which we prove inductive and coinductive rules for the operators. Then we show that a HyperCTL* formula captures Goguen-Meseguer noninterference, a landmark information flow property. We also define a deep embedding and connect it to the shallow embedding by a denotational semantics, for which we prove sanity w.r.t. dependence on the free variables. Finally, we show that under some finiteness assumptions about the model, noninterference is given by a (finitary) syntactic formula. notify = uuomul@yahoo.com [Bounded_Deducibility_Security] title = Bounded-Deducibility Security author = Andrei Popescu , Peter Lammich date = 2014-04-22 topic = Computer science/Security abstract = This is a formalization of bounded-deducibility security (BD security), a flexible notion of information-flow security applicable to arbitrary input-output automata. It generalizes Sutherland's classic notion of nondeducibility by factoring in declassification bounds and trigger, whereas nondeducibility states that, in a system, information cannot flow between specified sources and sinks, BD security indicates upper bounds for the flow and triggers under which these upper bounds are no longer guaranteed. notify = uuomul@yahoo.com, lammich@in.tum.de [Network_Security_Policy_Verification] title = Network Security Policy Verification author = Cornelius Diekmann date = 2014-07-04 topic = Computer science/Security abstract = We present a unified theory for verifying network security policies. A security policy is represented as directed graph. To check high-level security goals, security invariants over the policy are expressed. We cover monotonic security invariants, i.e. prohibiting more does not harm security. We provide the following contributions for the security invariant theory.
  • Secure auto-completion of scenario-specific knowledge, which eases usability.
  • Security violations can be repaired by tightening the policy iff the security invariants hold for the deny-all policy.
  • An algorithm to compute a security policy.
  • A formalization of stateful connection semantics in network security mechanisms.
  • An algorithm to compute a secure stateful implementation of a policy.
  • An executable implementation of all the theory.
  • Examples, ranging from an aircraft cabin data network to the analysis of a large real-world firewall.
  • More examples: A fully automated translation of high-level security goals to both firewall and SDN configurations (see Examples/Distributed_WebApp.thy).
For a detailed description, see extra-history = Change history: [2015-04-14]: Added Distributed WebApp example and improved graphviz visualization (revision 4dde08ca2ab8)
notify = diekmann@net.in.tum.de [Abstract_Completeness] title = Abstract Completeness author = Jasmin Christian Blanchette , Andrei Popescu , Dmitriy Traytel date = 2014-04-16 topic = Logic/Proof theory abstract = A formalization of an abstract property of possibly infinite derivation trees (modeled by a codatatype), representing the core of a proof (in Beth/Hintikka style) of the first-order logic completeness theorem, independent of the concrete syntax or inference rules. This work is described in detail in the IJCAR 2014 publication by the authors. The abstract proof can be instantiated for a wide range of Gentzen and tableau systems as well as various flavors of FOL---e.g., with or without predicates, equality, or sorts. Here, we give only a toy example instantiation with classical propositional logic. A more serious instance---many-sorted FOL with equality---is described elsewhere [Blanchette and Popescu, FroCoS 2013]. notify = traytel@in.tum.de [Pop_Refinement] title = Pop-Refinement author = Alessandro Coglio date = 2014-07-03 topic = Computer science/Programming languages/Misc abstract = Pop-refinement is an approach to stepwise refinement, carried out inside an interactive theorem prover by constructing a monotonically decreasing sequence of predicates over deeply embedded target programs. The sequence starts with a predicate that characterizes the possible implementations, and ends with a predicate that characterizes a unique program in explicit syntactic form. Pop-refinement enables more requirements (e.g. program-level and non-functional) to be captured in the initial specification and preserved through refinement. Security requirements expressed as hyperproperties (i.e. predicates over sets of traces) are always preserved by pop-refinement, unlike the popular notion of refinement as trace set inclusion. Two simple examples in Isabelle/HOL are presented, featuring program-level requirements, non-functional requirements, and hyperproperties. notify = coglio@kestrel.edu [VectorSpace] title = Vector Spaces author = Holden Lee date = 2014-08-29 topic = Mathematics/Algebra abstract = This formalisation of basic linear algebra is based completely on locales, building off HOL-Algebra. It includes basic definitions: linear combinations, span, linear independence; linear transformations; interpretation of function spaces as vector spaces; the direct sum of vector spaces, sum of subspaces; the replacement theorem; existence of bases in finite-dimensional; vector spaces, definition of dimension; the rank-nullity theorem. Some concepts are actually defined and proved for modules as they also apply there. Infinite-dimensional vector spaces are supported, but dimension is only supported for finite-dimensional vector spaces. The proofs are standard; the proofs of the replacement theorem and rank-nullity theorem roughly follow the presentation in Linear Algebra by Friedberg, Insel, and Spence. The rank-nullity theorem generalises the existing development in the Archive of Formal Proof (originally using type classes, now using a mix of type classes and locales). notify = holdenl@princeton.edu [Special_Function_Bounds] title = Real-Valued Special Functions: Upper and Lower Bounds author = Lawrence C. Paulson date = 2014-08-29 topic = Mathematics/Analysis abstract = This development proves upper and lower bounds for several familiar real-valued functions. For sin, cos, exp and sqrt, it defines and verifies infinite families of upper and lower bounds, mostly based on Taylor series expansions. For arctan, ln and exp, it verifies a finite collection of upper and lower bounds, originally obtained from the functions' continued fraction expansions using the computer algebra system Maple. A common theme in these proofs is to take the difference between a function and its approximation, which should be zero at one point, and then consider the sign of the derivative. The immediate purpose of this development is to verify axioms used by MetiTarski, an automatic theorem prover for real-valued special functions. Crucial to MetiTarski's operation is the provision of upper and lower bounds for each function of interest. notify = lp15@cam.ac.uk [Landau_Symbols] title = Landau Symbols author = Manuel Eberl date = 2015-07-14 topic = Mathematics/Analysis abstract = This entry provides Landau symbols to describe and reason about the asymptotic growth of functions for sufficiently large inputs. A number of simplification procedures are provided for additional convenience: cancelling of dominated terms in sums under a Landau symbol, cancelling of common factors in products, and a decision procedure for Landau expressions containing products of powers of functions like x, ln(x), ln(ln(x)) etc. notify = eberlm@in.tum.de [Error_Function] title = The Error Function author = Manuel Eberl topic = Mathematics/Analysis date = 2018-02-06 notify = eberlm@in.tum.de abstract =

This entry provides the definitions and basic properties of the complex and real error function erf and the complementary error function erfc. Additionally, it gives their full asymptotic expansions.

[Akra_Bazzi] title = The Akra-Bazzi theorem and the Master theorem author = Manuel Eberl date = 2015-07-14 topic = Mathematics/Analysis abstract = This article contains a formalisation of the Akra-Bazzi method based on a proof by Leighton. It is a generalisation of the well-known Master Theorem for analysing the complexity of Divide & Conquer algorithms. We also include a generalised version of the Master theorem based on the Akra-Bazzi theorem, which is easier to apply than the Akra-Bazzi theorem itself.

Some proof methods that facilitate applying the Master theorem are also included. For a more detailed explanation of the formalisation and the proof methods, see the accompanying paper (publication forthcoming). notify = eberlm@in.tum.de [Dirichlet_Series] title = Dirichlet Series author = Manuel Eberl topic = Mathematics/Number theory date = 2017-10-12 notify = eberlm@in.tum.de abstract = This entry is a formalisation of much of Chapters 2, 3, and 11 of Apostol's “Introduction to Analytic Number Theory”. This includes:

  • Definitions and basic properties for several number-theoretic functions (Euler's φ, Möbius μ, Liouville's λ, the divisor function σ, von Mangoldt's Λ)
  • Executable code for most of these functions, the most efficient implementations using the factoring algorithm by Thiemann et al.
  • Dirichlet products and formal Dirichlet series
  • Analytic results connecting convergent formal Dirichlet series to complex functions
  • Euler product expansions
  • Asymptotic estimates of number-theoretic functions including the density of squarefree integers and the average number of divisors of a natural number
These results are useful as a basis for developing more number-theoretic results, such as the Prime Number Theorem. [Gauss_Sums] title = Gauss Sums and the Pólya–Vinogradov Inequality author = Rodrigo Raya , Manuel Eberl topic = Mathematics/Number theory date = 2019-12-10 notify = manuel.eberl@tum.de abstract =

This article provides a full formalisation of Chapter 8 of Apostol's Introduction to Analytic Number Theory. Subjects that are covered are:

  • periodic arithmetic functions and their finite Fourier series
  • (generalised) Ramanujan sums
  • Gauss sums and separable characters
  • induced moduli and primitive characters
  • the Pólya—Vinogradov inequality
[Zeta_Function] title = The Hurwitz and Riemann ζ Functions author = Manuel Eberl topic = Mathematics/Number theory, Mathematics/Analysis date = 2017-10-12 notify = eberlm@in.tum.de abstract =

This entry builds upon the results about formal and analytic Dirichlet series to define the Hurwitz ζ function ζ(a,s) and, based on that, the Riemann ζ function ζ(s). This is done by first defining them for ℜ(z) > 1 and then successively extending the domain to the left using the Euler–MacLaurin formula.

Apart from the most basic facts such as analyticity, the following results are provided:

  • the Stieltjes constants and the Laurent expansion of ζ(s) at s = 1
  • the non-vanishing of ζ(s) for ℜ(z) ≥ 1
  • the relationship between ζ(a,s) and Γ
  • the special values at negative integers and positive even integers
  • Hurwitz's formula and the reflection formula for ζ(s)
  • the Hadjicostas–Chapman formula

The entry also contains Euler's analytic proof of the infinitude of primes, based on the fact that ζ(s) has a pole at s = 1.

[Linear_Recurrences] title = Linear Recurrences author = Manuel Eberl topic = Mathematics/Analysis date = 2017-10-12 notify = eberlm@in.tum.de abstract =

Linear recurrences with constant coefficients are an interesting class of recurrence equations that can be solved explicitly. The most famous example are certainly the Fibonacci numbers with the equation f(n) = f(n-1) + f(n - 2) and the quite non-obvious closed form (φn - (-φ)-n) / √5 where φ is the golden ratio.

In this work, I build on existing tools in Isabelle – such as formal power series and polynomial factorisation algorithms – to develop a theory of these recurrences and derive a fully executable solver for them that can be exported to programming languages like Haskell.

[Lambert_W] title = The Lambert W Function on the Reals author = Manuel Eberl topic = Mathematics/Analysis date = 2020-04-24 notify = eberlm@in.tum.de abstract =

The Lambert W function is a multi-valued function defined as the inverse function of xx ex. Besides numerous applications in combinatorics, physics, and engineering, it also frequently occurs when solving equations containing both ex and x, or both x and log x.

This article provides a definition of the two real-valued branches W0(x) and W-1(x) and proves various properties such as basic identities and inequalities, monotonicity, differentiability, asymptotic expansions, and the MacLaurin series of W0(x) at x = 0.

[Cartan_FP] title = The Cartan Fixed Point Theorems author = Lawrence C. Paulson date = 2016-03-08 topic = Mathematics/Analysis abstract = The Cartan fixed point theorems concern the group of holomorphic automorphisms on a connected open set of Cn. Ciolli et al. have formalised the one-dimensional case of these theorems in HOL Light. This entry contains their proofs, ported to Isabelle/HOL. Thus it addresses the authors' remark that "it would be important to write a formal proof in a language that can be read by both humans and machines". notify = lp15@cam.ac.uk [Gauss_Jordan] title = Gauss-Jordan Algorithm and Its Applications author = Jose Divasón , Jesús Aransay topic = Computer science/Algorithms/Mathematical date = 2014-09-03 abstract = The Gauss-Jordan algorithm states that any matrix over a field can be transformed by means of elementary row operations to a matrix in reduced row echelon form. The formalization is based on the Rank Nullity Theorem entry of the AFP and on the HOL-Multivariate-Analysis session of Isabelle, where matrices are represented as functions over finite types. We have set up the code generator to make this representation executable. In order to improve the performance, a refinement to immutable arrays has been carried out. We have formalized some of the applications of the Gauss-Jordan algorithm. Thanks to this development, the following facts can be computed over matrices whose elements belong to a field: Ranks, Determinants, Inverses, Bases and dimensions and Solutions of systems of linear equations. Code can be exported to SML and Haskell. notify = jose.divasonm@unirioja.es, jesus-maria.aransay@unirioja.es [Echelon_Form] title = Echelon Form author = Jose Divasón , Jesús Aransay topic = Computer science/Algorithms/Mathematical, Mathematics/Algebra date = 2015-02-12 abstract = We formalize an algorithm to compute the Echelon Form of a matrix. We have proved its existence over Bézout domains and made it executable over Euclidean domains, such as the integer ring and the univariate polynomials over a field. This allows us to compute determinants, inverses and characteristic polynomials of matrices. The work is based on the HOL-Multivariate Analysis library, and on both the Gauss-Jordan and Cayley-Hamilton AFP entries. As a by-product, some algebraic structures have been implemented (principal ideal domains, Bézout domains...). The algorithm has been refined to immutable arrays and code can be generated to functional languages as well. notify = jose.divasonm@unirioja.es, jesus-maria.aransay@unirioja.es [QR_Decomposition] title = QR Decomposition author = Jose Divasón , Jesús Aransay topic = Computer science/Algorithms/Mathematical, Mathematics/Algebra date = 2015-02-12 abstract = QR decomposition is an algorithm to decompose a real matrix A into the product of two other matrices Q and R, where Q is orthogonal and R is invertible and upper triangular. The algorithm is useful for the least squares problem; i.e., the computation of the best approximation of an unsolvable system of linear equations. As a side-product, the Gram-Schmidt process has also been formalized. A refinement using immutable arrays is presented as well. The development relies, among others, on the AFP entry "Implementing field extensions of the form Q[sqrt(b)]" by René Thiemann, which allows execution of the algorithm using symbolic computations. Verified code can be generated and executed using floats as well. extra-history = Change history: [2015-06-18]: The second part of the Fundamental Theorem of Linear Algebra has been generalized to more general inner product spaces. notify = jose.divasonm@unirioja.es, jesus-maria.aransay@unirioja.es [Hermite] title = Hermite Normal Form author = Jose Divasón , Jesús Aransay topic = Computer science/Algorithms/Mathematical, Mathematics/Algebra date = 2015-07-07 abstract = Hermite Normal Form is a canonical matrix analogue of Reduced Echelon Form, but involving matrices over more general rings. In this work we formalise an algorithm to compute the Hermite Normal Form of a matrix by means of elementary row operations, taking advantage of the Echelon Form AFP entry. We have proven the correctness of such an algorithm and refined it to immutable arrays. Furthermore, we have also formalised the uniqueness of the Hermite Normal Form of a matrix. Code can be exported and some examples of execution involving integer matrices and polynomial matrices are presented as well. notify = jose.divasonm@unirioja.es, jesus-maria.aransay@unirioja.es [Imperative_Insertion_Sort] title = Imperative Insertion Sort author = Christian Sternagel date = 2014-09-25 topic = Computer science/Algorithms abstract = The insertion sort algorithm of Cormen et al. (Introduction to Algorithms) is expressed in Imperative HOL and proved to be correct and terminating. For this purpose we also provide a theory about imperative loop constructs with accompanying induction/invariant rules for proving partial and total correctness. Furthermore, the formalized algorithm is fit for code generation. notify = lp15@cam.ac.uk [Stream_Fusion_Code] title = Stream Fusion in HOL with Code Generation author = Andreas Lochbihler , Alexandra Maximova date = 2014-10-10 topic = Computer science/Functional programming abstract = Stream Fusion is a system for removing intermediate list data structures from functional programs, in particular Haskell. This entry adapts stream fusion to Isabelle/HOL and its code generator. We define stream types for finite and possibly infinite lists and stream versions for most of the fusible list functions in the theories List and Coinductive_List, and prove them correct with respect to the conversion functions between lists and streams. The Stream Fusion transformation itself is implemented as a simproc in the preprocessor of the code generator. [Brian Huffman's AFP entry formalises stream fusion in HOLCF for the domain of lazy lists to prove the GHC compiler rewrite rules correct. In contrast, this work enables Isabelle's code generator to perform stream fusion itself. To that end, it covers both finite and coinductive lists from the HOL library and the Coinductive entry. The fusible list functions require specification and proof principles different from Huffman's.] notify = mail@andreas-lochbihler.de [Case_Labeling] title = Generating Cases from Labeled Subgoals author = Lars Noschinski date = 2015-07-21 topic = Tools, Computer science/Programming languages/Misc abstract = Isabelle/Isar provides named cases to structure proofs. This article contains an implementation of a proof method casify, which can be used to easily extend proof tools with support for named cases. Such a proof tool must produce labeled subgoals, which are then interpreted by casify.

As examples, this work contains verification condition generators producing named cases for three languages: The Hoare language from HOL/Library, a monadic language for computations with failure (inspired by the AutoCorres tool), and a language of conditional expressions. These VCGs are demonstrated by a number of example programs. notify = noschinl@gmail.com [DPT-SAT-Solver] title = A Fast SAT Solver for Isabelle in Standard ML topic = Tools author = Armin Heller <> date = 2009-12-09 abstract = This contribution contains a fast SAT solver for Isabelle written in Standard ML. By loading the theory DPT_SAT_Solver, the SAT solver installs itself (under the name ``dptsat'') and certain Isabelle tools like Refute will start using it automatically. This is a port of the DPT (Decision Procedure Toolkit) SAT Solver written in OCaml. notify = jasmin.blanchette@gmail.com [Rep_Fin_Groups] title = Representations of Finite Groups topic = Mathematics/Algebra author = Jeremy Sylvestre date = 2015-08-12 abstract = We provide a formal framework for the theory of representations of finite groups, as modules over the group ring. Along the way, we develop the general theory of groups (relying on the group_add class for the basics), modules, and vector spaces, to the extent required for theory of group representations. We then provide formal proofs of several important introductory theorems in the subject, including Maschke's theorem, Schur's lemma, and Frobenius reciprocity. We also prove that every irreducible representation is isomorphic to a submodule of the group ring, leading to the fact that for a finite group there are only finitely many isomorphism classes of irreducible representations. In all of this, no restriction is made on the characteristic of the ring or field of scalars until the definition of a group representation, and then the only restriction made is that the characteristic must not divide the order of the group. notify = jsylvest@ualberta.ca [Noninterference_Inductive_Unwinding] title = The Inductive Unwinding Theorem for CSP Noninterference Security topic = Computer science/Security author = Pasquale Noce date = 2015-08-18 abstract =

The necessary and sufficient condition for CSP noninterference security stated by the Ipurge Unwinding Theorem is expressed in terms of a pair of event lists varying over the set of process traces. This does not render it suitable for the subsequent application of rule induction in the case of a process defined inductively, since rule induction may rather be applied to a single variable ranging over an inductively defined set.

Starting from the Ipurge Unwinding Theorem, this paper derives a necessary and sufficient condition for CSP noninterference security that involves a single event list varying over the set of process traces, and is thus suitable for rule induction; hence its name, Inductive Unwinding Theorem. Similarly to the Ipurge Unwinding Theorem, the new theorem only requires to consider individual accepted and refused events for each process trace, and applies to the general case of a possibly intransitive noninterference policy. Specific variants of this theorem are additionally proven for deterministic processes and trace set processes.

notify = pasquale.noce.lavoro@gmail.com [Password_Authentication_Protocol] title = Verification of a Diffie-Hellman Password-based Authentication Protocol by Extending the Inductive Method author = Pasquale Noce topic = Computer science/Security date = 2017-01-03 notify = pasquale.noce.lavoro@gmail.com abstract = This paper constructs a formal model of a Diffie-Hellman password-based authentication protocol between a user and a smart card, and proves its security. The protocol provides for the dispatch of the user's password to the smart card on a secure messaging channel established by means of Password Authenticated Connection Establishment (PACE), where the mapping method being used is Chip Authentication Mapping. By applying and suitably extending Paulson's Inductive Method, this paper proves that the protocol establishes trustworthy secure messaging channels, preserves the secrecy of users' passwords, and provides an effective mutual authentication service. What is more, these security properties turn out to hold independently of the secrecy of the PACE authentication key. [Jordan_Normal_Form] title = Matrices, Jordan Normal Forms, and Spectral Radius Theory topic = Mathematics/Algebra author = René Thiemann , Akihisa Yamada contributors = Alexander Bentkamp date = 2015-08-21 abstract =

Matrix interpretations are useful as measure functions in termination proving. In order to use these interpretations also for complexity analysis, the growth rate of matrix powers has to examined. Here, we formalized a central result of spectral radius theory, namely that the growth rate is polynomially bounded if and only if the spectral radius of a matrix is at most one.

To formally prove this result we first studied the growth rates of matrices in Jordan normal form, and prove the result that every complex matrix has a Jordan normal form using a constructive prove via Schur decomposition.

The whole development is based on a new abstract type for matrices, which is also executable by a suitable setup of the code generator. It completely subsumes our former AFP-entry on executable matrices, and its main advantage is its close connection to the HMA-representation which allowed us to easily adapt existing proofs on determinants.

All the results have been applied to improve CeTA, our certifier to validate termination and complexity proof certificates.

extra-history = Change history: [2016-01-07]: Added Schur-decomposition, Gram-Schmidt orthogonalization, uniqueness of Jordan normal forms
[2018-04-17]: Integrated lemmas from deep-learning AFP-entry of Alexander Bentkamp notify = rene.thiemann@uibk.ac.at, ayamada@trs.cm.is.nagoya-u.ac.jp [LTL_to_DRA] title = Converting Linear Temporal Logic to Deterministic (Generalized) Rabin Automata topic = Computer science/Automata and formal languages author = Salomon Sickert date = 2015-09-04 abstract = Recently, Javier Esparza and Jan Kretinsky proposed a new method directly translating linear temporal logic (LTL) formulas to deterministic (generalized) Rabin automata. Compared to the existing approaches of constructing a non-deterministic Buechi-automaton in the first step and then applying a determinization procedure (e.g. some variant of Safra's construction) in a second step, this new approach preservers a relation between the formula and the states of the resulting automaton. While the old approach produced a monolithic structure, the new method is compositional. Furthermore, in some cases the resulting automata are much smaller than the automata generated by existing approaches. In order to ensure the correctness of the construction, this entry contains a complete formalisation and verification of the translation. Furthermore from this basis executable code is generated. extra-history = Change history: [2015-09-23]: Enable code export for the eager unfolding optimisation and reduce running time of the generated tool. Moreover, add support for the mlton SML compiler.
[2016-03-24]: Make use of the LTL entry and include the simplifier. notify = sickert@in.tum.de [Timed_Automata] title = Timed Automata author = Simon Wimmer date = 2016-03-08 topic = Computer science/Automata and formal languages abstract = Timed automata are a widely used formalism for modeling real-time systems, which is employed in a class of successful model checkers such as UPPAAL [LPY97], HyTech [HHWt97] or Kronos [Yov97]. This work formalizes the theory for the subclass of diagonal-free timed automata, which is sufficient to model many interesting problems. We first define the basic concepts and semantics of diagonal-free timed automata. Based on this, we prove two types of decidability results for the language emptiness problem. The first is the classic result of Alur and Dill [AD90, AD94], which uses a finite partitioning of the state space into so-called `regions`. Our second result focuses on an approach based on `Difference Bound Matrices (DBMs)`, which is practically used by model checkers. We prove the correctness of the basic forward analysis operations on DBMs. One of these operations is the Floyd-Warshall algorithm for the all-pairs shortest paths problem. To obtain a finite search space, a widening operation has to be used for this kind of analysis. We use Patricia Bouyer's [Bou04] approach to prove that this widening operation is correct in the sense that DBM-based forward analysis in combination with the widening operation also decides language emptiness. The interesting property of this proof is that the first decidability result is reused to obtain the second one. notify = wimmers@in.tum.de [Parity_Game] title = Positional Determinacy of Parity Games author = Christoph Dittmann date = 2015-11-02 topic = Mathematics/Games and economics, Mathematics/Graph theory abstract = We present a formalization of parity games (a two-player game on directed graphs) and a proof of their positional determinacy in Isabelle/HOL. This proof works for both finite and infinite games. notify = [Ergodic_Theory] title = Ergodic Theory author = Sebastien Gouezel date = 2015-12-01 topic = Mathematics/Probability theory abstract = Ergodic theory is the branch of mathematics that studies the behaviour of measure preserving transformations, in finite or infinite measure. It interacts both with probability theory (mainly through measure theory) and with geometry as a lot of interesting examples are from geometric origin. We implement the first definitions and theorems of ergodic theory, including notably Poicaré recurrence theorem for finite measure preserving systems (together with the notion of conservativity in general), induced maps, Kac's theorem, Birkhoff theorem (arguably the most important theorem in ergodic theory), and variations around it such as conservativity of the corresponding skew product, or Atkinson lemma. notify = sebastien.gouezel@univ-rennes1.fr, hoelzl@in.tum.de [Latin_Square] title = Latin Square author = Alexander Bentkamp date = 2015-12-02 topic = Mathematics/Combinatorics abstract = A Latin Square is a n x n table filled with integers from 1 to n where each number appears exactly once in each row and each column. A Latin Rectangle is a partially filled n x n table with r filled rows and n-r empty rows, such that each number appears at most once in each row and each column. The main result of this theory is that any Latin Rectangle can be completed to a Latin Square. notify = bentkamp@gmail.com [Deep_Learning] title = Expressiveness of Deep Learning author = Alexander Bentkamp date = 2016-11-10 topic = Computer science/Machine learning, Mathematics/Analysis abstract = Deep learning has had a profound impact on computer science in recent years, with applications to search engines, image recognition and language processing, bioinformatics, and more. Recently, Cohen et al. provided theoretical evidence for the superiority of deep learning over shallow learning. This formalization of their work simplifies and generalizes the original proof, while working around the limitations of the Isabelle type system. To support the formalization, I developed reusable libraries of formalized mathematics, including results about the matrix rank, the Lebesgue measure, and multivariate polynomials, as well as a library for tensor analysis. notify = bentkamp@gmail.com [Inductive_Inference] title = Some classical results in inductive inference of recursive functions author = Frank J. Balbach topic = Logic/Computability, Computer science/Machine learning date = 2020-08-31 notify = frank-balbach@gmx.de abstract =

This entry formalizes some classical concepts and results from inductive inference of recursive functions. In the basic setting a partial recursive function ("strategy") must identify ("learn") all functions from a set ("class") of recursive functions. To that end the strategy receives more and more values $f(0), f(1), f(2), \ldots$ of some function $f$ from the given class and in turn outputs descriptions of partial recursive functions, for example, Gödel numbers. The strategy is considered successful if the sequence of outputs ("hypotheses") converges to a description of $f$. A class of functions learnable in this sense is called "learnable in the limit". The set of all these classes is denoted by LIM.

Other types of inference considered are finite learning (FIN), behaviorally correct learning in the limit (BC), and some variants of LIM with restrictions on the hypotheses: total learning (TOTAL), consistent learning (CONS), and class-preserving learning (CP). The main results formalized are the proper inclusions $\mathrm{FIN} \subset \mathrm{CP} \subset \mathrm{TOTAL} \subset \mathrm{CONS} \subset \mathrm{LIM} \subset \mathrm{BC} \subset 2^{\mathcal{R}}$, where $\mathcal{R}$ is the set of all total recursive functions. Further results show that for all these inference types except CONS, strategies can be assumed to be total recursive functions; that all inference types but CP are closed under the subset relation between classes; and that no inference type is closed under the union of classes.

The above is based on a formalization of recursive functions heavily inspired by the Universal Turing Machine entry by Xu et al., but different in that it models partial functions with codomain nat option. The formalization contains a construction of a universal partial recursive function, without resorting to Turing machines, introduces decidability and recursive enumerability, and proves some standard results: existence of a Kleene normal form, the s-m-n theorem, Rice's theorem, and assorted fixed-point theorems (recursion theorems) by Kleene, Rogers, and Smullyan.

[Applicative_Lifting] title = Applicative Lifting author = Andreas Lochbihler , Joshua Schneider <> date = 2015-12-22 topic = Computer science/Functional programming abstract = Applicative functors augment computations with effects by lifting function application to types which model the effects. As the structure of the computation cannot depend on the effects, applicative expressions can be analysed statically. This allows us to lift universally quantified equations to the effectful types, as observed by Hinze. Thus, equational reasoning over effectful computations can be reduced to pure types.

This entry provides a package for registering applicative functors and two proof methods for lifting of equations over applicative functors. The first method normalises applicative expressions according to the laws of applicative functors. This way, equations whose two sides contain the same list of variables can be lifted to every applicative functor.

To lift larger classes of equations, the second method exploits a number of additional properties (e.g., commutativity of effects) provided the properties have been declared for the concrete applicative functor at hand upon registration.

We declare several types from the Isabelle library as applicative functors and illustrate the use of the methods with two examples: the lifting of the arithmetic type class hierarchy to streams and the verification of a relabelling function on binary trees. We also formalise and verify the normalisation algorithm used by the first proof method.

extra-history = Change history: [2016-03-03]: added formalisation of lifting with combinators
[2016-06-10]: implemented automatic derivation of lifted combinator reductions; support arbitrary lifted relations using relators; improved compatibility with locale interpretation (revision ec336f354f37)
notify = mail@andreas-lochbihler.de [Stern_Brocot] title = The Stern-Brocot Tree author = Peter Gammie , Andreas Lochbihler date = 2015-12-22 topic = Mathematics/Number theory abstract = The Stern-Brocot tree contains all rational numbers exactly once and in their lowest terms. We formalise the Stern-Brocot tree as a coinductive tree using recursive and iterative specifications, which we have proven equivalent, and show that it indeed contains all the numbers as stated. Following Hinze, we prove that the Stern-Brocot tree can be linearised looplessly into Stern's diatonic sequence (also known as Dijkstra's fusc function) and that it is a permutation of the Bird tree.

The reasoning stays at an abstract level by appealing to the uniqueness of solutions of guarded recursive equations and lifting algebraic laws point-wise to trees and streams using applicative functors.

notify = mail@andreas-lochbihler.de [Algebraic_Numbers] title = Algebraic Numbers in Isabelle/HOL topic = Mathematics/Algebra author = René Thiemann , Akihisa Yamada , Sebastiaan Joosten contributors = Manuel Eberl date = 2015-12-22 abstract = Based on existing libraries for matrices, factorization of rational polynomials, and Sturm's theorem, we formalized algebraic numbers in Isabelle/HOL. Our development serves as an implementation for real and complex numbers, and it admits to compute roots and completely factorize real and complex polynomials, provided that all coefficients are rational numbers. Moreover, we provide two implementations to display algebraic numbers, an injective and expensive one, or a faster but approximative version.

To this end, we mechanized several results on resultants, which also required us to prove that polynomials over a unique factorization domain form again a unique factorization domain.

extra-history = Change history: [2016-01-29]: Split off Polynomial Interpolation and Polynomial Factorization
[2017-04-16]: Use certified Berlekamp-Zassenhaus factorization, use subresultant algorithm for computing resultants, improved bisection algorithm notify = rene.thiemann@uibk.ac.at, ayamada@trs.cm.is.nagoya-u.ac.jp, sebastiaan.joosten@uibk.ac.at [Polynomial_Interpolation] title = Polynomial Interpolation topic = Mathematics/Algebra author = René Thiemann , Akihisa Yamada date = 2016-01-29 abstract = We formalized three algorithms for polynomial interpolation over arbitrary fields: Lagrange's explicit expression, the recursive algorithm of Neville and Aitken, and the Newton interpolation in combination with an efficient implementation of divided differences. Variants of these algorithms for integer polynomials are also available, where sometimes the interpolation can fail; e.g., there is no linear integer polynomial p such that p(0) = 0 and p(2) = 1. Moreover, for the Newton interpolation for integer polynomials, we proved that all intermediate results that are computed during the algorithm must be integers. This admits an early failure detection in the implementation. Finally, we proved the uniqueness of polynomial interpolation.

The development also contains improved code equations to speed up the division of integers in target languages. notify = rene.thiemann@uibk.ac.at, ayamada@trs.cm.is.nagoya-u.ac.jp [Polynomial_Factorization] title = Polynomial Factorization topic = Mathematics/Algebra author = René Thiemann , Akihisa Yamada date = 2016-01-29 abstract = Based on existing libraries for polynomial interpolation and matrices, we formalized several factorization algorithms for polynomials, including Kronecker's algorithm for integer polynomials, Yun's square-free factorization algorithm for field polynomials, and Berlekamp's algorithm for polynomials over finite fields. By combining the last one with Hensel's lifting, we derive an efficient factorization algorithm for the integer polynomials, which is then lifted for rational polynomials by mechanizing Gauss' lemma. Finally, we assembled a combined factorization algorithm for rational polynomials, which combines all the mentioned algorithms and additionally uses the explicit formula for roots of quadratic polynomials and a rational root test.

As side products, we developed division algorithms for polynomials over integral domains, as well as primality-testing and prime-factorization algorithms for integers. notify = rene.thiemann@uibk.ac.at, ayamada@trs.cm.is.nagoya-u.ac.jp [Perron_Frobenius] title = Perron-Frobenius Theorem for Spectral Radius Analysis author = Jose Divasón , Ondřej Kunčar , René Thiemann , Akihisa Yamada notify = rene.thiemann@uibk.ac.at date = 2016-05-20 topic = Mathematics/Algebra abstract =

The spectral radius of a matrix A is the maximum norm of all eigenvalues of A. In previous work we already formalized that for a complex matrix A, the values in An grow polynomially in n if and only if the spectral radius is at most one. One problem with the above characterization is the determination of all complex eigenvalues. In case A contains only non-negative real values, a simplification is possible with the help of the Perron–Frobenius theorem, which tells us that it suffices to consider only the real eigenvalues of A, i.e., applying Sturm's method can decide the polynomial growth of An.

We formalize the Perron–Frobenius theorem based on a proof via Brouwer's fixpoint theorem, which is available in the HOL multivariate analysis (HMA) library. Since the results on the spectral radius is based on matrices in the Jordan normal form (JNF) library, we further develop a connection which allows us to easily transfer theorems between HMA and JNF. With this connection we derive the combined result: if A is a non-negative real matrix, and no real eigenvalue of A is strictly larger than one, then An is polynomially bounded in n.

extra-history = Change history: [2017-10-18]: added Perron-Frobenius theorem for irreducible matrices with generalization (revision bda1f1ce8a1c)
[2018-05-17]: prove conjecture of CPP'18 paper: Jordan blocks of spectral radius have maximum size (revision ffdb3794e5d5) [Stochastic_Matrices] title = Stochastic Matrices and the Perron-Frobenius Theorem author = René Thiemann topic = Mathematics/Algebra, Computer science/Automata and formal languages date = 2017-11-22 notify = rene.thiemann@uibk.ac.at abstract = Stochastic matrices are a convenient way to model discrete-time and finite state Markov chains. The Perron–Frobenius theorem tells us something about the existence and uniqueness of non-negative eigenvectors of a stochastic matrix. In this entry, we formalize stochastic matrices, link the formalization to the existing AFP-entry on Markov chains, and apply the Perron–Frobenius theorem to prove that stationary distributions always exist, and they are unique if the stochastic matrix is irreducible. [Formal_SSA] title = Verified Construction of Static Single Assignment Form author = Sebastian Ullrich , Denis Lohner date = 2016-02-05 topic = Computer science/Algorithms, Computer science/Programming languages/Transformations abstract =

We define a functional variant of the static single assignment (SSA) form construction algorithm described by Braun et al., which combines simplicity and efficiency. The definition is based on a general, abstract control flow graph representation using Isabelle locales.

We prove that the algorithm's output is semantically equivalent to the input according to a small-step semantics, and that it is in minimal SSA form for the common special case of reducible inputs. We then show the satisfiability of the locale assumptions by giving instantiations for a simple While language.

Furthermore, we use a generic instantiation based on typedefs in order to extract OCaml code and replace the unverified SSA construction algorithm of the CompCertSSA project with it.

A more detailed description of the verified SSA construction can be found in the paper Verified Construction of Static Single Assignment Form, CC 2016.

notify = denis.lohner@kit.edu [Minimal_SSA] title = Minimal Static Single Assignment Form author = Max Wagner , Denis Lohner topic = Computer science/Programming languages/Transformations date = 2017-01-17 notify = denis.lohner@kit.edu abstract =

This formalization is an extension to "Verified Construction of Static Single Assignment Form". In their work, the authors have shown that Braun et al.'s static single assignment (SSA) construction algorithm produces minimal SSA form for input programs with a reducible control flow graph (CFG). However Braun et al. also proposed an extension to their algorithm that they claim produces minimal SSA form even for irreducible CFGs.
In this formalization we support that claim by giving a mechanized proof.

As the extension of Braun et al.'s algorithm aims for removing so-called redundant strongly connected components of phi functions, we show that this suffices to guarantee minimality according to Cytron et al..

[PropResPI] title = Propositional Resolution and Prime Implicates Generation author = Nicolas Peltier notify = Nicolas.Peltier@imag.fr date = 2016-03-11 topic = Logic/General logic/Mechanization of proofs abstract = We provide formal proofs in Isabelle-HOL (using mostly structured Isar proofs) of the soundness and completeness of the Resolution rule in propositional logic. The completeness proofs take into account the usual redundancy elimination rules (tautology elimination and subsumption), and several refinements of the Resolution rule are considered: ordered resolution (with selection functions), positive and negative resolution, semantic resolution and unit resolution (the latter refinement is complete only for clause sets that are Horn- renamable). We also define a concrete procedure for computing saturated sets and establish its soundness and completeness. The clause sets are not assumed to be finite, so that the results can be applied to formulas obtained by grounding sets of first-order clauses (however, a total ordering among atoms is assumed to be given). Next, we show that the unrestricted Resolution rule is deductive- complete, in the sense that it is able to generate all (prime) implicates of any set of propositional clauses (i.e., all entailment- minimal, non-valid, clausal consequences of the considered set). The generation of prime implicates is an important problem, with many applications in artificial intelligence and verification (for abductive reasoning, knowledge compilation, diagnosis, debugging etc.). We also show that implicates can be computed in an incremental way, by fixing an ordering among all the atoms in the considered sets and resolving upon these atoms one by one in the considered order (with no backtracking). This feature is critical for the efficient computation of prime implicates. Building on these results, we provide a procedure for computing such implicates and establish its soundness and completeness. [SuperCalc] title = A Variant of the Superposition Calculus author = Nicolas Peltier notify = Nicolas.Peltier@imag.fr date = 2016-09-06 topic = Logic/Proof theory abstract = We provide a formalization of a variant of the superposition calculus, together with formal proofs of soundness and refutational completeness (w.r.t. the usual redundancy criteria based on clause ordering). This version of the calculus uses all the standard restrictions of the superposition rules, together with the following refinement, inspired by the basic superposition calculus: each clause is associated with a set of terms which are assumed to be in normal form -- thus any application of the replacement rule on these terms is blocked. The set is initially empty and terms may be added or removed at each inference step. The set of terms that are assumed to be in normal form includes any term introduced by previous unifiers as well as any term occurring in the parent clauses at a position that is smaller (according to some given ordering on positions) than a previously replaced term. The standard superposition calculus corresponds to the case where the set of irreducible terms is always empty. [Nominal2] title = Nominal 2 author = Christian Urban , Stefan Berghofer , Cezary Kaliszyk date = 2013-02-21 topic = Tools abstract =

Dealing with binders, renaming of bound variables, capture-avoiding substitution, etc., is very often a major problem in formal proofs, especially in proofs by structural and rule induction. Nominal Isabelle is designed to make such proofs easy to formalise: it provides an infrastructure for declaring nominal datatypes (that is alpha-equivalence classes) and for defining functions over them by structural recursion. It also provides induction principles that have Barendregt’s variable convention already built in.

This entry can be used as a more advanced replacement for HOL/Nominal in the Isabelle distribution.

notify = christian.urban@kcl.ac.uk [First_Welfare_Theorem] title = Microeconomics and the First Welfare Theorem author = Julian Parsert , Cezary Kaliszyk topic = Mathematics/Games and economics license = LGPL date = 2017-09-01 notify = julian.parsert@uibk.ac.at, cezary.kaliszyk@uibk.ac.at abstract = Economic activity has always been a fundamental part of society. Due to modern day politics, economic theory has gained even more influence on our lives. Thus we want models and theories to be as precise as possible. This can be achieved using certification with the help of formal proof technology. Hence we will use Isabelle/HOL to construct two economic models, that of the the pure exchange economy and a version of the Arrow-Debreu Model. We will prove that the First Theorem of Welfare Economics holds within both. The theorem is the mathematical formulation of Adam Smith's famous invisible hand and states that a group of self-interested and rational actors will eventually achieve an efficient allocation of goods and services. extra-history = Change history: [2018-06-17]: Added some lemmas and a theory file, also introduced Microeconomics folder.
[Noninterference_Sequential_Composition] title = Conservation of CSP Noninterference Security under Sequential Composition author = Pasquale Noce date = 2016-04-26 topic = Computer science/Security, Computer science/Concurrency/Process calculi abstract =

In his outstanding work on Communicating Sequential Processes, Hoare has defined two fundamental binary operations allowing to compose the input processes into another, typically more complex, process: sequential composition and concurrent composition. Particularly, the output of the former operation is a process that initially behaves like the first operand, and then like the second operand once the execution of the first one has terminated successfully, as long as it does.

This paper formalizes Hoare's definition of sequential composition and proves, in the general case of a possibly intransitive policy, that CSP noninterference security is conserved under this operation, provided that successful termination cannot be affected by confidential events and cannot occur as an alternative to other events in the traces of the first operand. Both of these assumptions are shown, by means of counterexamples, to be necessary for the theorem to hold.

notify = pasquale.noce.lavoro@gmail.com [Noninterference_Concurrent_Composition] title = Conservation of CSP Noninterference Security under Concurrent Composition author = Pasquale Noce notify = pasquale.noce.lavoro@gmail.com date = 2016-06-13 topic = Computer science/Security, Computer science/Concurrency/Process calculi abstract =

In his outstanding work on Communicating Sequential Processes, Hoare has defined two fundamental binary operations allowing to compose the input processes into another, typically more complex, process: sequential composition and concurrent composition. Particularly, the output of the latter operation is a process in which any event not shared by both operands can occur whenever the operand that admits the event can engage in it, whereas any event shared by both operands can occur just in case both can engage in it.

This paper formalizes Hoare's definition of concurrent composition and proves, in the general case of a possibly intransitive policy, that CSP noninterference security is conserved under this operation. This result, along with the previous analogous one concerning sequential composition, enables the construction of more and more complex processes enforcing noninterference security by composing, sequentially or concurrently, simpler secure processes, whose security can in turn be proven using either the definition of security, or unwinding theorems.

[ROBDD] title = Algorithms for Reduced Ordered Binary Decision Diagrams author = Julius Michaelis , Maximilian Haslbeck , Peter Lammich , Lars Hupel date = 2016-04-27 topic = Computer science/Algorithms, Computer science/Data structures abstract = We present a verified and executable implementation of ROBDDs in Isabelle/HOL. Our implementation relates pointer-based computation in the Heap monad to operations on an abstract definition of boolean functions. Internally, we implemented the if-then-else combinator in a recursive fashion, following the Shannon decomposition of the argument functions. The implementation mixes and adapts known techniques and is built with efficiency in mind. notify = bdd@liftm.de, haslbecm@in.tum.de [No_FTL_observers] title = No Faster-Than-Light Observers author = Mike Stannett , István Németi date = 2016-04-28 topic = Mathematics/Physics abstract = We provide a formal proof within First Order Relativity Theory that no observer can travel faster than the speed of light. Originally reported in Stannett & Németi (2014) "Using Isabelle/HOL to verify first-order relativity theory", Journal of Automated Reasoning 52(4), pp. 361-378. notify = m.stannett@sheffield.ac.uk [Groebner_Bases] title = Gröbner Bases Theory author = Fabian Immler , Alexander Maletzky date = 2016-05-02 topic = Mathematics/Algebra, Computer science/Algorithms/Mathematical abstract = This formalization is concerned with the theory of Gröbner bases in (commutative) multivariate polynomial rings over fields, originally developed by Buchberger in his 1965 PhD thesis. Apart from the statement and proof of the main theorem of the theory, the formalization also implements Buchberger's algorithm for actually computing Gröbner bases as a tail-recursive function, thus allowing to effectively decide ideal membership in finitely generated polynomial ideals. Furthermore, all functions can be executed on a concrete representation of multivariate polynomials as association lists. extra-history = Change history: [2019-04-18]: Specialized Gröbner bases to less abstract representation of polynomials, where power-products are represented as polynomial mappings.
notify = alexander.maletzky@risc.jku.at [Nullstellensatz] title = Hilbert's Nullstellensatz author = Alexander Maletzky topic = Mathematics/Algebra, Mathematics/Geometry date = 2019-06-16 notify = alexander.maletzky@risc-software.at abstract = This entry formalizes Hilbert's Nullstellensatz, an important theorem in algebraic geometry that can be viewed as the generalization of the Fundamental Theorem of Algebra to multivariate polynomials: If a set of (multivariate) polynomials over an algebraically closed field has no common zero, then the ideal it generates is the entire polynomial ring. The formalization proves several equivalent versions of this celebrated theorem: the weak Nullstellensatz, the strong Nullstellensatz (connecting algebraic varieties and radical ideals), and the field-theoretic Nullstellensatz. The formalization follows Chapter 4.1. of Ideals, Varieties, and Algorithms by Cox, Little and O'Shea. [Bell_Numbers_Spivey] title = Spivey's Generalized Recurrence for Bell Numbers author = Lukas Bulwahn date = 2016-05-04 topic = Mathematics/Combinatorics abstract = This entry defines the Bell numbers as the cardinality of set partitions for a carrier set of given size, and derives Spivey's generalized recurrence relation for Bell numbers following his elegant and intuitive combinatorial proof.

As the set construction for the combinatorial proof requires construction of three intermediate structures, the main difficulty of the formalization is handling the overall combinatorial argument in a structured way. The introduced proof structure allows us to compose the combinatorial argument from its subparts, and supports to keep track how the detailed proof steps are related to the overall argument. To obtain this structure, this entry uses set monad notation for the set construction's definition, introduces suitable predicates and rules, and follows a repeating structure in its Isar proof. notify = lukas.bulwahn@gmail.com [Randomised_Social_Choice] title = Randomised Social Choice Theory author = Manuel Eberl date = 2016-05-05 topic = Mathematics/Games and economics abstract = This work contains a formalisation of basic Randomised Social Choice, including Stochastic Dominance and Social Decision Schemes (SDSs) along with some of their most important properties (Anonymity, Neutrality, ex-post- and SD-Efficiency, SD-Strategy-Proofness) and two particular SDSs – Random Dictatorship and Random Serial Dictatorship (with proofs of the properties that they satisfy). Many important properties of these concepts are also proven – such as the two equivalent characterisations of Stochastic Dominance and the fact that SD-efficiency of a lottery only depends on the support. The entry also provides convenient commands to define Preference Profiles, prove their well-formedness, and automatically derive restrictions that sufficiently nice SDSs need to satisfy on the defined profiles. Currently, the formalisation focuses on weak preferences and Stochastic Dominance, but it should be easy to extend it to other domains – such as strict preferences – or other lottery extensions – such as Bilinear Dominance or Pairwise Comparison. notify = eberlm@in.tum.de [SDS_Impossibility] title = The Incompatibility of SD-Efficiency and SD-Strategy-Proofness author = Manuel Eberl date = 2016-05-04 topic = Mathematics/Games and economics abstract = This formalisation contains the proof that there is no anonymous and neutral Social Decision Scheme for at least four voters and alternatives that fulfils both SD-Efficiency and SD-Strategy- Proofness. The proof is a fully structured and quasi-human-redable one. It was derived from the (unstructured) SMT proof of the case for exactly four voters and alternatives by Brandl et al. Their proof relies on an unverified translation of the original problem to SMT, and the proof that lifts the argument for exactly four voters and alternatives to the general case is also not machine-checked. In this Isabelle proof, on the other hand, all of these steps are fully proven and machine-checked. This is particularly important seeing as a previously published informal proof of a weaker statement contained a mistake in precisely this lifting step. notify = eberlm@in.tum.de [Median_Of_Medians_Selection] title = The Median-of-Medians Selection Algorithm author = Manuel Eberl topic = Computer science/Algorithms date = 2017-12-21 notify = eberlm@in.tum.de abstract =

This entry provides an executable functional implementation of the Median-of-Medians algorithm for selecting the k-th smallest element of an unsorted list deterministically in linear time. The size bounds for the recursive call that lead to the linear upper bound on the run-time of the algorithm are also proven.

[Mason_Stothers] title = The Mason–Stothers Theorem author = Manuel Eberl topic = Mathematics/Algebra date = 2017-12-21 notify = eberlm@in.tum.de abstract =

This article provides a formalisation of Snyder’s simple and elegant proof of the Mason–Stothers theorem, which is the polynomial analogue of the famous abc Conjecture for integers. Remarkably, Snyder found this very elegant proof when he was still a high-school student.

In short, the statement of the theorem is that three non-zero coprime polynomials A, B, C over a field which sum to 0 and do not all have vanishing derivatives fulfil max{deg(A), deg(B), deg(C)} < deg(rad(ABC)) where the rad(P) denotes the radical of P, i. e. the product of all unique irreducible factors of P.

This theorem also implies a kind of polynomial analogue of Fermat’s Last Theorem for polynomials: except for trivial cases, An + Bn + Cn = 0 implies n ≤ 2 for coprime polynomials A, B, C over a field.

[FLP] title = A Constructive Proof for FLP author = Benjamin Bisping , Paul-David Brodmann , Tim Jungnickel , Christina Rickmann , Henning Seidler , Anke Stüber , Arno Wilhelm-Weidner , Kirstin Peters , Uwe Nestmann date = 2016-05-18 topic = Computer science/Concurrency abstract = The impossibility of distributed consensus with one faulty process is a result with important consequences for real world distributed systems e.g., commits in replicated databases. Since proofs are not immune to faults and even plausible proofs with a profound formalism can conclude wrong results, we validate the fundamental result named FLP after Fischer, Lynch and Paterson. We present a formalization of distributed systems and the aforementioned consensus problem. Our proof is based on Hagen Völzer's paper "A constructive proof for FLP". In addition to the enhanced confidence in the validity of Völzer's proof, we contribute the missing gaps to show the correctness in Isabelle/HOL. We clarify the proof details and even prove fairness of the infinite execution that contradicts consensus. Our Isabelle formalization can also be reused for further proofs of properties of distributed systems. notify = henning.seidler@mailbox.tu-berlin.de [IMAP-CRDT] title = The IMAP CmRDT author = Tim Jungnickel , Lennart Oldenburg <>, Matthias Loibl <> topic = Computer science/Algorithms/Distributed, Computer science/Data structures date = 2017-11-09 notify = tim.jungnickel@tu-berlin.de abstract = We provide our Isabelle/HOL formalization of a Conflict-free Replicated Datatype for Internet Message Access Protocol commands. We show that Strong Eventual Consistency (SEC) is guaranteed by proving the commutativity of concurrent operations. We base our formalization on the recently proposed "framework for establishing Strong Eventual Consistency for Conflict-free Replicated Datatypes" (AFP.CRDT) from Gomes et al. Hence, we provide an additional example of how the recently proposed framework can be used to design and prove CRDTs. [Incredible_Proof_Machine] title = The meta theory of the Incredible Proof Machine author = Joachim Breitner , Denis Lohner date = 2016-05-20 topic = Logic/Proof theory abstract = The Incredible Proof Machine is an interactive visual theorem prover which represents proofs as port graphs. We model this proof representation in Isabelle, and prove that it is just as powerful as natural deduction. notify = mail@joachim-breitner.de [Word_Lib] title = Finite Machine Word Library author = Joel Beeren<>, Matthew Fernandez<>, Xin Gao<>, Gerwin Klein , Rafal Kolanski<>, Japheth Lim<>, Corey Lewis<>, Daniel Matichuk<>, Thomas Sewell<> notify = kleing@unsw.edu.au date = 2016-06-09 topic = Computer science/Data structures abstract = This entry contains an extension to the Isabelle library for fixed-width machine words. In particular, the entry adds quickcheck setup for words, printing as hexadecimals, additional operations, reasoning about alignment, signed words, enumerations of words, normalisation of word numerals, and an extensive library of properties about generic fixed-width words, as well as an instantiation of many of these to the commonly used 32 and 64-bit bases. [Catalan_Numbers] title = Catalan Numbers author = Manuel Eberl notify = eberlm@in.tum.de date = 2016-06-21 topic = Mathematics/Combinatorics abstract =

In this work, we define the Catalan numbers Cn and prove several equivalent definitions (including some closed-form formulae). We also show one of their applications (counting the number of binary trees of size n), prove the asymptotic growth approximation Cn ∼ 4n / (√π · n1.5), and provide reasonably efficient executable code to compute them.

The derivation of the closed-form formulae uses algebraic manipulations of the ordinary generating function of the Catalan numbers, and the asymptotic approximation is then done using generalised binomial coefficients and the Gamma function. Thanks to these highly non-elementary mathematical tools, the proofs are very short and simple.

[Fisher_Yates] title = Fisher–Yates shuffle author = Manuel Eberl notify = eberlm@in.tum.de date = 2016-09-30 topic = Computer science/Algorithms abstract =

This work defines and proves the correctness of the Fisher–Yates algorithm for shuffling – i.e. producing a random permutation – of a list. The algorithm proceeds by traversing the list and in each step swapping the current element with a random element from the remaining list.

[Bertrands_Postulate] title = Bertrand's postulate author = Julian Biendarra<>, Manuel Eberl contributors = Lawrence C. Paulson topic = Mathematics/Number theory date = 2017-01-17 notify = eberlm@in.tum.de abstract =

Bertrand's postulate is an early result on the distribution of prime numbers: For every positive integer n, there exists a prime number that lies strictly between n and 2n. The proof is ported from John Harrison's formalisation in HOL Light. It proceeds by first showing that the property is true for all n greater than or equal to 600 and then showing that it also holds for all n below 600 by case distinction.

[Rewriting_Z] title = The Z Property author = Bertram Felgenhauer<>, Julian Nagele<>, Vincent van Oostrom<>, Christian Sternagel notify = bertram.felgenhauer@uibk.ac.at, julian.nagele@uibk.ac.at, c.sternagel@gmail.com date = 2016-06-30 topic = Logic/Rewriting abstract = We formalize the Z property introduced by Dehornoy and van Oostrom. First we show that for any abstract rewrite system, Z implies confluence. Then we give two examples of proofs using Z: confluence of lambda-calculus with respect to beta-reduction and confluence of combinatory logic. [Resolution_FOL] title = The Resolution Calculus for First-Order Logic author = Anders Schlichtkrull notify = andschl@dtu.dk date = 2016-06-30 topic = Logic/General logic/Mechanization of proofs abstract = This theory is a formalization of the resolution calculus for first-order logic. It is proven sound and complete. The soundness proof uses the substitution lemma, which shows a correspondence between substitutions and updates to an environment. The completeness proof uses semantic trees, i.e. trees whose paths are partial Herbrand interpretations. It employs Herbrand's theorem in a formulation which states that an unsatisfiable set of clauses has a finite closed semantic tree. It also uses the lifting lemma which lifts resolution derivation steps from the ground world up to the first-order world. The theory is presented in a paper in the Journal of Automated Reasoning [Sch18] which extends a paper presented at the International Conference on Interactive Theorem Proving [Sch16]. An earlier version was presented in an MSc thesis [Sch15]. The formalization mostly follows textbooks by Ben-Ari [BA12], Chang and Lee [CL73], and Leitsch [Lei97]. The theory is part of the IsaFoL project [IsaFoL].

[Sch18] Anders Schlichtkrull. "Formalization of the Resolution Calculus for First-Order Logic". Journal of Automated Reasoning, 2018.
[Sch16] Anders Schlichtkrull. "Formalization of the Resolution Calculus for First-Order Logic". In: ITP 2016. Vol. 9807. LNCS. Springer, 2016.
[Sch15] Anders Schlichtkrull. "Formalization of Resolution Calculus in Isabelle". https://people.compute.dtu.dk/andschl/Thesis.pdf. MSc thesis. Technical University of Denmark, 2015.
[BA12] Mordechai Ben-Ari. Mathematical Logic for Computer Science. 3rd. Springer, 2012.
[CL73] Chin-Liang Chang and Richard Char-Tung Lee. Symbolic Logic and Mechanical Theorem Proving. 1st. Academic Press, Inc., 1973.
[Lei97] Alexander Leitsch. The Resolution Calculus. Texts in theoretical computer science. Springer, 1997.
[IsaFoL] IsaFoL authors. IsaFoL: Isabelle Formalization of Logic. https://bitbucket.org/jasmin_blanchette/isafol. extra-history = Change history: [2018-01-24]: added several new versions of the soundness and completeness theorems as described in the paper [Sch18].
[2018-03-20]: added a concrete instance of the unification and completeness theorems using the First-Order Terms AFP-entry from IsaFoR as described in the papers [Sch16] and [Sch18]. [Surprise_Paradox] title = Surprise Paradox author = Joachim Breitner notify = mail@joachim-breitner.de date = 2016-07-17 topic = Logic/Proof theory abstract = In 1964, Fitch showed that the paradox of the surprise hanging can be resolved by showing that the judge’s verdict is inconsistent. His formalization builds on Gödel’s coding of provability. In this theory, we reproduce his proof in Isabelle, building on Paulson’s formalisation of Gödel’s incompleteness theorems. [Ptolemys_Theorem] title = Ptolemy's Theorem author = Lukas Bulwahn notify = lukas.bulwahn@gmail.com date = 2016-08-07 topic = Mathematics/Geometry abstract = This entry provides an analytic proof to Ptolemy's Theorem using polar form transformation and trigonometric identities. In this formalization, we use ideas from John Harrison's HOL Light formalization and the proof sketch on the Wikipedia entry of Ptolemy's Theorem. This theorem is the 95th theorem of the Top 100 Theorems list. [Falling_Factorial_Sum] title = The Falling Factorial of a Sum author = Lukas Bulwahn topic = Mathematics/Combinatorics date = 2017-12-22 notify = lukas.bulwahn@gmail.com abstract = This entry shows that the falling factorial of a sum can be computed with an expression using binomial coefficients and the falling factorial of its summands. The entry provides three different proofs: a combinatorial proof, an induction proof and an algebraic proof using the Vandermonde identity. The three formalizations try to follow their informal presentations from a Mathematics Stack Exchange page as close as possible. The induction and algebraic formalization end up to be very close to their informal presentation, whereas the combinatorial proof first requires the introduction of list interleavings, and significant more detail than its informal presentation. [InfPathElimination] title = Infeasible Paths Elimination by Symbolic Execution Techniques: Proof of Correctness and Preservation of Paths author = Romain Aissat<>, Frederic Voisin<>, Burkhart Wolff notify = wolff@lri.fr date = 2016-08-18 topic = Computer science/Programming languages/Static analysis abstract = TRACER is a tool for verifying safety properties of sequential C programs. TRACER attempts at building a finite symbolic execution graph which over-approximates the set of all concrete reachable states and the set of feasible paths. We present an abstract framework for TRACER and similar CEGAR-like systems. The framework provides 1) a graph- transformation based method for reducing the feasible paths in control-flow graphs, 2) a model for symbolic execution, subsumption, predicate abstraction and invariant generation. In this framework we formally prove two key properties: correct construction of the symbolic states and preservation of feasible paths. The framework focuses on core operations, leaving to concrete prototypes to “fit in” heuristics for combining them. The accompanying paper (published in ITP 2016) can be found at https://www.lri.fr/∼wolff/papers/conf/2016-itp-InfPathsNSE.pdf. [Stirling_Formula] title = Stirling's formula author = Manuel Eberl notify = eberlm@in.tum.de date = 2016-09-01 topic = Mathematics/Analysis abstract =

This work contains a proof of Stirling's formula both for the factorial $n! \sim \sqrt{2\pi n} (n/e)^n$ on natural numbers and the real Gamma function $\Gamma(x)\sim \sqrt{2\pi/x} (x/e)^x$. The proof is based on work by Graham Jameson.

This is then extended to the full asymptotic expansion $$\log\Gamma(z) = \big(z - \tfrac{1}{2}\big)\log z - z + \tfrac{1}{2}\log(2\pi) + \sum_{k=1}^{n-1} \frac{B_{k+1}}{k(k+1)} z^{-k}\\ {} - \frac{1}{n} \int_0^\infty B_n([t])(t + z)^{-n}\,\text{d}t$$ uniformly for all complex $z\neq 0$ in the cone $\text{arg}(z)\leq \alpha$ for any $\alpha\in(0,\pi)$, with which the above asymptotic relation for Γ is also extended to complex arguments.

[Lp] title = Lp spaces author = Sebastien Gouezel notify = sebastien.gouezel@univ-rennes1.fr date = 2016-10-05 topic = Mathematics/Analysis abstract = Lp is the space of functions whose p-th power is integrable. It is one of the most fundamental Banach spaces that is used in analysis and probability. We develop a framework for function spaces, and then implement the Lp spaces in this framework using the existing integration theory in Isabelle/HOL. Our development contains most fundamental properties of Lp spaces, notably the Hölder and Minkowski inequalities, completeness of Lp, duality, stability under almost sure convergence, multiplication of functions in Lp and Lq, stability under conditional expectation. [Berlekamp_Zassenhaus] title = The Factorization Algorithm of Berlekamp and Zassenhaus author = Jose Divasón , Sebastiaan Joosten , René Thiemann , Akihisa Yamada notify = rene.thiemann@uibk.ac.at date = 2016-10-14 topic = Mathematics/Algebra abstract =

We formalize the Berlekamp-Zassenhaus algorithm for factoring square-free integer polynomials in Isabelle/HOL. We further adapt an existing formalization of Yun’s square-free factorization algorithm to integer polynomials, and thus provide an efficient and certified factorization algorithm for arbitrary univariate polynomials.

The algorithm first performs a factorization in the prime field GF(p) and then performs computations in the integer ring modulo p^k, where both p and k are determined at runtime. Since a natural modeling of these structures via dependent types is not possible in Isabelle/HOL, we formalize the whole algorithm using Isabelle’s recent addition of local type definitions.

Through experiments we verify that our algorithm factors polynomials of degree 100 within seconds.

[Allen_Calculus] title = Allen's Interval Calculus author = Fadoua Ghourabi <> notify = fadouaghourabi@gmail.com date = 2016-09-29 topic = Logic/General logic/Temporal logic, Mathematics/Order abstract = Allen’s interval calculus is a qualitative temporal representation of time events. Allen introduced 13 binary relations that describe all the possible arrangements between two events, i.e. intervals with non-zero finite length. The compositions are pertinent to reasoning about knowledge of time. In particular, a consistency problem of relation constraints is commonly solved with a guideline from these compositions. We formalize the relations together with an axiomatic system. We proof the validity of the 169 compositions of these relations. We also define nests as the sets of intervals that share a meeting point. We prove that nests give the ordering properties of points without introducing a new datatype for points. [1] J.F. Allen. Maintaining Knowledge about Temporal Intervals. In Commun. ACM, volume 26, pages 832–843, 1983. [2] J. F. Allen and P. J. Hayes. A Common-sense Theory of Time. In Proceedings of the 9th International Joint Conference on Artificial Intelligence (IJCAI’85), pages 528–531, 1985. [Source_Coding_Theorem] title = Source Coding Theorem author = Quentin Hibon , Lawrence C. Paulson notify = qh225@cl.cam.ac.uk date = 2016-10-19 topic = Mathematics/Probability theory abstract = This document contains a proof of the necessary condition on the code rate of a source code, namely that this code rate is bounded by the entropy of the source. This represents one half of Shannon's source coding theorem, which is itself an equivalence. [Buffons_Needle] title = Buffon's Needle Problem author = Manuel Eberl topic = Mathematics/Probability theory, Mathematics/Geometry date = 2017-06-06 notify = eberlm@in.tum.de abstract = In the 18th century, Georges-Louis Leclerc, Comte de Buffon posed and later solved the following problem, which is often called the first problem ever solved in geometric probability: Given a floor divided into vertical strips of the same width, what is the probability that a needle thrown onto the floor randomly will cross two strips? This entry formally defines the problem in the case where the needle's position is chosen uniformly at random in a single strip around the origin (which is equivalent to larger arrangements due to symmetry). It then provides proofs of the simple solution in the case where the needle's length is no greater than the width of the strips and the more complicated solution in the opposite case. [SPARCv8] title = A formal model for the SPARCv8 ISA and a proof of non-interference for the LEON3 processor author = Zhe Hou , David Sanan , Alwen Tiu , Yang Liu notify = zhe.hou@ntu.edu.sg, sanan@ntu.edu.sg date = 2016-10-19 topic = Computer science/Security, Computer science/Hardware abstract = We formalise the SPARCv8 instruction set architecture (ISA) which is used in processors such as LEON3. Our formalisation can be specialised to any SPARCv8 CPU, here we use LEON3 as a running example. Our model covers the operational semantics for all the instructions in the integer unit of the SPARCv8 architecture and it supports Isabelle code export, which effectively turns the Isabelle model into a SPARCv8 CPU simulator. We prove the language-based non-interference property for the LEON3 processor. Our model is based on deterministic monad, which is a modified version of the non-deterministic monad from NICTA/l4v. [Separata] title = Separata: Isabelle tactics for Separation Algebra author = Zhe Hou , David Sanan , Alwen Tiu , Rajeev Gore , Ranald Clouston notify = zhe.hou@ntu.edu.sg date = 2016-11-16 topic = Computer science/Programming languages/Logics, Tools abstract = We bring the labelled sequent calculus $LS_{PASL}$ for propositional abstract separation logic to Isabelle. The tactics given here are directly applied on an extension of the Separation Algebra in the AFP. In addition to the cancellative separation algebra, we further consider some useful properties in the heap model of separation logic, such as indivisible unit, disjointness, and cross-split. The tactics are essentially a proof search procedure for the calculus $LS_{PASL}$. We wrap the tactics in an Isabelle method called separata, and give a few examples of separation logic formulae which are provable by separata. [LOFT] title = LOFT — Verified Migration of Linux Firewalls to SDN author = Julius Michaelis , Cornelius Diekmann notify = isabelleopenflow@liftm.de date = 2016-10-21 topic = Computer science/Networks abstract = We present LOFT — Linux firewall OpenFlow Translator, a system that transforms the main routing table and FORWARD chain of iptables of a Linux-based firewall into a set of static OpenFlow rules. Our implementation is verified against a model of a simplified Linux-based router and we can directly show how much of the original functionality is preserved. [Stable_Matching] title = Stable Matching author = Peter Gammie notify = peteg42@gmail.com date = 2016-10-24 topic = Mathematics/Games and economics abstract = We mechanize proofs of several results from the matching with contracts literature, which generalize those of the classical two-sided matching scenarios that go by the name of stable marriage. Our focus is on game theoretic issues. Along the way we develop executable algorithms for computing optimal stable matches. [Modal_Logics_for_NTS] title = Modal Logics for Nominal Transition Systems author = Tjark Weber , Lars-Henrik Eriksson , Joachim Parrow , Johannes Borgström , Ramunas Gutkovas notify = tjark.weber@it.uu.se date = 2016-10-25 topic = Computer science/Concurrency/Process calculi, Logic/General logic/Modal logic abstract = We formalize a uniform semantic substrate for a wide variety of process calculi where states and action labels can be from arbitrary nominal sets. A Hennessy-Milner logic for these systems is defined, and proved adequate for bisimulation equivalence. A main novelty is the construction of an infinitary nominal data type to model formulas with (finitely supported) infinite conjunctions and actions that may contain binding names. The logic is generalized to treat different bisimulation variants such as early, late and open in a systematic way. extra-history = Change history: [2017-01-29]: Formalization of weak bisimilarity added (revision c87cc2057d9c) [Abs_Int_ITP2012] title = Abstract Interpretation of Annotated Commands author = Tobias Nipkow notify = nipkow@in.tum.de date = 2016-11-23 topic = Computer science/Programming languages/Static analysis abstract = This is the Isabelle formalization of the material decribed in the eponymous ITP 2012 paper. It develops a generic abstract interpreter for a while-language, including widening and narrowing. The collecting semantics and the abstract interpreter operate on annotated commands: the program is represented as a syntax tree with the semantic information directly embedded, without auxiliary labels. The aim of the formalization is simplicity, not efficiency or precision. This is motivated by the inclusion of the material in a theorem prover based course on semantics. A similar (but more polished) development is covered in the book Concrete Semantics. [Complx] title = COMPLX: A Verification Framework for Concurrent Imperative Programs author = Sidney Amani<>, June Andronick<>, Maksym Bortin<>, Corey Lewis<>, Christine Rizkallah<>, Joseph Tuong<> notify = sidney.amani@data61.csiro.au, corey.lewis@data61.csiro.au date = 2016-11-29 topic = Computer science/Programming languages/Logics, Computer science/Programming languages/Language definitions abstract = We propose a concurrency reasoning framework for imperative programs, based on the Owicki-Gries (OG) foundational shared-variable concurrency method. Our framework combines the approaches of Hoare-Parallel, a formalisation of OG in Isabelle/HOL for a simple while-language, and Simpl, a generic imperative language embedded in Isabelle/HOL, allowing formal reasoning on C programs. We define the Complx language, extending the syntax and semantics of Simpl with support for parallel composition and synchronisation. We additionally define an OG logic, which we prove sound w.r.t. the semantics, and a verification condition generator, both supporting involved low-level imperative constructs such as function calls and abrupt termination. We illustrate our framework on an example that features exceptions, guards and function calls. We aim to then target concurrent operating systems, such as the interruptible eChronos embedded operating system for which we already have a model-level OG proof using Hoare-Parallel. extra-history = Change history: [2017-01-13]: Improve VCG for nested parallels and sequential sections (revision 30739dbc3dcb) [Paraconsistency] title = Paraconsistency author = Anders Schlichtkrull , Jørgen Villadsen topic = Logic/General logic/Paraconsistent logics date = 2016-12-07 notify = andschl@dtu.dk, jovi@dtu.dk abstract = Paraconsistency is about handling inconsistency in a coherent way. In classical and intuitionistic logic everything follows from an inconsistent theory. A paraconsistent logic avoids the explosion. Quite a few applications in computer science and engineering are discussed in the Intelligent Systems Reference Library Volume 110: Towards Paraconsistent Engineering (Springer 2016). We formalize a paraconsistent many-valued logic that we motivated and described in a special issue on logical approaches to paraconsistency (Journal of Applied Non-Classical Logics 2005). We limit ourselves to the propositional fragment of the higher-order logic. The logic is based on so-called key equalities and has a countably infinite number of truth values. We prove theorems in the logic using the definition of validity. We verify truth tables and also counterexamples for non-theorems. We prove meta-theorems about the logic and finally we investigate a case study. [Proof_Strategy_Language] title = Proof Strategy Language author = Yutaka Nagashima<> topic = Tools date = 2016-12-20 notify = Yutaka.Nagashima@data61.csiro.au abstract = Isabelle includes various automatic tools for finding proofs under certain conditions. However, for each conjecture, knowing which automation to use, and how to tweak its parameters, is currently labour intensive. We have developed a language, PSL, designed to capture high level proof strategies. PSL offloads the construction of human-readable fast-to-replay proof scripts to automatic search, making use of search-time information about each conjecture. Our preliminary evaluations show that PSL reduces the labour cost of interactive theorem proving. This submission contains the implementation of PSL and an example theory file, Example.thy, showing how to write poof strategies in PSL. [Concurrent_Ref_Alg] title = Concurrent Refinement Algebra and Rely Quotients author = Julian Fell , Ian J. Hayes , Andrius Velykis topic = Computer science/Concurrency date = 2016-12-30 notify = Ian.Hayes@itee.uq.edu.au abstract = The concurrent refinement algebra developed here is designed to provide a foundation for rely/guarantee reasoning about concurrent programs. The algebra builds on a complete lattice of commands by providing sequential composition, parallel composition and a novel weak conjunction operator. The weak conjunction operator coincides with the lattice supremum providing its arguments are non-aborting, but aborts if either of its arguments do. Weak conjunction provides an abstract version of a guarantee condition as a guarantee process. We distinguish between models that distribute sequential composition over non-deterministic choice from the left (referred to as being conjunctive in the refinement calculus literature) and those that don't. Least and greatest fixed points of monotone functions are provided to allow recursion and iteration operators to be added to the language. Additional iteration laws are available for conjunctive models. The rely quotient of processes c and i is the process that, if executed in parallel with i implements c. It represents an abstract version of a rely condition generalised to a process. [FOL_Harrison] title = First-Order Logic According to Harrison author = Alexander Birch Jensen , Anders Schlichtkrull , Jørgen Villadsen topic = Logic/General logic/Mechanization of proofs date = 2017-01-01 notify = aleje@dtu.dk, andschl@dtu.dk, jovi@dtu.dk abstract =

We present a certified declarative first-order prover with equality based on John Harrison's Handbook of Practical Logic and Automated Reasoning, Cambridge University Press, 2009. ML code reflection is used such that the entire prover can be executed within Isabelle as a very simple interactive proof assistant. As examples we consider Pelletier's problems 1-46.

Reference: Programming and Verifying a Declarative First-Order Prover in Isabelle/HOL. Alexander Birch Jensen, John Bruntse Larsen, Anders Schlichtkrull & Jørgen Villadsen. AI Communications 31:281-299 2018. https://content.iospress.com/articles/ai-communications/aic764

See also: Students' Proof Assistant (SPA). https://github.com/logic-tools/spa

extra-history = Change history: [2018-07-21]: Proof of Pelletier's problem 34 (Andrews's Challenge) thanks to Asta Halkjær From. [Bernoulli] title = Bernoulli Numbers author = Lukas Bulwahn, Manuel Eberl topic = Mathematics/Analysis, Mathematics/Number theory date = 2017-01-24 notify = eberlm@in.tum.de abstract =

Bernoulli numbers were first discovered in the closed-form expansion of the sum 1m + 2m + … + nm for a fixed m and appear in many other places. This entry provides three different definitions for them: a recursive one, an explicit one, and one through their exponential generating function.

In addition, we prove some basic facts, e.g. their relation to sums of powers of integers and that all odd Bernoulli numbers except the first are zero, and some advanced facts like their relationship to the Riemann zeta function on positive even integers.

We also prove the correctness of the Akiyama–Tanigawa algorithm for computing Bernoulli numbers with reasonable efficiency, and we define the periodic Bernoulli polynomials (which appear e.g. in the Euler–MacLaurin summation formula and the expansion of the log-Gamma function) and prove their basic properties.

[Stone_Relation_Algebras] title = Stone Relation Algebras author = Walter Guttmann topic = Mathematics/Algebra date = 2017-02-07 notify = walter.guttmann@canterbury.ac.nz abstract = We develop Stone relation algebras, which generalise relation algebras by replacing the underlying Boolean algebra structure with a Stone algebra. We show that finite matrices over extended real numbers form an instance. As a consequence, relation-algebraic concepts and methods can be used for reasoning about weighted graphs. We also develop a fixpoint calculus and apply it to compare different definitions of reflexive-transitive closures in semirings. [Stone_Kleene_Relation_Algebras] title = Stone-Kleene Relation Algebras author = Walter Guttmann topic = Mathematics/Algebra date = 2017-07-06 notify = walter.guttmann@canterbury.ac.nz abstract = We develop Stone-Kleene relation algebras, which expand Stone relation algebras with a Kleene star operation to describe reachability in weighted graphs. Many properties of the Kleene star arise as a special case of a more general theory of iteration based on Conway semirings extended by simulation axioms. This includes several theorems representing complex program transformations. We formally prove the correctness of Conway's automata-based construction of the Kleene star of a matrix. We prove numerous results useful for reasoning about weighted graphs. [Abstract_Soundness] title = Abstract Soundness author = Jasmin Christian Blanchette , Andrei Popescu , Dmitriy Traytel topic = Logic/Proof theory date = 2017-02-10 notify = jasmin.blanchette@gmail.com abstract = A formalized coinductive account of the abstract development of Brotherston, Gorogiannis, and Petersen [APLAS 2012], in a slightly more general form since we work with arbitrary infinite proofs, which may be acyclic. This work is described in detail in an article by the authors, published in 2017 in the Journal of Automated Reasoning. The abstract proof can be instantiated for various formalisms, including first-order logic with inductive predicates. [Differential_Dynamic_Logic] title = Differential Dynamic Logic author = Brandon Bohrer topic = Logic/General logic/Modal logic, Computer science/Programming languages/Logics date = 2017-02-13 notify = bbohrer@cs.cmu.edu abstract = We formalize differential dynamic logic, a logic for proving properties of hybrid systems. The proof calculus in this formalization is based on the uniform substitution principle. We show it is sound with respect to our denotational semantics, which provides increased confidence in the correctness of the KeYmaera X theorem prover based on this calculus. As an application, we include a proof term checker embedded in Isabelle/HOL with several example proofs. Published in: Brandon Bohrer, Vincent Rahli, Ivana Vukotic, Marcus Völp, André Platzer: Formally verified differential dynamic logic. CPP 2017. [Syntax_Independent_Logic] title = Syntax-Independent Logic Infrastructure author = Andrei Popescu , Dmitriy Traytel topic = Logic/Proof theory date = 2020-09-16 notify = a.popescu@sheffield.ac.uk, traytel@di.ku.dk abstract = We formalize a notion of logic whose terms and formulas are kept abstract. In particular, logical connectives, substitution, free variables, and provability are not defined, but characterized by their general properties as locale assumptions. Based on this abstract characterization, we develop further reusable reasoning infrastructure. For example, we define parallel substitution (along with proving its characterizing theorems) from single-point substitution. Similarly, we develop a natural deduction style proof system starting from the abstract Hilbert-style one. These one-time efforts benefit different concrete logics satisfying our locales' assumptions. We instantiate the syntax-independent logic infrastructure to Robinson arithmetic (also known as Q) in the AFP entry Robinson_Arithmetic and to hereditarily finite set theory in the AFP entries Goedel_HFSet_Semantic and Goedel_HFSet_Semanticless, which are part of our formalization of Gödel's Incompleteness Theorems described in our CADE-27 paper A Formally Verified Abstract Account of Gödel's Incompleteness Theorems. [Goedel_Incompleteness] title = An Abstract Formalization of Gödel's Incompleteness Theorems author = Andrei Popescu , Dmitriy Traytel topic = Logic/Proof theory date = 2020-09-16 notify = a.popescu@sheffield.ac.uk, traytel@di.ku.dk abstract = We present an abstract formalization of Gödel's incompleteness theorems. We analyze sufficient conditions for the theorems' applicability to a partially specified logic. Our abstract perspective enables a comparison between alternative approaches from the literature. These include Rosser's variation of the first theorem, Jeroslow's variation of the second theorem, and the Swierczkowski–Paulson semantics-based approach. This AFP entry is the main entry point to the results described in our CADE-27 paper A Formally Verified Abstract Account of Gödel's Incompleteness Theorems. As part of our abstract formalization's validation, we instantiate our locales twice in the separate AFP entries Goedel_HFSet_Semantic and Goedel_HFSet_Semanticless. [Goedel_HFSet_Semantic] title = From Abstract to Concrete Gödel's Incompleteness Theorems—Part I author = Andrei Popescu , Dmitriy Traytel topic = Logic/Proof theory date = 2020-09-16 notify = a.popescu@sheffield.ac.uk, traytel@di.ku.dk abstract = We validate an abstract formulation of Gödel's First and Second Incompleteness Theorems from a separate AFP entry by instantiating them to the case of finite sound extensions of the Hereditarily Finite (HF) Set theory, i.e., FOL theories extending the HF Set theory with a finite set of axioms that are sound in the standard model. The concrete results had been previously formalised in an AFP entry by Larry Paulson; our instantiation reuses the infrastructure developed in that entry. [Goedel_HFSet_Semanticless] title = From Abstract to Concrete Gödel's Incompleteness Theorems—Part II author = Andrei Popescu , Dmitriy Traytel topic = Logic/Proof theory date = 2020-09-16 notify = a.popescu@sheffield.ac.uk, traytel@di.ku.dk abstract = We validate an abstract formulation of Gödel's Second Incompleteness Theorem from a separate AFP entry by instantiating it to the case of finite consistent extensions of the Hereditarily Finite (HF) Set theory, i.e., consistent FOL theories extending the HF Set theory with a finite set of axioms. The instantiation draws heavily on infrastructure previously developed by Larry Paulson in his direct formalisation of the concrete result. It strengthens Paulson's formalization of Gödel's Second from that entry by not assuming soundness, and in fact not relying on any notion of model or semantic interpretation. The strengthening was obtained by first replacing some of Paulson’s semantic arguments with proofs within his HF calculus, and then plugging in some of Paulson's (modified) lemmas to instantiate our soundness-free Gödel's Second locale. [Robinson_Arithmetic] title = Robinson Arithmetic author = Andrei Popescu , Dmitriy Traytel topic = Logic/Proof theory date = 2020-09-16 notify = a.popescu@sheffield.ac.uk, traytel@di.ku.dk abstract = We instantiate our syntax-independent logic infrastructure developed in a separate AFP entry to the FOL theory of Robinson arithmetic (also known as Q). The latter was formalised using Nominal Isabelle by adapting Larry Paulson’s formalization of the Hereditarily Finite Set theory. [Elliptic_Curves_Group_Law] title = The Group Law for Elliptic Curves author = Stefan Berghofer topic = Computer science/Security/Cryptography date = 2017-02-28 notify = berghofe@in.tum.de abstract = We prove the group law for elliptic curves in Weierstrass form over fields of characteristic greater than 2. In addition to affine coordinates, we also formalize projective coordinates, which allow for more efficient computations. By specializing the abstract formalization to prime fields, we can apply the curve operations to parameters used in standard security protocols. [Example-Submission] title = Example Submission author = Gerwin Klein topic = Mathematics/Analysis, Mathematics/Number theory date = 2004-02-25 notify = kleing@cse.unsw.edu.au abstract =

This is an example submission to the Archive of Formal Proofs. It shows submission requirements and explains the structure of a simple typical submission.

Note that you can use HTML tags and LaTeX formulae like $\sum_{n=1}^\infty \frac{1}{n^2} = \frac{\pi^2}{6}$ in the abstract. Display formulae like $$ \int_0^1 x^{-x}\,\text{d}x = \sum_{n=1}^\infty n^{-n}$$ are also possible. Please read the submission guidelines before using this.

extra-no-index = no-index: true [CRDT] title = A framework for establishing Strong Eventual Consistency for Conflict-free Replicated Datatypes author = Victor B. F. Gomes , Martin Kleppmann, Dominic P. Mulligan, Alastair R. Beresford topic = Computer science/Algorithms/Distributed, Computer science/Data structures date = 2017-07-07 notify = vb358@cam.ac.uk, dominic.p.mulligan@googlemail.com abstract = In this work, we focus on the correctness of Conflict-free Replicated Data Types (CRDTs), a class of algorithm that provides strong eventual consistency guarantees for replicated data. We develop a modular and reusable framework for verifying the correctness of CRDT algorithms. We avoid correctness issues that have dogged previous mechanised proofs in this area by including a network model in our formalisation, and proving that our theorems hold in all possible network behaviours. Our axiomatic network model is a standard abstraction that accurately reflects the behaviour of real-world computer networks. Moreover, we identify an abstract convergence theorem, a property of order relations, which provides a formal definition of strong eventual consistency. We then obtain the first machine-checked correctness theorems for three concrete CRDTs: the Replicated Growable Array, the Observed-Remove Set, and an Increment-Decrement Counter. [HOLCF-Prelude] title = HOLCF-Prelude author = Joachim Breitner, Brian Huffman<>, Neil Mitchell<>, Christian Sternagel topic = Computer science/Functional programming date = 2017-07-15 notify = c.sternagel@gmail.com, joachim@cis.upenn.edu, hupel@in.tum.de abstract = The Isabelle/HOLCF-Prelude is a formalization of a large part of Haskell's standard prelude in Isabelle/HOLCF. We use it to prove the correctness of the Eratosthenes' Sieve, in its self-referential implementation commonly used to showcase Haskell's laziness; prove correctness of GHC's "fold/build" rule and related rewrite rules; and certify a number of hints suggested by HLint. [Decl_Sem_Fun_PL] title = Declarative Semantics for Functional Languages author = Jeremy Siek topic = Computer science/Programming languages date = 2017-07-21 notify = jsiek@indiana.edu abstract = We present a semantics for an applied call-by-value lambda-calculus that is compositional, extensional, and elementary. We present four different views of the semantics: 1) as a relational (big-step) semantics that is not operational but instead declarative, 2) as a denotational semantics that does not use domain theory, 3) as a non-deterministic interpreter, and 4) as a variant of the intersection type systems of the Torino group. We prove that the semantics is correct by showing that it is sound and complete with respect to operational semantics on programs and that is sound with respect to contextual equivalence. We have not yet investigated whether it is fully abstract. We demonstrate that this approach to semantics is useful with three case studies. First, we use the semantics to prove correctness of a compiler optimization that inlines function application. Second, we adapt the semantics to the polymorphic lambda-calculus extended with general recursion and prove semantic type soundness. Third, we adapt the semantics to the call-by-value lambda-calculus with mutable references.
The paper that accompanies these Isabelle theories is available on arXiv. [DynamicArchitectures] title = Dynamic Architectures author = Diego Marmsoler topic = Computer science/System description languages date = 2017-07-28 notify = diego.marmsoler@tum.de abstract = The architecture of a system describes the system's overall organization into components and connections between those components. With the emergence of mobile computing, dynamic architectures have become increasingly important. In such architectures, components may appear or disappear, and connections may change over time. In the following we mechanize a theory of dynamic architectures and verify the soundness of a corresponding calculus. Therefore, we first formalize the notion of configuration traces as a model for dynamic architectures. Then, the behavior of single components is formalized in terms of behavior traces and an operator is introduced and studied to extract the behavior of a single component out of a given configuration trace. Then, behavior trace assertions are introduced as a temporal specification technique to specify behavior of components. Reasoning about component behavior in a dynamic context is formalized in terms of a calculus for dynamic architectures. Finally, the soundness of the calculus is verified by introducing an alternative interpretation for behavior trace assertions over configuration traces and proving the rules of the calculus. Since projection may lead to finite as well as infinite behavior traces, they are formalized in terms of coinductive lists. Thus, our theory is based on Lochbihler's formalization of coinductive lists. The theory may be applied to verify properties for dynamic architectures. extra-history = Change history: [2018-06-07]: adding logical operators to specify configuration traces (revision 09178f08f050)
[Stewart_Apollonius] title = Stewart's Theorem and Apollonius' Theorem author = Lukas Bulwahn topic = Mathematics/Geometry date = 2017-07-31 notify = lukas.bulwahn@gmail.com abstract = This entry formalizes the two geometric theorems, Stewart's and Apollonius' theorem. Stewart's Theorem relates the length of a triangle's cevian to the lengths of the triangle's two sides. Apollonius' Theorem is a specialisation of Stewart's theorem, restricting the cevian to be the median. The proof applies the law of cosines, some basic geometric facts about triangles and then simply transforms the terms algebraically to yield the conjectured relation. The formalization in Isabelle can closely follow the informal proofs described in the Wikipedia articles of those two theorems. [LambdaMu] title = The LambdaMu-calculus author = Cristina Matache , Victor B. F. Gomes , Dominic P. Mulligan topic = Computer science/Programming languages/Lambda calculi, Logic/General logic/Lambda calculus date = 2017-08-16 notify = victorborgesfg@gmail.com, dominic.p.mulligan@googlemail.com abstract = The propositions-as-types correspondence is ordinarily presented as linking the metatheory of typed λ-calculi and the proof theory of intuitionistic logic. Griffin observed that this correspondence could be extended to classical logic through the use of control operators. This observation set off a flurry of further research, leading to the development of Parigots λμ-calculus. In this work, we formalise λμ- calculus in Isabelle/HOL and prove several metatheoretical properties such as type preservation and progress. [Orbit_Stabiliser] title = Orbit-Stabiliser Theorem with Application to Rotational Symmetries author = Jonas Rädle topic = Mathematics/Algebra date = 2017-08-20 notify = jonas.raedle@tum.de abstract = The Orbit-Stabiliser theorem is a basic result in the algebra of groups that factors the order of a group into the sizes of its orbits and stabilisers. We formalize the notion of a group action and the related concepts of orbits and stabilisers. This allows us to prove the orbit-stabiliser theorem. In the second part of this work, we formalize the tetrahedral group and use the orbit-stabiliser theorem to prove that there are twelve (orientation-preserving) rotations of the tetrahedron. [PLM] title = Representation and Partial Automation of the Principia Logico-Metaphysica in Isabelle/HOL author = Daniel Kirchner topic = Logic/Philosophical aspects date = 2017-09-17 notify = daniel@ekpyron.org abstract =

We present an embedding of the second-order fragment of the Theory of Abstract Objects as described in Edward Zalta's upcoming work Principia Logico-Metaphysica (PLM) in the automated reasoning framework Isabelle/HOL. The Theory of Abstract Objects is a metaphysical theory that reifies property patterns, as they for example occur in the abstract reasoning of mathematics, as abstract objects and provides an axiomatic framework that allows to reason about these objects. It thereby serves as a fundamental metaphysical theory that can be used to axiomatize and describe a wide range of philosophical objects, such as Platonic forms or Leibniz' concepts, and has the ambition to function as a foundational theory of mathematics. The target theory of our embedding as described in chapters 7-9 of PLM employs a modal relational type theory as logical foundation for which a representation in functional type theory is known to be challenging.

Nevertheless we arrive at a functioning representation of the theory in the functional logic of Isabelle/HOL based on a semantical representation of an Aczel-model of the theory. Based on this representation we construct an implementation of the deductive system of PLM which allows to automatically and interactively find and verify theorems of PLM.

Our work thereby supports the concept of shallow semantical embeddings of logical systems in HOL as a universal tool for logical reasoning as promoted by Christoph Benzmüller.

The most notable result of the presented work is the discovery of a previously unknown paradox in the formulation of the Theory of Abstract Objects. The embedding of the theory in Isabelle/HOL played a vital part in this discovery. Furthermore it was possible to immediately offer several options to modify the theory to guarantee its consistency. Thereby our work could provide a significant contribution to the development of a proper grounding for object theory.

[KD_Tree] title = Multidimensional Binary Search Trees author = Martin Rau<> topic = Computer science/Data structures date = 2019-05-30 notify = martin.rau@tum.de, mrtnrau@googlemail.com abstract = This entry provides a formalization of multidimensional binary trees, also known as k-d trees. It includes a balanced build algorithm as well as the nearest neighbor algorithm and the range search algorithm. It is based on the papers Multidimensional binary search trees used for associative searching and An Algorithm for Finding Best Matches in Logarithmic Expected Time. extra-history = Change history: [2020-15-04]: Change representation of k-dimensional points from 'list' to HOL-Analysis.Finite_Cartesian_Product 'vec'. Update proofs to incorporate HOL-Analysis 'dist' and 'cbox' primitives. [Closest_Pair_Points] title = Closest Pair of Points Algorithms author = Martin Rau , Tobias Nipkow topic = Computer science/Algorithms/Geometry date = 2020-01-13 notify = martin.rau@tum.de, nipkow@in.tum.de abstract = This entry provides two related verified divide-and-conquer algorithms solving the fundamental Closest Pair of Points problem in Computational Geometry. Functional correctness and the optimal running time of O(n log n) are proved. Executable code is generated which is empirically competitive with handwritten reference implementations. extra-history = Change history: [2020-14-04]: Incorporate Time_Monad of the AFP entry Root_Balanced_Tree. [Approximation_Algorithms] title = Verified Approximation Algorithms author = Robin Eßmann , Tobias Nipkow , Simon Robillard topic = Computer science/Algorithms/Approximation date = 2020-01-16 notify = nipkow@in.tum.de abstract = We present the first formal verification of approximation algorithms for NP-complete optimization problems: vertex cover, independent set, load balancing, and bin packing. The proofs correct incompletenesses in existing proofs and improve the approximation ratio in one case. [Diophantine_Eqns_Lin_Hom] title = Homogeneous Linear Diophantine Equations author = Florian Messner , Julian Parsert , Jonas Schöpf , Christian Sternagel topic = Computer science/Algorithms/Mathematical, Mathematics/Number theory, Tools license = LGPL date = 2017-10-14 notify = c.sternagel@gmail.com, julian.parsert@gmail.com abstract = We formalize the theory of homogeneous linear diophantine equations, focusing on two main results: (1) an abstract characterization of minimal complete sets of solutions, and (2) an algorithm computing them. Both, the characterization and the algorithm are based on previous work by Huet. Our starting point is a simple but inefficient variant of Huet's lexicographic algorithm incorporating improved bounds due to Clausen and Fortenbacher. We proceed by proving its soundness and completeness. Finally, we employ code equations to obtain a reasonably efficient implementation. Thus, we provide a formally verified solver for homogeneous linear diophantine equations. [Winding_Number_Eval] title = Evaluate Winding Numbers through Cauchy Indices author = Wenda Li topic = Mathematics/Analysis date = 2017-10-17 notify = wl302@cam.ac.uk, liwenda1990@hotmail.com abstract = In complex analysis, the winding number measures the number of times a path (counterclockwise) winds around a point, while the Cauchy index can approximate how the path winds. This entry provides a formalisation of the Cauchy index, which is then shown to be related to the winding number. In addition, this entry also offers a tactic that enables users to evaluate the winding number by calculating Cauchy indices. [Count_Complex_Roots] title = Count the Number of Complex Roots author = Wenda Li topic = Mathematics/Analysis date = 2017-10-17 notify = wl302@cam.ac.uk, liwenda1990@hotmail.com abstract = Based on evaluating Cauchy indices through remainder sequences, this entry provides an effective procedure to count the number of complex roots (with multiplicity) of a polynomial within a rectangle box or a half-plane. Potential applications of this entry include certified complex root isolation (of a polynomial) and testing the Routh-Hurwitz stability criterion (i.e., to check whether all the roots of some characteristic polynomial have negative real parts). [Buchi_Complementation] title = Büchi Complementation author = Julian Brunner topic = Computer science/Automata and formal languages date = 2017-10-19 notify = brunnerj@in.tum.de abstract = This entry provides a verified implementation of rank-based Büchi Complementation. The verification is done in three steps:
  1. Definition of odd rankings and proof that an automaton rejects a word iff there exists an odd ranking for it.
  2. Definition of the complement automaton and proof that it accepts exactly those words for which there is an odd ranking.
  3. Verified implementation of the complement automaton using the Isabelle Collections Framework.
[Transition_Systems_and_Automata] title = Transition Systems and Automata author = Julian Brunner topic = Computer science/Automata and formal languages date = 2017-10-19 notify = brunnerj@in.tum.de abstract = This entry provides a very abstract theory of transition systems that can be instantiated to express various types of automata. A transition system is typically instantiated by providing a set of initial states, a predicate for enabled transitions, and a transition execution function. From this, it defines the concepts of finite and infinite paths as well as the set of reachable states, among other things. Many useful theorems, from basic path manipulation rules to coinduction and run construction rules, are proven in this abstract transition system context. The library comes with instantiations for DFAs, NFAs, and Büchi automata. [Kuratowski_Closure_Complement] title = The Kuratowski Closure-Complement Theorem author = Peter Gammie , Gianpaolo Gioiosa<> topic = Mathematics/Topology date = 2017-10-26 notify = peteg42@gmail.com abstract = We discuss a topological curiosity discovered by Kuratowski (1922): the fact that the number of distinct operators on a topological space generated by compositions of closure and complement never exceeds 14, and is exactly 14 in the case of R. In addition, we prove a theorem due to Chagrov (1982) that classifies topological spaces according to the number of such operators they support. [Hybrid_Multi_Lane_Spatial_Logic] title = Hybrid Multi-Lane Spatial Logic author = Sven Linker topic = Logic/General logic/Modal logic date = 2017-11-06 notify = s.linker@liverpool.ac.uk abstract = We present a semantic embedding of a spatio-temporal multi-modal logic, specifically defined to reason about motorway traffic, into Isabelle/HOL. The semantic model is an abstraction of a motorway, emphasising local spatial properties, and parameterised by the types of sensors deployed in the vehicles. We use the logic to define controller constraints to ensure safety, i.e., the absence of collisions on the motorway. After proving safety with a restrictive definition of sensors, we relax these assumptions and show how to amend the controller constraints to still guarantee safety. [Dirichlet_L] title = Dirichlet L-Functions and Dirichlet's Theorem author = Manuel Eberl topic = Mathematics/Number theory, Mathematics/Algebra date = 2017-12-21 notify = eberlm@in.tum.de abstract =

This article provides a formalisation of Dirichlet characters and Dirichlet L-functions including proofs of their basic properties – most notably their analyticity, their areas of convergence, and their non-vanishing for ℜ(s) ≥ 1. All of this is built in a very high-level style using Dirichlet series. The proof of the non-vanishing follows a very short and elegant proof by Newman, which we attempt to reproduce faithfully in a similar level of abstraction in Isabelle.

This also leads to a relatively short proof of Dirichlet’s Theorem, which states that, if h and n are coprime, there are infinitely many primes p with ph (mod n).

[Symmetric_Polynomials] title = Symmetric Polynomials author = Manuel Eberl topic = Mathematics/Algebra date = 2018-09-25 notify = eberlm@in.tum.de abstract =

A symmetric polynomial is a polynomial in variables X1,…,Xn that does not discriminate between its variables, i. e. it is invariant under any permutation of them. These polynomials are important in the study of the relationship between the coefficients of a univariate polynomial and its roots in its algebraic closure.

This article provides a definition of symmetric polynomials and the elementary symmetric polynomials e1,…,en and proofs of their basic properties, including three notable ones:

  • Vieta's formula, which gives an explicit expression for the k-th coefficient of a univariate monic polynomial in terms of its roots x1,…,xn, namely ck = (-1)n-k en-k(x1,…,xn).
  • Second, the Fundamental Theorem of Symmetric Polynomials, which states that any symmetric polynomial is itself a uniquely determined polynomial combination of the elementary symmetric polynomials.
  • Third, as a corollary of the previous two, that given a polynomial over some ring R, any symmetric polynomial combination of its roots is also in R even when the roots are not.

Both the symmetry property itself and the witness for the Fundamental Theorem are executable.

[Taylor_Models] title = Taylor Models author = Christoph Traut<>, Fabian Immler topic = Computer science/Algorithms/Mathematical, Computer science/Data structures, Mathematics/Analysis, Mathematics/Algebra date = 2018-01-08 notify = immler@in.tum.de abstract = We present a formally verified implementation of multivariate Taylor models. Taylor models are a form of rigorous polynomial approximation, consisting of an approximation polynomial based on Taylor expansions, combined with a rigorous bound on the approximation error. Taylor models were introduced as a tool to mitigate the dependency problem of interval arithmetic. Our implementation automatically computes Taylor models for the class of elementary functions, expressed by composition of arithmetic operations and basic functions like exp, sin, or square root. [Green] title = An Isabelle/HOL formalisation of Green's Theorem author = Mohammad Abdulaziz , Lawrence C. Paulson topic = Mathematics/Analysis date = 2018-01-11 notify = mohammad.abdulaziz8@gmail.com, lp15@cam.ac.uk abstract = We formalise a statement of Green’s theorem—the first formalisation to our knowledge—in Isabelle/HOL. The theorem statement that we formalise is enough for most applications, especially in physics and engineering. Our formalisation is made possible by a novel proof that avoids the ubiquitous line integral cancellation argument. This eliminates the need to formalise orientations and region boundaries explicitly with respect to the outwards-pointing normal vector. Instead we appeal to a homological argument about equivalences between paths. [AI_Planning_Languages_Semantics] title = AI Planning Languages Semantics author = Mohammad Abdulaziz , Peter Lammich topic = Computer science/Artificial intelligence date = 2020-10-29 notify = mohammad.abdulaziz8@gmail.com abstract = This is an Isabelle/HOL formalisation of the semantics of the multi-valued planning tasks language that is used by the planning system Fast-Downward, the STRIPS fragment of the Planning Domain Definition Language (PDDL), and the STRIPS soundness meta-theory developed by Vladimir Lifschitz. It also contains formally verified checkers for checking the well-formedness of problems specified in either language as well the correctness of potential solutions. The formalisation in this entry was described in an earlier publication. [Verified_SAT_Based_AI_Planning] title = Verified SAT-Based AI Planning author = Mohammad Abdulaziz , Friedrich Kurz <> topic = Computer science/Artificial intelligence date = 2020-10-29 notify = mohammad.abdulaziz8@gmail.com abstract = We present an executable formally verified SAT encoding of classical AI planning that is based on the encodings by Kautz and Selman and the one by Rintanen et al. The encoding was experimentally tested and shown to be usable for reasonably sized standard AI planning benchmarks. We also use it as a reference to test a state-of-the-art SAT-based planner, showing that it sometimes falsely claims that problems have no solutions of certain lengths. The formalisation in this submission was described in an independent publication. [Gromov_Hyperbolicity] title = Gromov Hyperbolicity author = Sebastien Gouezel<> topic = Mathematics/Geometry date = 2018-01-16 notify = sebastien.gouezel@univ-rennes1.fr abstract = A geodesic metric space is Gromov hyperbolic if all its geodesic triangles are thin, i.e., every side is contained in a fixed thickening of the two other sides. While this definition looks innocuous, it has proved extremely important and versatile in modern geometry since its introduction by Gromov. We formalize the basic classical properties of Gromov hyperbolic spaces, notably the Morse lemma asserting that quasigeodesics are close to geodesics, the invariance of hyperbolicity under quasi-isometries, we define and study the Gromov boundary and its associated distance, and prove that a quasi-isometry between Gromov hyperbolic spaces extends to a homeomorphism of the boundaries. We also prove a less classical theorem, by Bonk and Schramm, asserting that a Gromov hyperbolic space embeds isometrically in a geodesic Gromov-hyperbolic space. As the original proof uses a transfinite sequence of Cauchy completions, this is an interesting formalization exercise. Along the way, we introduce basic material on isometries, quasi-isometries, Lipschitz maps, geodesic spaces, the Hausdorff distance, the Cauchy completion of a metric space, and the exponential on extended real numbers. [Ordered_Resolution_Prover] title = Formalization of Bachmair and Ganzinger's Ordered Resolution Prover author = Anders Schlichtkrull , Jasmin Christian Blanchette , Dmitriy Traytel , Uwe Waldmann topic = Logic/General logic/Mechanization of proofs date = 2018-01-18 notify = andschl@dtu.dk, j.c.blanchette@vu.nl abstract = This Isabelle/HOL formalization covers Sections 2 to 4 of Bachmair and Ganzinger's "Resolution Theorem Proving" chapter in the Handbook of Automated Reasoning. This includes soundness and completeness of unordered and ordered variants of ground resolution with and without literal selection, the standard redundancy criterion, a general framework for refutational theorem proving, and soundness and completeness of an abstract first-order prover. [Chandy_Lamport] title = A Formal Proof of The Chandy--Lamport Distributed Snapshot Algorithm author = Ben Fiedler , Dmitriy Traytel topic = Computer science/Algorithms/Distributed date = 2020-07-21 notify = ben.fiedler@inf.ethz.ch, traytel@inf.ethz.ch abstract = We provide a suitable distributed system model and implementation of the Chandy--Lamport distributed snapshot algorithm [ACM Transactions on Computer Systems, 3, 63-75, 1985]. Our main result is a formal termination and correctness proof of the Chandy--Lamport algorithm and its use in stable property detection. [BNF_Operations] title = Operations on Bounded Natural Functors author = Jasmin Christian Blanchette , Andrei Popescu , Dmitriy Traytel topic = Tools date = 2017-12-19 notify = jasmin.blanchette@gmail.com,uuomul@yahoo.com,traytel@inf.ethz.ch abstract = This entry formalizes the closure property of bounded natural functors (BNFs) under seven operations. These operations and the corresponding proofs constitute the core of Isabelle's (co)datatype package. To be close to the implemented tactics, the proofs are deliberately formulated as detailed apply scripts. The (co)datatypes together with (co)induction principles and (co)recursors are byproducts of the fixpoint operations LFP and GFP. Composition of BNFs is subdivided into four simpler operations: Compose, Kill, Lift, and Permute. The N2M operation provides mutual (co)induction principles and (co)recursors for nested (co)datatypes. [LLL_Basis_Reduction] title = A verified LLL algorithm author = Ralph Bottesch <>, Jose Divasón , Maximilian Haslbeck , Sebastiaan Joosten , René Thiemann , Akihisa Yamada<> topic = Computer science/Algorithms/Mathematical, Mathematics/Algebra date = 2018-02-02 notify = ralph.bottesch@uibk.ac.at, jose.divason@unirioja.es, maximilian.haslbeck@uibk.ac.at, s.j.c.joosten@utwente.nl, rene.thiemann@uibk.ac.at, ayamada@trs.cm.is.nagoya-u.ac.jp abstract = The Lenstra-Lenstra-Lovász basis reduction algorithm, also known as LLL algorithm, is an algorithm to find a basis with short, nearly orthogonal vectors of an integer lattice. Thereby, it can also be seen as an approximation to solve the shortest vector problem (SVP), which is an NP-hard problem, where the approximation quality solely depends on the dimension of the lattice, but not the lattice itself. The algorithm also possesses many applications in diverse fields of computer science, from cryptanalysis to number theory, but it is specially well-known since it was used to implement the first polynomial-time algorithm to factor polynomials. In this work we present the first mechanized soundness proof of the LLL algorithm to compute short vectors in lattices. The formalization follows a textbook by von zur Gathen and Gerhard. extra-history = Change history: [2018-04-16]: Integrated formal complexity bounds (Haslbeck, Thiemann) [2018-05-25]: Integrated much faster LLL implementation based on integer arithmetic (Bottesch, Haslbeck, Thiemann) [LLL_Factorization] title = A verified factorization algorithm for integer polynomials with polynomial complexity author = Jose Divasón , Sebastiaan Joosten , René Thiemann , Akihisa Yamada topic = Mathematics/Algebra date = 2018-02-06 notify = jose.divason@unirioja.es, s.j.c.joosten@utwente.nl, rene.thiemann@uibk.ac.at, ayamada@trs.cm.is.nagoya-u.ac.jp abstract = Short vectors in lattices and factors of integer polynomials are related. Each factor of an integer polynomial belongs to a certain lattice. When factoring polynomials, the condition that we are looking for an irreducible polynomial means that we must look for a small element in a lattice, which can be done by a basis reduction algorithm. In this development we formalize this connection and thereby one main application of the LLL basis reduction algorithm: an algorithm to factor square-free integer polynomials which runs in polynomial time. The work is based on our previous Berlekamp–Zassenhaus development, where the exponential reconstruction phase has been replaced by the polynomial-time basis reduction algorithm. Thanks to this formalization we found a serious flaw in a textbook. [Treaps] title = Treaps author = Maximilian Haslbeck , Manuel Eberl , Tobias Nipkow topic = Computer science/Data structures date = 2018-02-06 notify = eberlm@in.tum.de abstract =

A Treap is a binary tree whose nodes contain pairs consisting of some payload and an associated priority. It must have the search-tree property w.r.t. the payloads and the heap property w.r.t. the priorities. Treaps are an interesting data structure that is related to binary search trees (BSTs) in the following way: if one forgets all the priorities of a treap, the resulting BST is exactly the same as if one had inserted the elements into an empty BST in order of ascending priority. This means that a treap behaves like a BST where we can pretend the elements were inserted in a different order from the one in which they were actually inserted.

In particular, by choosing these priorities at random upon insertion of an element, we can pretend that we inserted the elements in random order, so that the shape of the resulting tree is that of a random BST no matter in what order we insert the elements. This is the main result of this formalisation.

[Skip_Lists] title = Skip Lists author = Max W. Haslbeck , Manuel Eberl topic = Computer science/Data structures date = 2020-01-09 notify = max.haslbeck@gmx.de abstract =

Skip lists are sorted linked lists enhanced with shortcuts and are an alternative to binary search trees. A skip lists consists of multiple levels of sorted linked lists where a list on level n is a subsequence of the list on level n − 1. In the ideal case, elements are skipped in such a way that a lookup in a skip lists takes O(log n) time. In a randomised skip list the skipped elements are choosen randomly.

This entry contains formalized proofs of the textbook results about the expected height and the expected length of a search path in a randomised skip list.

[Mersenne_Primes] title = Mersenne primes and the Lucas–Lehmer test author = Manuel Eberl topic = Mathematics/Number theory date = 2020-01-17 notify = eberlm@in.tum.de abstract =

This article provides formal proofs of basic properties of Mersenne numbers, i. e. numbers of the form 2n - 1, and especially of Mersenne primes.

In particular, an efficient, verified, and executable version of the Lucas–Lehmer test is developed. This test decides primality for Mersenne numbers in time polynomial in n.

[Hoare_Time] title = Hoare Logics for Time Bounds author = Maximilian P. L. Haslbeck , Tobias Nipkow topic = Computer science/Programming languages/Logics date = 2018-02-26 notify = haslbema@in.tum.de abstract = We study three different Hoare logics for reasoning about time bounds of imperative programs and formalize them in Isabelle/HOL: a classical Hoare like logic due to Nielson, a logic with potentials due to Carbonneaux et al. and a separation logic following work by Atkey, Chaguérand and Pottier. These logics are formally shown to be sound and complete. Verification condition generators are developed and are shown sound and complete too. We also consider variants of the systems where we abstract from multiplicative constants in the running time bounds, thus supporting a big-O style of reasoning. Finally we compare the expressive power of the three systems. [Architectural_Design_Patterns] title = A Theory of Architectural Design Patterns author = Diego Marmsoler topic = Computer science/System description languages date = 2018-03-01 notify = diego.marmsoler@tum.de abstract = The following document formalizes and verifies several architectural design patterns. Each pattern specification is formalized in terms of a locale where the locale assumptions correspond to the assumptions which a pattern poses on an architecture. Thus, pattern specifications may build on top of each other by interpreting the corresponding locale. A pattern is verified using the framework provided by the AFP entry Dynamic Architectures. Currently, the document consists of formalizations of 4 different patterns: the singleton, the publisher subscriber, the blackboard pattern, and the blockchain pattern. Thereby, the publisher component of the publisher subscriber pattern is modeled as an instance of the singleton pattern and the blackboard pattern is modeled as an instance of the publisher subscriber pattern. In general, this entry provides the first steps towards an overall theory of architectural design patterns. extra-history = Change history: [2018-05-25]: changing the major assumption for blockchain architectures from alternative minings to relative mining frequencies (revision 5043c5c71685)
[2019-04-08]: adapting the terminology: honest instead of trusted, dishonest instead of untrusted (revision 7af3431a22ae) [Weight_Balanced_Trees] title = Weight-Balanced Trees author = Tobias Nipkow , Stefan Dirix<> topic = Computer science/Data structures date = 2018-03-13 notify = nipkow@in.tum.de abstract = This theory provides a verified implementation of weight-balanced trees following the work of Hirai and Yamamoto who proved that all parameters in a certain range are valid, i.e. guarantee that insertion and deletion preserve weight-balance. Instead of a general theorem we provide parameterized proofs of preservation of the invariant that work for many (all?) valid parameters. [Fishburn_Impossibility] title = The Incompatibility of Fishburn-Strategyproofness and Pareto-Efficiency author = Felix Brandt , Manuel Eberl , Christian Saile , Christian Stricker topic = Mathematics/Games and economics date = 2018-03-22 notify = eberlm@in.tum.de abstract =

This formalisation contains the proof that there is no anonymous Social Choice Function for at least three agents and alternatives that fulfils both Pareto-Efficiency and Fishburn-Strategyproofness. It was derived from a proof of Brandt et al., which relies on an unverified translation of a fixed finite instance of the original problem to SAT. This Isabelle proof contains a machine-checked version of both the statement for exactly three agents and alternatives and the lifting to the general case.

[BNF_CC] title = Bounded Natural Functors with Covariance and Contravariance author = Andreas Lochbihler , Joshua Schneider topic = Computer science/Functional programming, Tools date = 2018-04-24 notify = mail@andreas-lochbihler.de, joshua.schneider@inf.ethz.ch abstract = Bounded natural functors (BNFs) provide a modular framework for the construction of (co)datatypes in higher-order logic. Their functorial operations, the mapper and relator, are restricted to a subset of the parameters, namely those where recursion can take place. For certain applications, such as free theorems, data refinement, quotients, and generalised rewriting, it is desirable that these operations do not ignore the other parameters. In this article, we formalise the generalisation BNFCC that extends the mapper and relator to covariant and contravariant parameters. We show that
  1. BNFCCs are closed under functor composition and least and greatest fixpoints,
  2. subtypes inherit the BNFCC structure under conditions that generalise those for the BNF case, and
  3. BNFCCs preserve quotients under mild conditions.
These proofs are carried out for abstract BNFCCs similar to the AFP entry BNF Operations. In addition, we apply the BNFCC theory to several concrete functors. [Modular_Assembly_Kit_Security] title = An Isabelle/HOL Formalization of the Modular Assembly Kit for Security Properties author = Oliver Bračevac , Richard Gay , Sylvia Grewe , Heiko Mantel , Henning Sudbrock , Markus Tasch topic = Computer science/Security date = 2018-05-07 notify = tasch@mais.informatik.tu-darmstadt.de abstract = The "Modular Assembly Kit for Security Properties" (MAKS) is a framework for both the definition and verification of possibilistic information-flow security properties at the specification-level. MAKS supports the uniform representation of a wide range of possibilistic information-flow properties and provides support for the verification of such properties via unwinding results and compositionality results. We provide a formalization of this framework in Isabelle/HOL. [AxiomaticCategoryTheory] title = Axiom Systems for Category Theory in Free Logic author = Christoph Benzmüller , Dana Scott topic = Mathematics/Category theory date = 2018-05-23 notify = c.benzmueller@gmail.com abstract = This document provides a concise overview on the core results of our previous work on the exploration of axioms systems for category theory. Extending the previous studies (http://arxiv.org/abs/1609.01493) we include one further axiomatic theory in our experiments. This additional theory has been suggested by Mac Lane in 1948. We show that the axioms proposed by Mac Lane are equivalent to the ones we studied before, which includes an axioms set suggested by Scott in the 1970s and another axioms set proposed by Freyd and Scedrov in 1990, which we slightly modified to remedy a minor technical issue. [OpSets] title = OpSets: Sequential Specifications for Replicated Datatypes author = Martin Kleppmann , Victor B. F. Gomes , Dominic P. Mulligan , Alastair R. Beresford topic = Computer science/Algorithms/Distributed, Computer science/Data structures date = 2018-05-10 notify = vb358@cam.ac.uk abstract = We introduce OpSets, an executable framework for specifying and reasoning about the semantics of replicated datatypes that provide eventual consistency in a distributed system, and for mechanically verifying algorithms that implement these datatypes. Our approach is simple but expressive, allowing us to succinctly specify a variety of abstract datatypes, including maps, sets, lists, text, graphs, trees, and registers. Our datatypes are also composable, enabling the construction of complex data structures. To demonstrate the utility of OpSets for analysing replication algorithms, we highlight an important correctness property for collaborative text editing that has traditionally been overlooked; algorithms that do not satisfy this property can exhibit awkward interleaving of text. We use OpSets to specify this correctness property and prove that although one existing replication algorithm satisfies this property, several other published algorithms do not. [Irrationality_J_Hancl] title = Irrational Rapidly Convergent Series author = Angeliki Koutsoukou-Argyraki , Wenda Li topic = Mathematics/Number theory, Mathematics/Analysis date = 2018-05-23 notify = ak2110@cam.ac.uk, wl302@cam.ac.uk abstract = We formalize with Isabelle/HOL a proof of a theorem by J. Hancl asserting the irrationality of the sum of a series consisting of rational numbers, built up by sequences that fulfill certain properties. Even though the criterion is a number theoretic result, the proof makes use only of analytical arguments. We also formalize a corollary of the theorem for a specific series fulfilling the assumptions of the theorem. [Optimal_BST] title = Optimal Binary Search Trees author = Tobias Nipkow , Dániel Somogyi <> topic = Computer science/Algorithms, Computer science/Data structures date = 2018-05-27 notify = nipkow@in.tum.de abstract = This article formalizes recursive algorithms for the construction of optimal binary search trees given fixed access frequencies. We follow Knuth (1971), Yao (1980) and Mehlhorn (1984). The algorithms are memoized with the help of the AFP article Monadification, Memoization and Dynamic Programming, thus yielding dynamic programming algorithms. [Projective_Geometry] title = Projective Geometry author = Anthony Bordg topic = Mathematics/Geometry date = 2018-06-14 notify = apdb3@cam.ac.uk abstract = We formalize the basics of projective geometry. In particular, we give a proof of the so-called Hessenberg's theorem in projective plane geometry. We also provide a proof of the so-called Desargues's theorem based on an axiomatization of (higher) projective space geometry using the notion of rank of a matroid. This last approach allows to handle incidence relations in an homogeneous way dealing only with points and without the need of talking explicitly about lines, planes or any higher entity. [Localization_Ring] title = The Localization of a Commutative Ring author = Anthony Bordg topic = Mathematics/Algebra date = 2018-06-14 notify = apdb3@cam.ac.uk abstract = We formalize the localization of a commutative ring R with respect to a multiplicative subset (i.e. a submonoid of R seen as a multiplicative monoid). This localization is itself a commutative ring and we build the natural homomorphism of rings from R to its localization. [Minsky_Machines] title = Minsky Machines author = Bertram Felgenhauer<> topic = Logic/Computability date = 2018-08-14 notify = int-e@gmx.de abstract =

We formalize undecidablity results for Minsky machines. To this end, we also formalize recursive inseparability.

We start by proving that Minsky machines can compute arbitrary primitive recursive and recursive functions. We then show that there is a deterministic Minsky machine with one argument and two final states such that the set of inputs that are accepted in one state is recursively inseparable from the set of inputs that are accepted in the other state.

As a corollary, the set of Minsky configurations that reach the first state but not the second recursively inseparable from the set of Minsky configurations that reach the second state but not the first. In particular both these sets are undecidable.

We do not prove that recursive functions can simulate Minsky machines.

[Neumann_Morgenstern_Utility] title = Von-Neumann-Morgenstern Utility Theorem author = Julian Parsert, Cezary Kaliszyk topic = Mathematics/Games and economics license = LGPL date = 2018-07-04 notify = julian.parsert@uibk.ac.at, cezary.kaliszyk@uibk.ac.at abstract = Utility functions form an essential part of game theory and economics. In order to guarantee the existence of utility functions most of the time sufficient properties are assumed in an axiomatic manner. One famous and very common set of such assumptions is that of expected utility theory. Here, the rationality, continuity, and independence of preferences is assumed. The von-Neumann-Morgenstern Utility theorem shows that these assumptions are necessary and sufficient for an expected utility function to exists. This theorem was proven by Neumann and Morgenstern in ``Theory of Games and Economic Behavior'' which is regarded as one of the most influential works in game theory. The formalization includes formal definitions of the underlying concepts including continuity and independence of preferences. [Simplex] title = An Incremental Simplex Algorithm with Unsatisfiable Core Generation author = Filip Marić , Mirko Spasić , René Thiemann topic = Computer science/Algorithms/Optimization date = 2018-08-24 notify = rene.thiemann@uibk.ac.at abstract = We present an Isabelle/HOL formalization and total correctness proof for the incremental version of the Simplex algorithm which is used in most state-of-the-art SMT solvers. It supports extraction of satisfying assignments, extraction of minimal unsatisfiable cores, incremental assertion of constraints and backtracking. The formalization relies on stepwise program refinement, starting from a simple specification, going through a number of refinement steps, and ending up in a fully executable functional implementation. Symmetries present in the algorithm are handled with special care. [Budan_Fourier] title = The Budan-Fourier Theorem and Counting Real Roots with Multiplicity author = Wenda Li topic = Mathematics/Analysis date = 2018-09-02 notify = wl302@cam.ac.uk, liwenda1990@hotmail.com abstract = This entry is mainly about counting and approximating real roots (of a polynomial) with multiplicity. We have first formalised the Budan-Fourier theorem: given a polynomial with real coefficients, we can calculate sign variations on Fourier sequences to over-approximate the number of real roots (counting multiplicity) within an interval. When all roots are known to be real, the over-approximation becomes tight: we can utilise this theorem to count real roots exactly. It is also worth noting that Descartes' rule of sign is a direct consequence of the Budan-Fourier theorem, and has been included in this entry. In addition, we have extended previous formalised Sturm's theorem to count real roots with multiplicity, while the original Sturm's theorem only counts distinct real roots. Compared to the Budan-Fourier theorem, our extended Sturm's theorem always counts roots exactly but may suffer from greater computational cost. [Quaternions] title = Quaternions author = Lawrence C. Paulson topic = Mathematics/Algebra, Mathematics/Geometry date = 2018-09-05 notify = lp15@cam.ac.uk abstract = This theory is inspired by the HOL Light development of quaternions, but follows its own route. Quaternions are developed coinductively, as in the existing formalisation of the complex numbers. Quaternions are quickly shown to belong to the type classes of real normed division algebras and real inner product spaces. And therefore they inherit a great body of facts involving algebraic laws, limits, continuity, etc., which must be proved explicitly in the HOL Light version. The development concludes with the geometric interpretation of the product of imaginary quaternions. [Octonions] title = Octonions author = Angeliki Koutsoukou-Argyraki topic = Mathematics/Algebra, Mathematics/Geometry date = 2018-09-14 notify = ak2110@cam.ac.uk abstract = We develop the basic theory of Octonions, including various identities and properties of the octonions and of the octonionic product, a description of 7D isometries and representations of orthogonal transformations. To this end we first develop the theory of the vector cross product in 7 dimensions. The development of the theory of Octonions is inspired by that of the theory of Quaternions by Lawrence Paulson. However, we do not work within the type class real_algebra_1 because the octonionic product is not associative. [Aggregation_Algebras] title = Aggregation Algebras author = Walter Guttmann topic = Mathematics/Algebra date = 2018-09-15 notify = walter.guttmann@canterbury.ac.nz abstract = We develop algebras for aggregation and minimisation for weight matrices and for edge weights in graphs. We verify the correctness of Prim's and Kruskal's minimum spanning tree algorithms based on these algebras. We also show numerous instances of these algebras based on linearly ordered commutative semigroups. [Prime_Number_Theorem] title = The Prime Number Theorem author = Manuel Eberl , Lawrence C. Paulson topic = Mathematics/Number theory date = 2018-09-19 notify = eberlm@in.tum.de abstract =

This article provides a short proof of the Prime Number Theorem in several equivalent forms, most notably π(x) ~ x/ln x where π(x) is the number of primes no larger than x. It also defines other basic number-theoretic functions related to primes like Chebyshev's functions ϑ and ψ and the “n-th prime number” function pn. We also show various bounds and relationship between these functions are shown. Lastly, we derive Mertens' First and Second Theorem, i. e. ∑px ln p/p = ln x + O(1) and ∑px 1/p = ln ln x + M + O(1/ln x). We also give explicit bounds for the remainder terms.

The proof of the Prime Number Theorem builds on a library of Dirichlet series and analytic combinatorics. We essentially follow the presentation by Newman. The core part of the proof is a Tauberian theorem for Dirichlet series, which is proven using complex analysis and then used to strengthen Mertens' First Theorem to ∑px ln p/p = ln x + c + o(1).

A variant of this proof has been formalised before by Harrison in HOL Light, and formalisations of Selberg's elementary proof exist both by Avigad et al. in Isabelle and by Carneiro in Metamath. The advantage of the analytic proof is that, while it requires more powerful mathematical tools, it is considerably shorter and clearer. This article attempts to provide a short and clear formalisation of all components of that proof using the full range of mathematical machinery available in Isabelle, staying as close as possible to Newman's simple paper proof.

[Signature_Groebner] title = Signature-Based Gröbner Basis Algorithms author = Alexander Maletzky topic = Mathematics/Algebra, Computer science/Algorithms/Mathematical date = 2018-09-20 notify = alexander.maletzky@risc.jku.at abstract =

This article formalizes signature-based algorithms for computing Gröbner bases. Such algorithms are, in general, superior to other algorithms in terms of efficiency, and have not been formalized in any proof assistant so far. The present development is both generic, in the sense that most known variants of signature-based algorithms are covered by it, and effectively executable on concrete input thanks to Isabelle's code generator. Sample computations of benchmark problems show that the verified implementation of signature-based algorithms indeed outperforms the existing implementation of Buchberger's algorithm in Isabelle/HOL.

Besides total correctness of the algorithms, the article also proves that under certain conditions they a-priori detect and avoid all useless zero-reductions, and always return 'minimal' (in some sense) Gröbner bases if an input parameter is chosen in the right way.

The formalization follows the recent survey article by Eder and Faugère.

[Factored_Transition_System_Bounding] title = Upper Bounding Diameters of State Spaces of Factored Transition Systems author = Friedrich Kurz <>, Mohammad Abdulaziz topic = Computer science/Automata and formal languages, Mathematics/Graph theory date = 2018-10-12 notify = friedrich.kurz@tum.de, mohammad.abdulaziz@in.tum.de abstract = A completeness threshold is required to guarantee the completeness of planning as satisfiability, and bounded model checking of safety properties. One valid completeness threshold is the diameter of the underlying transition system. The diameter is the maximum element in the set of lengths of all shortest paths between pairs of states. The diameter is not calculated exactly in our setting, where the transition system is succinctly described using a (propositionally) factored representation. Rather, an upper bound on the diameter is calculated compositionally, by bounding the diameters of small abstract subsystems, and then composing those. We port a HOL4 formalisation of a compositional algorithm for computing a relatively tight upper bound on the system diameter. This compositional algorithm exploits acyclicity in the state space to achieve compositionality, and it was introduced by Abdulaziz et. al. The formalisation that we port is described as a part of another paper by Abdulaziz et. al. As a part of this porting we developed a libray about transition systems, which shall be of use in future related mechanisation efforts. [Smooth_Manifolds] title = Smooth Manifolds author = Fabian Immler , Bohua Zhan topic = Mathematics/Analysis, Mathematics/Topology date = 2018-10-22 notify = immler@in.tum.de, bzhan@ios.ac.cn abstract = We formalize the definition and basic properties of smooth manifolds in Isabelle/HOL. Concepts covered include partition of unity, tangent and cotangent spaces, and the fundamental theorem of path integrals. We also examine some concrete manifolds such as spheres and projective spaces. The formalization makes extensive use of the analysis and linear algebra libraries in Isabelle/HOL, in particular its “types-to-sets” mechanism. [Matroids] title = Matroids author = Jonas Keinholz<> topic = Mathematics/Combinatorics date = 2018-11-16 notify = eberlm@in.tum.de abstract =

This article defines the combinatorial structures known as Independence Systems and Matroids and provides basic concepts and theorems related to them. These structures play an important role in combinatorial optimisation, e. g. greedy algorithms such as Kruskal's algorithm. The development is based on Oxley's `What is a Matroid?'.

[Graph_Saturation] title = Graph Saturation author = Sebastiaan J. C. Joosten<> topic = Logic/Rewriting, Mathematics/Graph theory date = 2018-11-23 notify = sjcjoosten@gmail.com abstract = This is an Isabelle/HOL formalisation of graph saturation, closely following a paper by the author on graph saturation. Nine out of ten lemmas of the original paper are proven in this formalisation. The formalisation additionally includes two theorems that show the main premise of the paper: that consistency and entailment are decided through graph saturation. This formalisation does not give executable code, and it did not implement any of the optimisations suggested in the paper. [Functional_Ordered_Resolution_Prover] title = A Verified Functional Implementation of Bachmair and Ganzinger's Ordered Resolution Prover author = Anders Schlichtkrull , Jasmin Christian Blanchette , Dmitriy Traytel topic = Logic/General logic/Mechanization of proofs date = 2018-11-23 notify = andschl@dtu.dk,j.c.blanchette@vu.nl,traytel@inf.ethz.ch abstract = This Isabelle/HOL formalization refines the abstract ordered resolution prover presented in Section 4.3 of Bachmair and Ganzinger's "Resolution Theorem Proving" chapter in the Handbook of Automated Reasoning. The result is a functional implementation of a first-order prover. [Auto2_HOL] title = Auto2 Prover author = Bohua Zhan topic = Tools date = 2018-11-20 notify = bzhan@ios.ac.cn abstract = Auto2 is a saturation-based heuristic prover for higher-order logic, implemented as a tactic in Isabelle. This entry contains the instantiation of auto2 for Isabelle/HOL, along with two basic examples: solutions to some of the Pelletier’s problems, and elementary number theory of primes. [Order_Lattice_Props] title = Properties of Orderings and Lattices author = Georg Struth topic = Mathematics/Order date = 2018-12-11 notify = g.struth@sheffield.ac.uk abstract = These components add further fundamental order and lattice-theoretic concepts and properties to Isabelle's libraries. They follow by and large the introductory sections of the Compendium of Continuous Lattices, covering directed and filtered sets, down-closed and up-closed sets, ideals and filters, Galois connections, closure and co-closure operators. Some emphasis is on duality and morphisms between structures, as in the Compendium. To this end, three ad-hoc approaches to duality are compared. [Quantales] title = Quantales author = Georg Struth topic = Mathematics/Algebra date = 2018-12-11 notify = g.struth@sheffield.ac.uk abstract = These mathematical components formalise basic properties of quantales, together with some important models, constructions, and concepts, including quantic nuclei and conuclei. [Transformer_Semantics] title = Transformer Semantics author = Georg Struth topic = Mathematics/Algebra, Computer science/Semantics date = 2018-12-11 notify = g.struth@sheffield.ac.uk abstract = These mathematical components formalise predicate transformer semantics for programs, yet currently only for partial correctness and in the absence of faults. A first part for isotone (or monotone), Sup-preserving and Inf-preserving transformers follows Back and von Wright's approach, with additional emphasis on the quantalic structure of algebras of transformers. The second part develops Sup-preserving and Inf-preserving predicate transformers from the powerset monad, via its Kleisli category and Eilenberg-Moore algebras, with emphasis on adjunctions and dualities, as well as isomorphisms between relations, state transformers and predicate transformers. [Concurrent_Revisions] title = Formalization of Concurrent Revisions author = Roy Overbeek topic = Computer science/Concurrency date = 2018-12-25 notify = Roy.Overbeek@cwi.nl abstract = Concurrent revisions is a concurrency control model developed by Microsoft Research. It has many interesting properties that distinguish it from other well-known models such as transactional memory. One of these properties is determinacy: programs written within the model always produce the same outcome, independent of scheduling activity. The concurrent revisions model has an operational semantics, with an informal proof of determinacy. This document contains an Isabelle/HOL formalization of this semantics and the proof of determinacy. [Core_DOM] title = A Formal Model of the Document Object Model author = Achim D. Brucker , Michael Herzberg topic = Computer science/Data structures date = 2018-12-26 notify = adbrucker@0x5f.org abstract = In this AFP entry, we formalize the core of the Document Object Model (DOM). At its core, the DOM defines a tree-like data structure for representing documents in general and HTML documents in particular. It is the heart of any modern web browser. Formalizing the key concepts of the DOM is a prerequisite for the formal reasoning over client-side JavaScript programs and for the analysis of security concepts in modern web browsers. We present a formalization of the core DOM, with focus on the node-tree and the operations defined on node-trees, in Isabelle/HOL. We use the formalization to verify the functional correctness of the most important functions defined in the DOM standard. Moreover, our formalization is 1) extensible, i.e., can be extended without the need of re-proving already proven properties and 2) executable, i.e., we can generate executable code from our specification. [Core_SC_DOM] title = The Safely Composable DOM author = Achim D. Brucker , Michael Herzberg topic = Computer science/Data structures date = 2020-09-28 notify = adbrucker@0x5f.org, mail@michael-herzberg.de abstract = In this AFP entry, we formalize the core of the Safely Composable Document Object Model (SC DOM). The SC DOM improve the standard DOM (as formalized in the AFP entry "Core DOM") by strengthening the tree boundaries set by shadow roots: in the SC DOM, the shadow root is a sub-class of the document class (instead of a base class). This modifications also results in changes to some API methods (e.g., getOwnerDocument) to return the nearest shadow root rather than the document root. As a result, many API methods that, when called on a node inside a shadow tree, would previously ``break out'' and return or modify nodes that are possibly outside the shadow tree, now stay within its boundaries. This change in behavior makes programs that operate on shadow trees more predictable for the developer and allows them to make more assumptions about other code accessing the DOM. [Shadow_SC_DOM] title = A Formal Model of the Safely Composable Document Object Model with Shadow Roots author = Achim D. Brucker , Michael Herzberg topic = Computer science/Data structures date = 2020-09-28 notify = adbrucker@0x5f.org, mail@michael-herzberg.de abstract = In this AFP entry, we extend our formalization of the safely composable DOM with Shadow Roots. This is a proposal for Shadow Roots with stricter safety guarantess than the standard compliant formalization (see "Shadow DOM"). Shadow Roots are a recent proposal of the web community to support a component-based development approach for client-side web applications. Shadow roots are a significant extension to the DOM standard and, as web standards are condemned to be backward compatible, such extensions often result in complex specification that may contain unwanted subtleties that can be detected by a formalization. Our Isabelle/HOL formalization is, in the sense of object-orientation, an extension of our formalization of the core DOM and enjoys the same basic properties, i.e., it is extensible, i.e., can be extended without the need of re-proving already proven properties and executable, i.e., we can generate executable code from our specification. We exploit the executability to show that our formalization complies to the official standard of the W3C, respectively, the WHATWG. [SC_DOM_Components] title = A Formalization of Safely Composable Web Components author = Achim D. Brucker , Michael Herzberg topic = Computer science/Data structures date = 2020-09-28 notify = adbrucker@0x5f.org, mail@michael-herzberg.de abstract = While the (safely composable) DOM with shadow trees provide the technical basis for defining web components, it does neither defines the concept of web components nor specifies the safety properties that web components should guarantee. Consequently, the standard also does not discuss how or even if the methods for modifying the DOM respect component boundaries. In AFP entry, we present a formally verified model of safely composable web components and define safety properties which ensure that different web components can only interact with each other using well-defined interfaces. Moreover, our verification of the application programming interface (API) of the DOM revealed numerous invariants that implementations of the DOM API need to preserve to ensure the integrity of components. In comparison to the strict standard compliance formalization of Web Components in the AFP entry "DOM_Components", the notion of components in this entry (based on "SC_DOM" and "Shadow_SC_DOM") provides much stronger safety guarantees. [Store_Buffer_Reduction] title = A Reduction Theorem for Store Buffers author = Ernie Cohen , Norbert Schirmer topic = Computer science/Concurrency date = 2019-01-07 notify = norbert.schirmer@web.de abstract = When verifying a concurrent program, it is usual to assume that memory is sequentially consistent. However, most modern multiprocessors depend on store buffering for efficiency, and provide native sequential consistency only at a substantial performance penalty. To regain sequential consistency, a programmer has to follow an appropriate programming discipline. However, naïve disciplines, such as protecting all shared accesses with locks, are not flexible enough for building high-performance multiprocessor software. We present a new discipline for concurrent programming under TSO (total store order, with store buffer forwarding). It does not depend on concurrency primitives, such as locks. Instead, threads use ghost operations to acquire and release ownership of memory addresses. A thread can write to an address only if no other thread owns it, and can read from an address only if it owns it or it is shared and the thread has flushed its store buffer since it last wrote to an address it did not own. This discipline covers both coarse-grained concurrency (where data is protected by locks) as well as fine-grained concurrency (where atomic operations race to memory). We formalize this discipline in Isabelle/HOL, and prove that if every execution of a program in a system without store buffers follows the discipline, then every execution of the program with store buffers is sequentially consistent. Thus, we can show sequential consistency under TSO by ordinary assertional reasoning about the program, without having to consider store buffers at all. [IMP2] title = IMP2 – Simple Program Verification in Isabelle/HOL author = Peter Lammich , Simon Wimmer topic = Computer science/Programming languages/Logics, Computer science/Algorithms date = 2019-01-15 notify = lammich@in.tum.de abstract = IMP2 is a simple imperative language together with Isabelle tooling to create a program verification environment in Isabelle/HOL. The tools include a C-like syntax, a verification condition generator, and Isabelle commands for the specification of programs. The framework is modular, i.e., it allows easy reuse of already proved programs within larger programs. This entry comes with a quickstart guide and a large collection of examples, spanning basic algorithms with simple proofs to more advanced algorithms and proof techniques like data refinement. Some highlights from the examples are:
  • Bisection Square Root,
  • Extended Euclid,
  • Exponentiation by Squaring,
  • Binary Search,
  • Insertion Sort,
  • Quicksort,
  • Depth First Search.
The abstract syntax and semantics are very simple and well-documented. They are suitable to be used in a course, as extension to the IMP language which comes with the Isabelle distribution. While this entry is limited to a simple imperative language, the ideas could be extended to more sophisticated languages. [Farkas] title = Farkas' Lemma and Motzkin's Transposition Theorem author = Ralph Bottesch , Max W. Haslbeck , René Thiemann topic = Mathematics/Algebra date = 2019-01-17 notify = rene.thiemann@uibk.ac.at abstract = We formalize a proof of Motzkin's transposition theorem and Farkas' lemma in Isabelle/HOL. Our proof is based on the formalization of the simplex algorithm which, given a set of linear constraints, either returns a satisfying assignment to the problem or detects unsatisfiability. By reusing facts about the simplex algorithm we show that a set of linear constraints is unsatisfiable if and only if there is a linear combination of the constraints which evaluates to a trivially unsatisfiable inequality. [Auto2_Imperative_HOL] title = Verifying Imperative Programs using Auto2 author = Bohua Zhan topic = Computer science/Algorithms, Computer science/Data structures date = 2018-12-21 notify = bzhan@ios.ac.cn abstract = This entry contains the application of auto2 to verifying functional and imperative programs. Algorithms and data structures that are verified include linked lists, binary search trees, red-black trees, interval trees, priority queue, quicksort, union-find, Dijkstra's algorithm, and a sweep-line algorithm for detecting rectangle intersection. The imperative verification is based on Imperative HOL and its separation logic framework. A major goal of this work is to set up automation in order to reduce the length of proof that the user needs to provide, both for verifying functional programs and for working with separation logic. [UTP] title = Isabelle/UTP: Mechanised Theory Engineering for Unifying Theories of Programming author = Simon Foster , Frank Zeyda<>, Yakoub Nemouchi , Pedro Ribeiro<>, Burkhart Wolff topic = Computer science/Programming languages/Logics date = 2019-02-01 notify = simon.foster@york.ac.uk abstract = Isabelle/UTP is a mechanised theory engineering toolkit based on Hoare and He’s Unifying Theories of Programming (UTP). UTP enables the creation of denotational, algebraic, and operational semantics for different programming languages using an alphabetised relational calculus. We provide a semantic embedding of the alphabetised relational calculus in Isabelle/HOL, including new type definitions, relational constructors, automated proof tactics, and accompanying algebraic laws. Isabelle/UTP can be used to both capture laws of programming for different languages, and put these fundamental theorems to work in the creation of associated verification tools, using calculi like Hoare logics. This document describes the relational core of the UTP in Isabelle/HOL. [HOL-CSP] title = HOL-CSP Version 2.0 author = Safouan Taha , Lina Ye , Burkhart Wolff topic = Computer science/Concurrency/Process calculi, Computer science/Semantics date = 2019-04-26 notify = wolff@lri.fr abstract = This is a complete formalization of the work of Hoare and Roscoe on the denotational semantics of the Failure/Divergence Model of CSP. It follows essentially the presentation of CSP in Roscoe’s Book ”Theory and Practice of Concurrency” [8] and the semantic details in a joint Paper of Roscoe and Brooks ”An improved failures model for communicating processes". The present work is based on a prior formalization attempt, called HOL-CSP 1.0, done in 1997 by H. Tej and B. Wolff with the Isabelle proof technology available at that time. This work revealed minor, but omnipresent foundational errors in key concepts like the process invariant. The present version HOL-CSP profits from substantially improved libraries (notably HOLCF), improved automated proof techniques, and structured proof techniques in Isar and is substantially shorter but more complete. [Probabilistic_Prime_Tests] title = Probabilistic Primality Testing author = Daniel Stüwe<>, Manuel Eberl topic = Mathematics/Number theory date = 2019-02-11 notify = eberlm@in.tum.de abstract =

The most efficient known primality tests are probabilistic in the sense that they use randomness and may, with some probability, mistakenly classify a composite number as prime – but never a prime number as composite. Examples of this are the Miller–Rabin test, the Solovay–Strassen test, and (in most cases) Fermat's test.

This entry defines these three tests and proves their correctness. It also develops some of the number-theoretic foundations, such as Carmichael numbers and the Jacobi symbol with an efficient executable algorithm to compute it.

[Kruskal] title = Kruskal's Algorithm for Minimum Spanning Forest author = Maximilian P.L. Haslbeck , Peter Lammich , Julian Biendarra<> topic = Computer science/Algorithms/Graph date = 2019-02-14 notify = haslbema@in.tum.de, lammich@in.tum.de abstract = This Isabelle/HOL formalization defines a greedy algorithm for finding a minimum weight basis on a weighted matroid and proves its correctness. This algorithm is an abstract version of Kruskal's algorithm. We interpret the abstract algorithm for the cycle matroid (i.e. forests in a graph) and refine it to imperative executable code using an efficient union-find data structure. Our formalization can be instantiated for different graph representations. We provide instantiations for undirected graphs and symmetric directed graphs. [List_Inversions] title = The Inversions of a List author = Manuel Eberl topic = Computer science/Algorithms date = 2019-02-01 notify = eberlm@in.tum.de abstract =

This entry defines the set of inversions of a list, i.e. the pairs of indices that violate sortedness. It also proves the correctness of the well-known O(n log n) divide-and-conquer algorithm to compute the number of inversions.

[Prime_Distribution_Elementary] title = Elementary Facts About the Distribution of Primes author = Manuel Eberl topic = Mathematics/Number theory date = 2019-02-21 notify = eberlm@in.tum.de abstract =

This entry is a formalisation of Chapter 4 (and parts of Chapter 3) of Apostol's Introduction to Analytic Number Theory. The main topics that are addressed are properties of the distribution of prime numbers that can be shown in an elementary way (i. e. without the Prime Number Theorem), the various equivalent forms of the PNT (which imply each other in elementary ways), and consequences that follow from the PNT in elementary ways. The latter include, most notably, asymptotic bounds for the number of distinct prime factors of n, the divisor function d(n), Euler's totient function φ(n), and lcm(1,…,n).

[Safe_OCL] title = Safe OCL author = Denis Nikiforov <> topic = Computer science/Programming languages/Language definitions license = LGPL date = 2019-03-09 notify = denis.nikif@gmail.com abstract =

The theory is a formalization of the OCL type system, its abstract syntax and expression typing rules. The theory does not define a concrete syntax and a semantics. In contrast to Featherweight OCL, it is based on a deep embedding approach. The type system is defined from scratch, it is not based on the Isabelle HOL type system.

The Safe OCL distincts nullable and non-nullable types. Also the theory gives a formal definition of safe navigation operations. The Safe OCL typing rules are much stricter than rules given in the OCL specification. It allows one to catch more errors on a type checking phase.

The type theory presented is four-layered: classes, basic types, generic types, errorable types. We introduce the following new types: non-nullable types (T[1]), nullable types (T[?]), OclSuper. OclSuper is a supertype of all other types (basic types, collections, tuples). This type allows us to define a total supremum function, so types form an upper semilattice. It allows us to define rich expression typing rules in an elegant manner.

The Preliminaries Chapter of the theory defines a number of helper lemmas for transitive closures and tuples. It defines also a generic object model independent from OCL. It allows one to use the theory as a reference for formalization of analogous languages.

[QHLProver] title = Quantum Hoare Logic author = Junyi Liu<>, Bohua Zhan , Shuling Wang<>, Shenggang Ying<>, Tao Liu<>, Yangjia Li<>, Mingsheng Ying<>, Naijun Zhan<> topic = Computer science/Programming languages/Logics, Computer science/Semantics date = 2019-03-24 notify = bzhan@ios.ac.cn abstract = We formalize quantum Hoare logic as given in [1]. In particular, we specify the syntax and denotational semantics of a simple model of quantum programs. Then, we write down the rules of quantum Hoare logic for partial correctness, and show the soundness and completeness of the resulting proof system. As an application, we verify the correctness of Grover’s algorithm. [Transcendence_Series_Hancl_Rucki] title = The Transcendence of Certain Infinite Series author = Angeliki Koutsoukou-Argyraki , Wenda Li topic = Mathematics/Analysis, Mathematics/Number theory date = 2019-03-27 notify = wl302@cam.ac.uk, ak2110@cam.ac.uk abstract = We formalize the proofs of two transcendence criteria by J. Hančl and P. Rucki that assert the transcendence of the sums of certain infinite series built up by sequences that fulfil certain properties. Both proofs make use of Roth's celebrated theorem on diophantine approximations to algebraic numbers from 1955 which we implement as an assumption without having formalised its proof. [Binding_Syntax_Theory] title = A General Theory of Syntax with Bindings author = Lorenzo Gheri , Andrei Popescu topic = Computer science/Programming languages/Lambda calculi, Computer science/Functional programming, Logic/General logic/Mechanization of proofs date = 2019-04-06 notify = a.popescu@mdx.ac.uk, lor.gheri@gmail.com abstract = We formalize a theory of syntax with bindings that has been developed and refined over the last decade to support several large formalization efforts. Terms are defined for an arbitrary number of constructors of varying numbers of inputs, quotiented to alpha-equivalence and sorted according to a binding signature. The theory includes many properties of the standard operators on terms: substitution, swapping and freshness. It also includes bindings-aware induction and recursion principles and support for semantic interpretation. This work has been presented in the ITP 2017 paper “A Formalized General Theory of Syntax with Bindings”. [LTL_Master_Theorem] title = A Compositional and Unified Translation of LTL into ω-Automata author = Benedikt Seidl , Salomon Sickert topic = Computer science/Automata and formal languages date = 2019-04-16 notify = benedikt.seidl@tum.de, s.sickert@tum.de abstract = We present a formalisation of the unified translation approach of linear temporal logic (LTL) into ω-automata from [1]. This approach decomposes LTL formulas into ``simple'' languages and allows a clear separation of concerns: first, we formalise the purely logical result yielding this decomposition; second, we instantiate this generic theory to obtain a construction for deterministic (state-based) Rabin automata (DRA). We extract from this particular instantiation an executable tool translating LTL to DRAs. To the best of our knowledge this is the first verified translation from LTL to DRAs that is proven to be double exponential in the worst case which asymptotically matches the known lower bound.

[1] Javier Esparza, Jan Kretínský, Salomon Sickert. One Theorem to Rule Them All: A Unified Translation of LTL into ω-Automata. LICS 2018 [LambdaAuth] title = Formalization of Generic Authenticated Data Structures author = Matthias Brun<>, Dmitriy Traytel topic = Computer science/Security, Computer science/Programming languages/Lambda calculi date = 2019-05-14 notify = traytel@inf.ethz.ch abstract = Authenticated data structures are a technique for outsourcing data storage and maintenance to an untrusted server. The server is required to produce an efficiently checkable and cryptographically secure proof that it carried out precisely the requested computation. Miller et al. introduced λ• (pronounced lambda auth)—a functional programming language with a built-in primitive authentication construct, which supports a wide range of user-specified authenticated data structures while guaranteeing certain correctness and security properties for all well-typed programs. We formalize λ• and prove its correctness and security properties. With Isabelle's help, we uncover and repair several mistakes in the informal proofs and lemma statements. Our findings are summarized in a paper draft. [IMP2_Binary_Heap] title = Binary Heaps for IMP2 author = Simon Griebel<> topic = Computer science/Data structures, Computer science/Algorithms date = 2019-06-13 notify = s.griebel@tum.de abstract = In this submission array-based binary minimum heaps are formalized. The correctness of the following heap operations is proved: insert, get-min, delete-min and make-heap. These are then used to verify an in-place heapsort. The formalization is based on IMP2, an imperative program verification framework implemented in Isabelle/HOL. The verified heap functions are iterative versions of the partly recursive functions found in "Algorithms and Data Structures – The Basic Toolbox" by K. Mehlhorn and P. Sanders and "Introduction to Algorithms" by T. H. Cormen, C. E. Leiserson, R. L. Rivest and C. Stein. [Groebner_Macaulay] title = Gröbner Bases, Macaulay Matrices and Dubé's Degree Bounds author = Alexander Maletzky topic = Mathematics/Algebra date = 2019-06-15 notify = alexander.maletzky@risc.jku.at abstract = This entry formalizes the connection between Gröbner bases and Macaulay matrices (sometimes also referred to as `generalized Sylvester matrices'). In particular, it contains a method for computing Gröbner bases, which proceeds by first constructing some Macaulay matrix of the initial set of polynomials, then row-reducing this matrix, and finally converting the result back into a set of polynomials. The output is shown to be a Gröbner basis if the Macaulay matrix constructed in the first step is sufficiently large. In order to obtain concrete upper bounds on the size of the matrix (and hence turn the method into an effectively executable algorithm), Dubé's degree bounds on Gröbner bases are utilized; consequently, they are also part of the formalization. [Linear_Inequalities] title = Linear Inequalities author = Ralph Bottesch , Alban Reynaud <>, René Thiemann topic = Mathematics/Algebra date = 2019-06-21 notify = rene.thiemann@uibk.ac.at abstract = We formalize results about linear inqualities, mainly from Schrijver's book. The main results are the proof of the fundamental theorem on linear inequalities, Farkas' lemma, Carathéodory's theorem, the Farkas-Minkowsky-Weyl theorem, the decomposition theorem of polyhedra, and Meyer's result that the integer hull of a polyhedron is a polyhedron itself. Several theorems include bounds on the appearing numbers, and in particular we provide an a-priori bound on mixed-integer solutions of linear inequalities. [Linear_Programming] title = Linear Programming author = Julian Parsert , Cezary Kaliszyk topic = Mathematics/Algebra date = 2019-08-06 notify = julian.parsert@gmail.com, cezary.kaliszyk@uibk.ac.at abstract = We use the previous formalization of the general simplex algorithm to formulate an algorithm for solving linear programs. We encode the linear programs using only linear constraints. Solving these constraints also solves the original linear program. This algorithm is proven to be sound by applying the weak duality theorem which is also part of this formalization. [Differential_Game_Logic] title = Differential Game Logic author = André Platzer topic = Computer science/Programming languages/Logics date = 2019-06-03 notify = aplatzer@cs.cmu.edu abstract = This formalization provides differential game logic (dGL), a logic for proving properties of hybrid game. In addition to the syntax and semantics, it formalizes a uniform substitution calculus for dGL. Church's uniform substitutions substitute a term or formula for a function or predicate symbol everywhere. The uniform substitutions for dGL also substitute hybrid games for a game symbol everywhere. We prove soundness of one-pass uniform substitutions and the axioms of differential game logic with respect to their denotational semantics. One-pass uniform substitutions are faster by postponing soundness-critical admissibility checks with a linear pass homomorphic application and regain soundness by a variable condition at the replacements. The formalization is based on prior non-mechanized soundness proofs for dGL. [Complete_Non_Orders] title = Complete Non-Orders and Fixed Points author = Akihisa Yamada , Jérémy Dubut topic = Mathematics/Order date = 2019-06-27 notify = akihisayamada@nii.ac.jp, dubut@nii.ac.jp abstract = We develop an Isabelle/HOL library of order-theoretic concepts, such as various completeness conditions and fixed-point theorems. We keep our formalization as general as possible: we reprove several well-known results about complete orders, often without any properties of ordering, thus complete non-orders. In particular, we generalize the Knaster–Tarski theorem so that we ensure the existence of a quasi-fixed point of monotone maps over complete non-orders, and show that the set of quasi-fixed points is complete under a mild condition—attractivity—which is implied by either antisymmetry or transitivity. This result generalizes and strengthens a result by Stauti and Maaden. Finally, we recover Kleene’s fixed-point theorem for omega-complete non-orders, again using attractivity to prove that Kleene’s fixed points are least quasi-fixed points. [Priority_Search_Trees] title = Priority Search Trees author = Peter Lammich , Tobias Nipkow topic = Computer science/Data structures date = 2019-06-25 notify = lammich@in.tum.de abstract = We present a new, purely functional, simple and efficient data structure combining a search tree and a priority queue, which we call a priority search tree. The salient feature of priority search trees is that they offer a decrease-key operation, something that is missing from other simple, purely functional priority queue implementations. Priority search trees can be implemented on top of any search tree. This entry does the implementation for red-black trees. This entry formalizes the first part of our ITP-2019 proof pearl Purely Functional, Simple and Efficient Priority Search Trees and Applications to Prim and Dijkstra. [Prim_Dijkstra_Simple] title = Purely Functional, Simple, and Efficient Implementation of Prim and Dijkstra author = Peter Lammich , Tobias Nipkow topic = Computer science/Algorithms/Graph date = 2019-06-25 notify = lammich@in.tum.de abstract = We verify purely functional, simple and efficient implementations of Prim's and Dijkstra's algorithms. This constitutes the first verification of an executable and even efficient version of Prim's algorithm. This entry formalizes the second part of our ITP-2019 proof pearl Purely Functional, Simple and Efficient Priority Search Trees and Applications to Prim and Dijkstra. [MFOTL_Monitor] title = Formalization of a Monitoring Algorithm for Metric First-Order Temporal Logic author = Joshua Schneider , Dmitriy Traytel topic = Computer science/Algorithms, Logic/General logic/Temporal logic, Computer science/Automata and formal languages date = 2019-07-04 notify = joshua.schneider@inf.ethz.ch, traytel@inf.ethz.ch abstract = A monitor is a runtime verification tool that solves the following problem: Given a stream of time-stamped events and a policy formulated in a specification language, decide whether the policy is satisfied at every point in the stream. We verify the correctness of an executable monitor for specifications given as formulas in metric first-order temporal logic (MFOTL), an expressive extension of linear temporal logic with real-time constraints and first-order quantification. The verified monitor implements a simplified variant of the algorithm used in the efficient MonPoly monitoring tool. The formalization is presented in a RV 2019 paper, which also compares the output of the verified monitor to that of other monitoring tools on randomly generated inputs. This case study revealed several errors in the optimized but unverified tools. extra-history = Change history: [2020-08-13]: added the formalization of the abstract slicing framework and joint data slicer (revision b1639ed541b7)
[FOL_Seq_Calc1] title = A Sequent Calculus for First-Order Logic author = Asta Halkjær From contributors = Alexander Birch Jensen , Anders Schlichtkrull , Jørgen Villadsen topic = Logic/Proof theory date = 2019-07-18 notify = ahfrom@dtu.dk abstract = This work formalizes soundness and completeness of a one-sided sequent calculus for first-order logic. The completeness is shown via a translation from a complete semantic tableau calculus, the proof of which is based on the First-Order Logic According to Fitting theory. The calculi and proof techniques are taken from Ben-Ari's Mathematical Logic for Computer Science. [Szpilrajn] title = Szpilrajn Extension Theorem author = Peter Zeller topic = Mathematics/Order date = 2019-07-27 notify = p_zeller@cs.uni-kl.de abstract = We formalize the Szpilrajn extension theorem, also known as order-extension principal: Every strict partial order can be extended to a strict linear order. [TESL_Language] title = A Formal Development of a Polychronous Polytimed Coordination Language author = Hai Nguyen Van , Frédéric Boulanger , Burkhart Wolff topic = Computer science/System description languages, Computer science/Semantics, Computer science/Concurrency date = 2019-07-30 notify = frederic.boulanger@centralesupelec.fr, burkhart.wolff@lri.fr abstract = The design of complex systems involves different formalisms for modeling their different parts or aspects. The global model of a system may therefore consist of a coordination of concurrent sub-models that use different paradigms. We develop here a theory for a language used to specify the timed coordination of such heterogeneous subsystems by addressing the following issues:

  • the behavior of the sub-systems is observed only at a series of discrete instants,
  • events may occur in different sub-systems at unrelated times, leading to polychronous systems, which do not necessarily have a common base clock,
  • coordination between subsystems involves causality, so the occurrence of an event may enforce the occurrence of other events, possibly after a certain duration has elapsed or an event has occurred a given number of times,
  • the domain of time (discrete, rational, continuous...) may be different in the subsystems, leading to polytimed systems,
  • the time frames of different sub-systems may be related (for instance, time in a GPS satellite and in a GPS receiver on Earth are related although they are not the same).
Firstly, a denotational semantics of the language is defined. Then, in order to be able to incrementally check the behavior of systems, an operational semantics is given, with proofs of progress, soundness and completeness with regard to the denotational semantics. These proofs are made according to a setup that can scale up when new operators are added to the language. In order for specifications to be composed in a clean way, the language should be invariant by stuttering (i.e., adding observation instants at which nothing happens). The proof of this invariance is also given. [Stellar_Quorums] title = Stellar Quorum Systems author = Giuliano Losa topic = Computer science/Algorithms/Distributed date = 2019-08-01 notify = giuliano@galois.com abstract = We formalize the static properties of personal Byzantine quorum systems (PBQSs) and Stellar quorum systems, as described in the paper ``Stellar Consensus by Reduction'' (to appear at DISC 2019). [IMO2019] title = Selected Problems from the International Mathematical Olympiad 2019 author = Manuel Eberl topic = Mathematics/Misc date = 2019-08-05 notify = eberlm@in.tum.de abstract =

This entry contains formalisations of the answers to three of the six problem of the International Mathematical Olympiad 2019, namely Q1, Q4, and Q5.

The reason why these problems were chosen is that they are particularly amenable to formalisation: they can be solved with minimal use of libraries. The remaining three concern geometry and graph theory, which, in the author's opinion, are more difficult to formalise resp. require a more complex library.

[Adaptive_State_Counting] title = Formalisation of an Adaptive State Counting Algorithm author = Robert Sachtleben topic = Computer science/Automata and formal languages, Computer science/Algorithms date = 2019-08-16 notify = rob_sac@uni-bremen.de abstract = This entry provides a formalisation of a refinement of an adaptive state counting algorithm, used to test for reduction between finite state machines. The algorithm has been originally presented by Hierons in the paper Testing from a Non-Deterministic Finite State Machine Using Adaptive State Counting. Definitions for finite state machines and adaptive test cases are given and many useful theorems are derived from these. The algorithm is formalised using mutually recursive functions, for which it is proven that the generated test suite is sufficient to test for reduction against finite state machines of a certain fault domain. Additionally, the algorithm is specified in a simple WHILE-language and its correctness is shown using Hoare-logic. [Jacobson_Basic_Algebra] title = A Case Study in Basic Algebra author = Clemens Ballarin topic = Mathematics/Algebra date = 2019-08-30 notify = ballarin@in.tum.de abstract = The focus of this case study is re-use in abstract algebra. It contains locale-based formalisations of selected parts of set, group and ring theory from Jacobson's Basic Algebra leading to the respective fundamental homomorphism theorems. The study is not intended as a library base for abstract algebra. It rather explores an approach towards abstract algebra in Isabelle. [Hybrid_Systems_VCs] title = Verification Components for Hybrid Systems author = Jonathan Julian Huerta y Munive <> topic = Mathematics/Algebra, Mathematics/Analysis date = 2019-09-10 notify = jjhuertaymunive1@sheffield.ac.uk, jonjulian23@gmail.com abstract = These components formalise a semantic framework for the deductive verification of hybrid systems. They support reasoning about continuous evolutions of hybrid programs in the style of differential dynamics logic. Vector fields or flows model these evolutions, and their verification is done with invariants for the former or orbits for the latter. Laws of modal Kleene algebra or categorical predicate transformers implement the verification condition generation. Examples show the approach at work. extra-history = Change history: [2020-12-13]: added components based on Kleene algebras with tests. These implement differential Hoare logic (dH) and a Morgan-style differential refinement calculus (dR) for verification of hybrid programs. [Generic_Join] title = Formalization of Multiway-Join Algorithms author = Thibault Dardinier<> topic = Computer science/Algorithms date = 2019-09-16 notify = tdardini@student.ethz.ch, traytel@inf.ethz.ch abstract = Worst-case optimal multiway-join algorithms are recent seminal achievement of the database community. These algorithms compute the natural join of multiple relational databases and improve in the worst case over traditional query plan optimizations of nested binary joins. In 2014, Ngo, Ré, and Rudra gave a unified presentation of different multi-way join algorithms. We formalized and proved correct their "Generic Join" algorithm and extended it to support negative joins. [Aristotles_Assertoric_Syllogistic] title = Aristotle's Assertoric Syllogistic author = Angeliki Koutsoukou-Argyraki topic = Logic/Philosophical aspects date = 2019-10-08 notify = ak2110@cam.ac.uk abstract = We formalise with Isabelle/HOL some basic elements of Aristotle's assertoric syllogistic following the article from the Stanford Encyclopedia of Philosophy by Robin Smith. To this end, we use a set theoretic formulation (covering both individual and general predication). In particular, we formalise the deductions in the Figures and after that we present Aristotle's metatheoretical observation that all deductions in the Figures can in fact be reduced to either Barbara or Celarent. As the formal proofs prove to be straightforward, the interest of this entry lies in illustrating the functionality of Isabelle and high efficiency of Sledgehammer for simple exercises in philosophy. [VerifyThis2019] title = VerifyThis 2019 -- Polished Isabelle Solutions author = Peter Lammich<>, Simon Wimmer topic = Computer science/Algorithms date = 2019-10-16 notify = lammich@in.tum.de, wimmers@in.tum.de abstract = VerifyThis 2019 (http://www.pm.inf.ethz.ch/research/verifythis.html) was a program verification competition associated with ETAPS 2019. It was the 8th event in the VerifyThis competition series. In this entry, we present polished and completed versions of our solutions that we created during the competition. [ZFC_in_HOL] title = Zermelo Fraenkel Set Theory in Higher-Order Logic author = Lawrence C. Paulson topic = Logic/Set theory date = 2019-10-24 notify = lp15@cam.ac.uk abstract =

This entry is a new formalisation of ZFC set theory in Isabelle/HOL. It is logically equivalent to Obua's HOLZF; the point is to have the closest possible integration with the rest of Isabelle/HOL, minimising the amount of new notations and exploiting type classes.

There is a type V of sets and a function elts :: V => V set mapping a set to its elements. Classes simply have type V set, and a predicate identifies the small classes: those that correspond to actual sets. Type classes connected with orders and lattices are used to minimise the amount of new notation for concepts such as the subset relation, union and intersection. Basic concepts — Cartesian products, disjoint sums, natural numbers, functions, etc. — are formalised.

More advanced set-theoretic concepts, such as transfinite induction, ordinals, cardinals and the transitive closure of a set, are also provided. The definition of addition and multiplication for general sets (not just ordinals) follows Kirby.

The theory provides two type classes with the aim of facilitating developments that combine V with other Isabelle/HOL types: embeddable, the class of types that can be injected into V (including V itself as well as V*V, etc.), and small, the class of types that correspond to some ZF set.

extra-history = Change history: [2020-01-28]: Generalisation of the "small" predicate and order types to arbitrary sets; ordinal exponentiation; introduction of the coercion ord_of_nat :: "nat => V"; numerous new lemmas. (revision 6081d5be8d08) [Interval_Arithmetic_Word32] title = Interval Arithmetic on 32-bit Words author = Brandon Bohrer topic = Computer science/Data structures date = 2019-11-27 notify = bjbohrer@gmail.com, bbohrer@cs.cmu.edu abstract = Interval_Arithmetic implements conservative interval arithmetic computations, then uses this interval arithmetic to implement a simple programming language where all terms have 32-bit signed word values, with explicit infinities for terms outside the representable bounds. Our target use case is interpreters for languages that must have a well-understood low-level behavior. We include a formalization of bounded-length strings which are used for the identifiers of our language. Bounded-length identifiers are useful in some applications, for example the Differential_Dynamic_Logic article, where a Euclidean space indexed by identifiers demands that identifiers are finitely many. [Generalized_Counting_Sort] title = An Efficient Generalization of Counting Sort for Large, possibly Infinite Key Ranges author = Pasquale Noce topic = Computer science/Algorithms, Computer science/Functional programming date = 2019-12-04 notify = pasquale.noce.lavoro@gmail.com abstract = Counting sort is a well-known algorithm that sorts objects of any kind mapped to integer keys, or else to keys in one-to-one correspondence with some subset of the integers (e.g. alphabet letters). However, it is suitable for direct use, viz. not just as a subroutine of another sorting algorithm (e.g. radix sort), only if the key range is not significantly larger than the number of the objects to be sorted. This paper describes a tail-recursive generalization of counting sort making use of a bounded number of counters, suitable for direct use in case of a large, or even infinite key range of any kind, subject to the only constraint of being a subset of an arbitrary linear order. After performing a pen-and-paper analysis of how such algorithm has to be designed to maximize its efficiency, this paper formalizes the resulting generalized counting sort (GCsort) algorithm and then formally proves its correctness properties, namely that (a) the counters' number is maximized never exceeding the fixed upper bound, (b) objects are conserved, (c) objects get sorted, and (d) the algorithm is stable. [Poincare_Bendixson] title = The Poincaré-Bendixson Theorem author = Fabian Immler , Yong Kiam Tan topic = Mathematics/Analysis date = 2019-12-18 notify = fimmler@cs.cmu.edu, yongkiat@cs.cmu.edu abstract = The Poincaré-Bendixson theorem is a classical result in the study of (continuous) dynamical systems. Colloquially, it restricts the possible behaviors of planar dynamical systems: such systems cannot be chaotic. In practice, it is a useful tool for proving the existence of (limiting) periodic behavior in planar systems. The theorem is an interesting and challenging benchmark for formalized mathematics because proofs in the literature rely on geometric sketches and only hint at symmetric cases. It also requires a substantial background of mathematical theories, e.g., the Jordan curve theorem, real analysis, ordinary differential equations, and limiting (long-term) behavior of dynamical systems. [Isabelle_C] title = Isabelle/C author = Frédéric Tuong , Burkhart Wolff topic = Computer science/Programming languages/Language definitions, Computer science/Semantics, Tools date = 2019-10-22 notify = tuong@users.gforge.inria.fr, wolff@lri.fr abstract = We present a framework for C code in C11 syntax deeply integrated into the Isabelle/PIDE development environment. Our framework provides an abstract interface for verification back-ends to be plugged-in independently. Thus, various techniques such as deductive program verification or white-box testing can be applied to the same source, which is part of an integrated PIDE document model. Semantic back-ends are free to choose the supported C fragment and its semantics. In particular, they can differ on the chosen memory model or the specification mechanism for framing conditions. Our framework supports semantic annotations of C sources in the form of comments. Annotations serve to locally control back-end settings, and can express the term focus to which an annotation refers. Both the logical and the syntactic context are available when semantic annotations are evaluated. As a consequence, a formula in an annotation can refer both to HOL or C variables. Our approach demonstrates the degree of maturity and expressive power the Isabelle/PIDE sub-system has achieved in recent years. Our integration technique employs Lex and Yacc style grammars to ensure efficient deterministic parsing. This is the core-module of Isabelle/C; the AFP package for Clean and Clean_wrapper as well as AutoCorres and AutoCorres_wrapper (available via git) are applications of this front-end. [Zeta_3_Irrational] title = The Irrationality of ζ(3) author = Manuel Eberl topic = Mathematics/Number theory date = 2019-12-27 notify = manuel.eberl@tum.de abstract =

This article provides a formalisation of Beukers's straightforward analytic proof that ζ(3) is irrational. This was first proven by Apéry (which is why this result is also often called ‘Apéry's Theorem’) using a more algebraic approach. This formalisation follows Filaseta's presentation of Beukers's proof.

[Hybrid_Logic] title = Formalizing a Seligman-Style Tableau System for Hybrid Logic author = Asta Halkjær From topic = Logic/General logic/Modal logic date = 2019-12-20 notify = ahfrom@dtu.dk abstract = This work is a formalization of soundness and completeness proofs for a Seligman-style tableau system for hybrid logic. The completeness result is obtained via a synthetic approach using maximally consistent sets of tableau blocks. The formalization differs from previous work in a few ways. First, to avoid the need to backtrack in the construction of a tableau, the formalized system has no unnamed initial segment, and therefore no Name rule. Second, I show that the full Bridge rule is admissible in the system. Third, I start from rules restricted to only extend the branch with new formulas, including only witnessing diamonds that are not already witnessed, and show that the unrestricted rules are admissible. Similarly, I start from simpler versions of the @-rules and show that these are sufficient. The GoTo rule is restricted using a notion of potential such that each application consumes potential and potential is earned through applications of the remaining rules. I show that if a branch can be closed then it can be closed starting from a single unit. Finally, Nom is restricted by a fixed set of allowed nominals. The resulting system should be terminating. extra-history = Change history: [2020-06-03]: The fully restricted system has been shown complete by updating the synthetic completeness proof. [Bicategory] title = Bicategories author = Eugene W. Stark topic = Mathematics/Category theory date = 2020-01-06 notify = stark@cs.stonybrook.edu abstract =

Taking as a starting point the author's previous work on developing aspects of category theory in Isabelle/HOL, this article gives a compatible formalization of the notion of "bicategory" and develops a framework within which formal proofs of facts about bicategories can be given. The framework includes a number of basic results, including the Coherence Theorem, the Strictness Theorem, pseudofunctors and biequivalence, and facts about internal equivalences and adjunctions in a bicategory. As a driving application and demonstration of the utility of the framework, it is used to give a formal proof of a theorem, due to Carboni, Kasangian, and Street, that characterizes up to biequivalence the bicategories of spans in a category with pullbacks. The formalization effort necessitated the filling-in of many details that were not evident from the brief presentation in the original paper, as well as identifying a few minor corrections along the way.

Revisions made subsequent to the first version of this article added additional material on pseudofunctors, pseudonatural transformations, modifications, and equivalence of bicategories; the main thrust being to give a proof that a pseudofunctor is a biequivalence if and only if it can be extended to an equivalence of bicategories.

extra-history = Change history: [2020-02-15]: Move ConcreteCategory.thy from Bicategory to Category3 and use it systematically. Make other minor improvements throughout. (revision a51840d36867)
[2020-11-04]: Added new material on equivalence of bicategories, with associated changes. (revision 472cb2268826)
[Subset_Boolean_Algebras] title = A Hierarchy of Algebras for Boolean Subsets author = Walter Guttmann , Bernhard Möller topic = Mathematics/Algebra date = 2020-01-31 notify = walter.guttmann@canterbury.ac.nz abstract = We present a collection of axiom systems for the construction of Boolean subalgebras of larger overall algebras. The subalgebras are defined as the range of a complement-like operation on a semilattice. This technique has been used, for example, with the antidomain operation, dynamic negation and Stone algebras. We present a common ground for these constructions based on a new equational axiomatisation of Boolean algebras. [Goodstein_Lambda] title = Implementing the Goodstein Function in λ-Calculus author = Bertram Felgenhauer topic = Logic/Rewriting date = 2020-02-21 notify = int-e@gmx.de abstract = In this formalization, we develop an implementation of the Goodstein function G in plain λ-calculus, linked to a concise, self-contained specification. The implementation works on a Church-encoded representation of countable ordinals. The initial conversion to hereditary base 2 is not covered, but the material is sufficient to compute the particular value G(16), and easily extends to other fixed arguments. [VeriComp] title = A Generic Framework for Verified Compilers author = Martin Desharnais topic = Computer science/Programming languages/Compiling date = 2020-02-10 notify = martin.desharnais@unibw.de abstract = This is a generic framework for formalizing compiler transformations. It leverages Isabelle/HOL’s locales to abstract over concrete languages and transformations. It states common definitions for language semantics, program behaviours, forward and backward simulations, and compilers. We provide generic operations, such as simulation and compiler composition, and prove general (partial) correctness theorems, resulting in reusable proof components. [Hello_World] title = Hello World author = Cornelius Diekmann , Lars Hupel topic = Computer science/Functional programming date = 2020-03-07 notify = diekmann@net.in.tum.de abstract = In this article, we present a formalization of the well-known "Hello, World!" code, including a formal framework for reasoning about IO. Our model is inspired by the handling of IO in Haskell. We start by formalizing the 🌍 and embrace the IO monad afterwards. Then we present a sample main :: IO (), followed by its proof of correctness. [WOOT_Strong_Eventual_Consistency] title = Strong Eventual Consistency of the Collaborative Editing Framework WOOT author = Emin Karayel , Edgar Gonzàlez topic = Computer science/Algorithms/Distributed date = 2020-03-25 notify = eminkarayel@google.com, edgargip@google.com, me@eminkarayel.de abstract = Commutative Replicated Data Types (CRDTs) are a promising new class of data structures for large-scale shared mutable content in applications that only require eventual consistency. The WithOut Operational Transforms (WOOT) framework is a CRDT for collaborative text editing introduced by Oster et al. (CSCW 2006) for which the eventual consistency property was verified only for a bounded model to date. We contribute a formal proof for WOOTs strong eventual consistency. [Furstenberg_Topology] title = Furstenberg's topology and his proof of the infinitude of primes author = Manuel Eberl topic = Mathematics/Number theory date = 2020-03-22 notify = manuel.eberl@tum.de abstract =

This article gives a formal version of Furstenberg's topological proof of the infinitude of primes. He defines a topology on the integers based on arithmetic progressions (or, equivalently, residue classes). Using some fairly obvious properties of this topology, the infinitude of primes is then easily obtained.

Apart from this, this topology is also fairly ‘nice’ in general: it is second countable, metrizable, and perfect. All of these (well-known) facts are formally proven, including an explicit metric for the topology given by Zulfeqarr.

[Saturation_Framework] title = A Comprehensive Framework for Saturation Theorem Proving author = Sophie Tourret topic = Logic/General logic/Mechanization of proofs date = 2020-04-09 notify = stourret@mpi-inf.mpg.de abstract = This Isabelle/HOL formalization is the companion of the technical report “A comprehensive framework for saturation theorem proving”, itself companion of the eponym IJCAR 2020 paper, written by Uwe Waldmann, Sophie Tourret, Simon Robillard and Jasmin Blanchette. It verifies a framework for formal refutational completeness proofs of abstract provers that implement saturation calculi, such as ordered resolution or superposition, and allows to model entire prover architectures in such a way that the static refutational completeness of a calculus immediately implies the dynamic refutational completeness of a prover implementing the calculus using a variant of the given clause loop. The technical report “A comprehensive framework for saturation theorem proving” is available on the Matryoshka website. The names of the Isabelle lemmas and theorems corresponding to the results in the report are indicated in the margin of the report. [Saturation_Framework_Extensions] title = Extensions to the Comprehensive Framework for Saturation Theorem Proving author = Jasmin Blanchette , Sophie Tourret topic = Logic/General logic/Mechanization of proofs date = 2020-08-25 notify = jasmin.blanchette@gmail.com abstract = This Isabelle/HOL formalization extends the AFP entry Saturation_Framework with the following contributions:
  • an application of the framework to prove Bachmair and Ganzinger's resolution prover RP refutationally complete, which was formalized in a more ad hoc fashion by Schlichtkrull et al. in the AFP entry Ordered_Resultion_Prover;
  • generalizations of various basic concepts formalized by Schlichtkrull et al., which were needed to verify RP and could be useful to formalize other calculi, such as superposition;
  • alternative proofs of fairness (and hence saturation and ultimately refutational completeness) for the given clause procedures GC and LGC, based on invariance.
[MFODL_Monitor_Optimized] title = Formalization of an Optimized Monitoring Algorithm for Metric First-Order Dynamic Logic with Aggregations author = Thibault Dardinier<>, Lukas Heimes<>, Martin Raszyk , Joshua Schneider , Dmitriy Traytel topic = Computer science/Algorithms, Logic/General logic/Modal logic, Computer science/Automata and formal languages date = 2020-04-09 notify = martin.raszyk@inf.ethz.ch, joshua.schneider@inf.ethz.ch, traytel@inf.ethz.ch abstract = A monitor is a runtime verification tool that solves the following problem: Given a stream of time-stamped events and a policy formulated in a specification language, decide whether the policy is satisfied at every point in the stream. We verify the correctness of an executable monitor for specifications given as formulas in metric first-order dynamic logic (MFODL), which combines the features of metric first-order temporal logic (MFOTL) and metric dynamic logic. Thus, MFODL supports real-time constraints, first-order parameters, and regular expressions. Additionally, the monitor supports aggregation operations such as count and sum. This formalization, which is described in a forthcoming paper at IJCAR 2020, significantly extends previous work on a verified monitor for MFOTL. Apart from the addition of regular expressions and aggregations, we implemented multi-way joins and a specialized sliding window algorithm to further optimize the monitor. [Sliding_Window_Algorithm] title = Formalization of an Algorithm for Greedily Computing Associative Aggregations on Sliding Windows author = Lukas Heimes<>, Dmitriy Traytel , Joshua Schneider<> topic = Computer science/Algorithms date = 2020-04-10 notify = heimesl@student.ethz.ch, traytel@inf.ethz.ch, joshua.schneider@inf.ethz.ch abstract = Basin et al.'s sliding window algorithm (SWA) is an algorithm for combining the elements of subsequences of a sequence with an associative operator. It is greedy and minimizes the number of operator applications. We formalize the algorithm and verify its functional correctness. We extend the algorithm with additional operations and provide an alternative interface to the slide operation that does not require the entire input sequence. [Lucas_Theorem] title = Lucas's Theorem author = Chelsea Edmonds topic = Mathematics/Number theory date = 2020-04-07 notify = cle47@cam.ac.uk abstract = This work presents a formalisation of a generating function proof for Lucas's theorem. We first outline extensions to the existing Formal Power Series (FPS) library, including an equivalence relation for coefficients modulo n, an alternate binomial theorem statement, and a formalised proof of the Freshman's dream (mod p) lemma. The second part of the work presents the formal proof of Lucas's Theorem. Working backwards, the formalisation first proves a well known corollary of the theorem which is easier to formalise, and then applies induction to prove the original theorem statement. The proof of the corollary aims to provide a good example of a formalised generating function equivalence proof using the FPS library. The final theorem statement is intended to be integrated into the formalised proof of Hilbert's 10th Problem. [ADS_Functor] title = Authenticated Data Structures As Functors author = Andreas Lochbihler , Ognjen Marić topic = Computer science/Data structures date = 2020-04-16 notify = andreas.lochbihler@digitalasset.com, mail@andreas-lochbihler.de abstract = Authenticated data structures allow several systems to convince each other that they are referring to the same data structure, even if each of them knows only a part of the data structure. Using inclusion proofs, knowledgeable systems can selectively share their knowledge with other systems and the latter can verify the authenticity of what is being shared. In this article, we show how to modularly define authenticated data structures, their inclusion proofs, and operations thereon as datatypes in Isabelle/HOL, using a shallow embedding. Modularity allows us to construct complicated trees from reusable building blocks, which we call Merkle functors. Merkle functors include sums, products, and function spaces and are closed under composition and least fixpoints. As a practical application, we model the hierarchical transactions of Canton, a practical interoperability protocol for distributed ledgers, as authenticated data structures. This is a first step towards formalizing the Canton protocol and verifying its integrity and security guarantees. [Power_Sum_Polynomials] title = Power Sum Polynomials author = Manuel Eberl topic = Mathematics/Algebra date = 2020-04-24 notify = eberlm@in.tum.de abstract =

This article provides a formalisation of the symmetric multivariate polynomials known as power sum polynomials. These are of the form pn(X1,…, Xk) = X1n + … + Xkn. A formal proof of the Girard–Newton Theorem is also given. This theorem relates the power sum polynomials to the elementary symmetric polynomials sk in the form of a recurrence relation (-1)k k sk = ∑i∈[0,k) (-1)i si pk-i .

As an application, this is then used to solve a generalised form of a puzzle given as an exercise in Dummit and Foote's Abstract Algebra: For k complex unknowns x1, …, xk, define pj := x1j + … + xkj. Then for each vector a ∈ ℂk, show that there is exactly one solution to the system p1 = a1, …, pk = ak up to permutation of the xi and determine the value of pi for i>k.

[Gaussian_Integers] title = Gaussian Integers author = Manuel Eberl topic = Mathematics/Number theory date = 2020-04-24 notify = eberlm@in.tum.de abstract =

The Gaussian integers are the subring ℤ[i] of the complex numbers, i. e. the ring of all complex numbers with integral real and imaginary part. This article provides a definition of this ring as well as proofs of various basic properties, such as that they form a Euclidean ring and a full classification of their primes. An executable (albeit not very efficient) factorisation algorithm is also provided.

Lastly, this Gaussian integer formalisation is used in two short applications:

  1. The characterisation of all positive integers that can be written as sums of two squares
  2. Euclid's formula for primitive Pythagorean triples

While elementary proofs for both of these are already available in the AFP, the theory of Gaussian integers provides more concise proofs and a more high-level view.

[Forcing] title = Formalization of Forcing in Isabelle/ZF author = Emmanuel Gunther , Miguel Pagano , Pedro Sánchez Terraf topic = Logic/Set theory date = 2020-05-06 notify = gunther@famaf.unc.edu.ar, pagano@famaf.unc.edu.ar, sterraf@famaf.unc.edu.ar abstract = We formalize the theory of forcing in the set theory framework of Isabelle/ZF. Under the assumption of the existence of a countable transitive model of ZFC, we construct a proper generic extension and show that the latter also satisfies ZFC. [Delta_System_Lemma] title = Cofinality and the Delta System Lemma author = Pedro Sánchez Terraf topic = Mathematics/Combinatorics, Logic/Set theory date = 2020-12-27 notify = sterraf@famaf.unc.edu.ar abstract = We formalize the basic results on cofinality of linearly ordered sets and ordinals and Šanin’s Lemma for uncountable families of finite sets. This last result is used to prove the countable chain condition for Cohen posets. We work in the set theory framework of Isabelle/ZF, using the Axiom of Choice as needed. [Recursion-Addition] title = Recursion Theorem in ZF author = Georgy Dunaev topic = Logic/Set theory date = 2020-05-11 notify = georgedunaev@gmail.com abstract = This document contains a proof of the recursion theorem. This is a mechanization of the proof of the recursion theorem from the text Introduction to Set Theory, by Karel Hrbacek and Thomas Jech. This implementation may be used as the basis for a model of Peano arithmetic in ZF. While recursion and the natural numbers are already available in Isabelle/ZF, this clean development is much easier to follow. [LTL_Normal_Form] title = An Efficient Normalisation Procedure for Linear Temporal Logic: Isabelle/HOL Formalisation author = Salomon Sickert topic = Computer science/Automata and formal languages, Logic/General logic/Temporal logic date = 2020-05-08 notify = s.sickert@tum.de abstract = In the mid 80s, Lichtenstein, Pnueli, and Zuck proved a classical theorem stating that every formula of Past LTL (the extension of LTL with past operators) is equivalent to a formula of the form $\bigwedge_{i=1}^n \mathbf{G}\mathbf{F} \varphi_i \vee \mathbf{F}\mathbf{G} \psi_i$, where $\varphi_i$ and $\psi_i$ contain only past operators. Some years later, Chang, Manna, and Pnueli built on this result to derive a similar normal form for LTL. Both normalisation procedures have a non-elementary worst-case blow-up, and follow an involved path from formulas to counter-free automata to star-free regular expressions and back to formulas. We improve on both points. We present an executable formalisation of a direct and purely syntactic normalisation procedure for LTL yielding a normal form, comparable to the one by Chang, Manna, and Pnueli, that has only a single exponential blow-up. [Matrices_for_ODEs] title = Matrices for ODEs author = Jonathan Julian Huerta y Munive topic = Mathematics/Analysis, Mathematics/Algebra date = 2020-04-19 notify = jonjulian23@gmail.com abstract = Our theories formalise various matrix properties that serve to establish existence, uniqueness and characterisation of the solution to affine systems of ordinary differential equations (ODEs). In particular, we formalise the operator and maximum norm of matrices. Then we use them to prove that square matrices form a Banach space, and in this setting, we show an instance of Picard-Lindelöf’s theorem for affine systems of ODEs. Finally, we use this formalisation to verify three simple hybrid programs. [Irrational_Series_Erdos_Straus] title = Irrationality Criteria for Series by Erdős and Straus author = Angeliki Koutsoukou-Argyraki , Wenda Li topic = Mathematics/Number theory, Mathematics/Analysis date = 2020-05-12 notify = ak2110@cam.ac.uk, wl302@cam.ac.uk, liwenda1990@hotmail.com abstract = We formalise certain irrationality criteria for infinite series of the form: \[\sum_{n=1}^\infty \frac{b_n}{\prod_{i=1}^n a_i} \] where $\{b_n\}$ is a sequence of integers and $\{a_n\}$ a sequence of positive integers with $a_n >1$ for all large n. The results are due to P. Erdős and E. G. Straus [1]. In particular, we formalise Theorem 2.1, Corollary 2.10 and Theorem 3.1. The latter is an application of Theorem 2.1 involving the prime numbers. [Knuth_Bendix_Order] title = A Formalization of Knuth–Bendix Orders author = Christian Sternagel , René Thiemann topic = Logic/Rewriting date = 2020-05-13 notify = c.sternagel@gmail.com, rene.thiemann@uibk.ac.at abstract = We define a generalized version of Knuth–Bendix orders, including subterm coefficient functions. For these orders we formalize several properties such as strong normalization, the subterm property, closure properties under substitutions and contexts, as well as ground totality. [Stateful_Protocol_Composition_and_Typing] title = Stateful Protocol Composition and Typing author = Andreas V. Hess , Sebastian Mödersheim , Achim D. Brucker topic = Computer science/Security date = 2020-04-08 notify = avhe@dtu.dk, andreasvhess@gmail.com, samo@dtu.dk, brucker@spamfence.net, andschl@dtu.dk abstract = We provide in this AFP entry several relative soundness results for security protocols. In particular, we prove typing and compositionality results for stateful protocols (i.e., protocols with mutable state that may span several sessions), and that focuses on reachability properties. Such results are useful to simplify protocol verification by reducing it to a simpler problem: Typing results give conditions under which it is safe to verify a protocol in a typed model where only "well-typed" attacks can occur whereas compositionality results allow us to verify a composed protocol by only verifying the component protocols in isolation. The conditions on the protocols under which the results hold are furthermore syntactic in nature allowing for full automation. The foundation presented here is used in another entry to provide fully automated and formalized security proofs of stateful protocols. [Automated_Stateful_Protocol_Verification] title = Automated Stateful Protocol Verification author = Andreas V. Hess , Sebastian Mödersheim , Achim D. Brucker , Anders Schlichtkrull topic = Computer science/Security, Tools date = 2020-04-08 notify = avhe@dtu.dk, andreasvhess@gmail.com, samo@dtu.dk, brucker@spamfence.net, andschl@dtu.dk abstract = In protocol verification we observe a wide spectrum from fully automated methods to interactive theorem proving with proof assistants like Isabelle/HOL. In this AFP entry, we present a fully-automated approach for verifying stateful security protocols, i.e., protocols with mutable state that may span several sessions. The approach supports reachability goals like secrecy and authentication. We also include a simple user-friendly transaction-based protocol specification language that is embedded into Isabelle. [Smith_Normal_Form] title = A verified algorithm for computing the Smith normal form of a matrix author = Jose Divasón topic = Mathematics/Algebra, Computer science/Algorithms/Mathematical date = 2020-05-23 notify = jose.divason@unirioja.es abstract = This work presents a formal proof in Isabelle/HOL of an algorithm to transform a matrix into its Smith normal form, a canonical matrix form, in a general setting: the algorithm is parameterized by operations to prove its existence over elementary divisor rings, while execution is guaranteed over Euclidean domains. We also provide a formal proof on some results about the generality of this algorithm as well as the uniqueness of the Smith normal form. Since Isabelle/HOL does not feature dependent types, the development is carried out switching conveniently between two different existing libraries: the Hermite normal form (based on HOL Analysis) and the Jordan normal form AFP entries. This permits to reuse results from both developments and it is done by means of the lifting and transfer package together with the use of local type definitions. [Nash_Williams] title = The Nash-Williams Partition Theorem author = Lawrence C. Paulson topic = Mathematics/Combinatorics date = 2020-05-16 notify = lp15@cam.ac.uk abstract = In 1965, Nash-Williams discovered a generalisation of the infinite form of Ramsey's theorem. Where the latter concerns infinite sets of n-element sets for some fixed n, the Nash-Williams theorem concerns infinite sets of finite sets (or lists) subject to a “no initial segment” condition. The present formalisation follows a monograph on Ramsey Spaces by Todorčević. [Safe_Distance] title = A Formally Verified Checker of the Safe Distance Traffic Rules for Autonomous Vehicles author = Albert Rizaldi , Fabian Immler topic = Computer science/Algorithms/Mathematical, Mathematics/Physics date = 2020-06-01 notify = albert.rizaldi@ntu.edu.sg, fimmler@andrew.cmu.edu, martin.rau@tum.de abstract = The Vienna Convention on Road Traffic defines the safe distance traffic rules informally. This could make autonomous vehicle liable for safe-distance-related accidents because there is no clear definition of how large a safe distance is. We provide a formally proven prescriptive definition of a safe distance, and checkers which can decide whether an autonomous vehicle is obeying the safe distance rule. Not only does our work apply to the domain of law, but it also serves as a specification for autonomous vehicle manufacturers and for online verification of path planners. [Relational_Paths] title = Relational Characterisations of Paths author = Walter Guttmann , Peter Höfner topic = Mathematics/Graph theory date = 2020-07-13 notify = walter.guttmann@canterbury.ac.nz, peter@hoefner-online.de abstract = Binary relations are one of the standard ways to encode, characterise and reason about graphs. Relation algebras provide equational axioms for a large fragment of the calculus of binary relations. Although relations are standard tools in many areas of mathematics and computing, researchers usually fall back to point-wise reasoning when it comes to arguments about paths in a graph. We present a purely algebraic way to specify different kinds of paths in Kleene relation algebras, which are relation algebras equipped with an operation for reflexive transitive closure. We study the relationship between paths with a designated root vertex and paths without such a vertex. Since we stay in first-order logic this development helps with mechanising proofs. To demonstrate the applicability of the algebraic framework we verify the correctness of three basic graph algorithms. [Amicable_Numbers] title = Amicable Numbers author = Angeliki Koutsoukou-Argyraki topic = Mathematics/Number theory date = 2020-08-04 notify = ak2110@cam.ac.uk abstract = This is a formalisation of Amicable Numbers, involving some relevant material including Euler's sigma function, some relevant definitions, results and examples as well as rules such as Thābit ibn Qurra's Rule, Euler's Rule, te Riele's Rule and Borho's Rule with breeders. [Ordinal_Partitions] title = Ordinal Partitions author = Lawrence C. Paulson topic = Mathematics/Combinatorics, Logic/Set theory date = 2020-08-03 notify = lp15@cam.ac.uk abstract = The theory of partition relations concerns generalisations of Ramsey's theorem. For any ordinal $\alpha$, write $\alpha \to (\alpha, m)^2$ if for each function $f$ from unordered pairs of elements of $\alpha$ into $\{0,1\}$, either there is a subset $X\subseteq \alpha$ order-isomorphic to $\alpha$ such that $f\{x,y\}=0$ for all $\{x,y\}\subseteq X$, or there is an $m$ element set $Y\subseteq \alpha$ such that $f\{x,y\}=1$ for all $\{x,y\}\subseteq Y$. (In both cases, with $\{x,y\}$ we require $x\not=y$.) In particular, the infinite Ramsey theorem can be written in this notation as $\omega \to (\omega, \omega)^2$, or if we restrict $m$ to the positive integers as above, then $\omega \to (\omega, m)^2$ for all $m$. This entry formalises Larson's proof of $\omega^\omega \to (\omega^\omega, m)^2$ along with a similar proof of a result due to Specker: $\omega^2 \to (\omega^2, m)^2$. Also proved is a necessary result by Erdős and Milner: $\omega^{1+\alpha\cdot n} \to (\omega^{1+\alpha}, 2^n)^2$. [Relational_Disjoint_Set_Forests] title = Relational Disjoint-Set Forests author = Walter Guttmann topic = Computer science/Data structures date = 2020-08-26 notify = walter.guttmann@canterbury.ac.nz abstract = We give a simple relation-algebraic semantics of read and write operations on associative arrays. The array operations seamlessly integrate with assignments in the Hoare-logic library. Using relation algebras and Kleene algebras we verify the correctness of an array-based implementation of disjoint-set forests with a naive union operation and a find operation with path compression. [PAC_Checker] title = Practical Algebraic Calculus Checker author = Mathias Fleury , Daniela Kaufmann topic = Computer science/Algorithms date = 2020-08-31 notify = mathias.fleury@jku.at abstract = Generating and checking proof certificates is important to increase the trust in automated reasoning tools. In recent years formal verification using computer algebra became more important and is heavily used in automated circuit verification. An existing proof format which covers algebraic reasoning and allows efficient proof checking is the practical algebraic calculus (PAC). In this development, we present the verified checker Pastèque that is obtained by synthesis via the Refinement Framework. This is the formalization going with our FMCAD'20 tool presentation. [BirdKMP] title = Putting the `K' into Bird's derivation of Knuth-Morris-Pratt string matching author = Peter Gammie topic = Computer science/Functional programming date = 2020-08-25 notify = peteg42@gmail.com abstract = Richard Bird and collaborators have proposed a derivation of an intricate cyclic program that implements the Morris-Pratt string matching algorithm. Here we provide a proof of total correctness for Bird's derivation and complete it by adding Knuth's optimisation. [Extended_Finite_State_Machines] title = A Formal Model of Extended Finite State Machines author = Michael Foster , Achim D. Brucker , Ramsay G. Taylor , John Derrick topic = Computer science/Automata and formal languages date = 2020-09-07 notify = jmafoster1@sheffield.ac.uk, adbrucker@0x5f.org abstract = In this AFP entry, we provide a formalisation of extended finite state machines (EFSMs) where models are represented as finite sets of transitions between states. EFSMs execute traces to produce observable outputs. We also define various simulation and equality metrics for EFSMs in terms of traces and prove their strengths in relation to each other. Another key contribution is a framework of function definitions such that LTL properties can be phrased over EFSMs. Finally, we provide a simple example case study in the form of a drinks machine. [Extended_Finite_State_Machine_Inference] title = Inference of Extended Finite State Machines author = Michael Foster , Achim D. Brucker , Ramsay G. Taylor , John Derrick topic = Computer science/Automata and formal languages date = 2020-09-07 notify = jmafoster1@sheffield.ac.uk, adbrucker@0x5f.org abstract = In this AFP entry, we provide a formal implementation of a state-merging technique to infer extended finite state machines (EFSMs), complete with output and update functions, from black-box traces. In particular, we define the subsumption in context relation as a means of determining whether one transition is able to account for the behaviour of another. Building on this, we define the direct subsumption relation, which lifts the subsumption in context relation to EFSM level such that we can use it to determine whether it is safe to merge a given pair of transitions. Key proofs include the conditions necessary for subsumption to occur and that subsumption and direct subsumption are preorder relations. We also provide a number of different heuristics which can be used to abstract away concrete values into registers so that more states and transitions can be merged and provide proofs of the various conditions which must hold for these abstractions to subsume their ungeneralised counterparts. A Code Generator setup to create executable Scala code is also defined. [Physical_Quantities] title = A Sound Type System for Physical Quantities, Units, and Measurements author = Simon Foster , Burkhart Wolff topic = Mathematics/Physics, Computer science/Programming languages/Type systems date = 2020-10-20 notify = simon.foster@york.ac.uk, wolff@lri.fr abstract = The present Isabelle theory builds a formal model for both the International System of Quantities (ISQ) and the International System of Units (SI), which are both fundamental for physics and engineering. Both the ISQ and the SI are deeply integrated into Isabelle's type system. Quantities are parameterised by dimension types, which correspond to base vectors, and thus only quantities of the same dimension can be equated. Since the underlying "algebra of quantities" induces congruences on quantity and SI types, specific tactic support is developed to capture these. Our construction is validated by a test-set of known equivalences between both quantities and SI units. Moreover, the presented theory can be used for type-safe conversions between the SI system and others, like the British Imperial System (BIS). [Shadow_DOM] title = A Formal Model of the Document Object Model with Shadow Roots author = Achim D. Brucker , Michael Herzberg topic = Computer science/Data structures date = 2020-09-28 notify = adbrucker@0x5f.org, mail@michael-herzberg.de abstract = In this AFP entry, we extend our formalization of the core DOM with Shadow Roots. Shadow roots are a recent proposal of the web community to support a component-based development approach for client-side web applications. Shadow roots are a significant extension to the DOM standard and, as web standards are condemned to be backward compatible, such extensions often result in complex specification that may contain unwanted subtleties that can be detected by a formalization. Our Isabelle/HOL formalization is, in the sense of object-orientation, an extension of our formalization of the core DOM and enjoys the same basic properties, i.e., it is extensible, i.e., can be extended without the need of re-proving already proven properties and executable, i.e., we can generate executable code from our specification. We exploit the executability to show that our formalization complies to the official standard of the W3C, respectively, the WHATWG. [DOM_Components] title = A Formalization of Web Components author = Achim D. Brucker , Michael Herzberg topic = Computer science/Data structures date = 2020-09-28 notify = adbrucker@0x5f.org, mail@michael-herzberg.de abstract = While the DOM with shadow trees provide the technical basis for defining web components, the DOM standard neither defines the concept of web components nor specifies the safety properties that web components should guarantee. Consequently, the standard also does not discuss how or even if the methods for modifying the DOM respect component boundaries. In AFP entry, we present a formally verified model of web components and define safety properties which ensure that different web components can only interact with each other using well-defined interfaces. Moreover, our verification of the application programming interface (API) of the DOM revealed numerous invariants that implementations of the DOM API need to preserve to ensure the integrity of components. [Interpreter_Optimizations] title = Inline Caching and Unboxing Optimization for Interpreters author = Martin Desharnais topic = Computer science/Programming languages/Misc date = 2020-12-07 notify = martin.desharnais@unibw.de abstract = This Isabelle/HOL formalization builds on the VeriComp entry of the Archive of Formal Proofs to provide the following contributions:
  • an operational semantics for a realistic virtual machine (Std) for dynamically typed programming languages;
  • the formalization of an inline caching optimization (Inca), a proof of bisimulation with (Std), and a compilation function;
  • the formalization of an unboxing optimization (Ubx), a proof of bisimulation with (Inca), and a simple compilation function.
This formalization was described in the CPP 2021 paper Towards Efficient and Verified Virtual Machines for Dynamic Languages [Isabelle_Marries_Dirac] title = Isabelle Marries Dirac: a Library for Quantum Computation and Quantum Information author = Anthony Bordg , Hanna Lachnitt, Yijun He topic = Computer science/Algorithms/Quantum computing, Mathematics/Physics/Quantum information date = 2020-11-22 notify = apdb3@cam.ac.uk, lachnitt@stanford.edu abstract = This work is an effort to formalise some quantum algorithms and results in quantum information theory. Formal methods being critical for the safety and security of algorithms and protocols, we foresee their widespread use for quantum computing in the future. We have developed a large library for quantum computing in Isabelle based on a matrix representation for quantum circuits, successfully formalising the no-cloning theorem, quantum teleportation, Deutsch's algorithm, the Deutsch-Jozsa algorithm and the quantum Prisoner's Dilemma. [Finite-Map-Extras] title = Finite Map Extras author = Javier Díaz topic = Computer science/Data structures date = 2020-10-12 notify = javier.diaz.manzi@gmail.com abstract = This entry includes useful syntactic sugar, new operators and functions, and their associated lemmas for finite maps which currently are not present in the standard Finite_Map theory. [Relational_Minimum_Spanning_Trees] title = Relational Minimum Spanning Tree Algorithms author = Walter Guttmann , Nicolas Robinson-O'Brien<> topic = Computer science/Algorithms/Graph date = 2020-12-08 notify = walter.guttmann@canterbury.ac.nz abstract = We verify the correctness of Prim's, Kruskal's and Borůvka's minimum spanning tree algorithms based on algebras for aggregation and minimisation. [Topological_Semantics] title = Topological semantics for paraconsistent and paracomplete logics author = David Fuenmayor topic = Logic/General logic date = 2020-12-17 notify = davfuenmayor@gmail.com abstract = We introduce a generalized topological semantics for paraconsistent and paracomplete logics by drawing upon early works on topological Boolean algebras (cf. works by Kuratowski, Zarycki, McKinsey & Tarski, etc.). In particular, this work exemplarily illustrates the shallow semantical embeddings approach (SSE) employing the proof assistant Isabelle/HOL. By means of the SSE technique we can effectively harness theorem provers, model finders and 'hammers' for reasoning with quantified non-classical logics. [CSP_RefTK] title = The HOL-CSP Refinement Toolkit author = Safouan Taha , Burkhart Wolff , Lina Ye topic = Computer science/Concurrency/Process calculi, Computer science/Semantics date = 2020-11-19 notify = wolff@lri.fr abstract = We use a formal development for CSP, called HOL-CSP2.0, to analyse a family of refinement notions, comprising classic and new ones. This analysis enables to derive a number of properties that allow to deepen the understanding of these notions, in particular with respect to specification decomposition principles for the case of infinite sets of events. The established relations between the refinement relations help to clarify some obscure points in the CSP literature, but also provide a weapon for shorter refinement proofs. Furthermore, we provide a framework for state-normalisation allowing to formally reason on parameterised process architectures. As a result, we have a modern environment for formal proofs of concurrent systems that allow for the combination of general infinite processes with locally finite ones in a logically safe way. We demonstrate these verification-techniques for classical, generalised examples: The CopyBuffer for arbitrary data and the Dijkstra's Dining Philosopher Problem of arbitrary size. [Hood_Melville_Queue] title = Hood-Melville Queue author = Alejandro Gómez-Londoño topic = Computer science/Data structures date = 2021-01-18 notify = nipkow@in.tum.de -abstract = +abstract = This is a verified implementation of a constant time queue. The original design is due to Hood and Melville. This formalization follows the presentation in Purely Functional Data Structuresby Okasaki. +[JinjaDCI] +title = JinjaDCI: a Java semantics with dynamic class initialization +author = Susannah Mansky +topic = Computer science/Programming languages/Language definitions +date = 2021-01-11 +notify = sjohnsn2@illinois.edu, susannahej@gmail.com +abstract = + We extend Jinja to include static fields, methods, and instructions, + and dynamic class initialization, based on the Java SE 8 + specification. This includes extension of definitions and proofs. This + work is partially described in Mansky and Gunter's paper at CPP + 2019 and Mansky's doctoral thesis (UIUC, 2020). + diff --git a/thys/Hood_Melville_Queue/Hood_Melville_Queue.thy b/thys/Hood_Melville_Queue/Hood_Melville_Queue.thy --- a/thys/Hood_Melville_Queue/Hood_Melville_Queue.thy +++ b/thys/Hood_Melville_Queue/Hood_Melville_Queue.thy @@ -1,752 +1,789 @@ theory Hood_Melville_Queue imports "HOL-Data_Structures.Queue_Spec" begin (* All the possible states a queue can be in *) datatype 'a status = (* front \ rear the queue operates like a normal split queue *) Idle (* The queue is performing the first step to create the new front *) | Rev nat "'a list" "'a list" "'a list" "'a list" (* Finishing creating the new front *) | App nat "'a list" "'a list" (* The new front is ready *) | Done "'a list" (* A queue with constant time dequeue and enqueue *) record 'a queue = lenf :: nat (* length of the front *) front :: "'a list" (* front of the queue *) status :: "'a status" (* status representing intermediate operations *) rear :: "'a list" (* rear of the queue *) lenr :: nat (* length of the rear *) (* exec performs a single step towards creating the new front by reversing the rear and appending the front *) fun exec :: "'a status \ 'a status" where "exec (Rev ok (x#f) f' (y#r) r') = Rev (ok+1) f (x#f') r (y#r')" | "exec (Rev ok [] f' [y] r') = App ok f' (y#r')" | "exec (App 0 f' r') = Done r' " | "exec (App ok (x#f') r') = App (ok-1) f' (x#r')" | "exec s = s" (* When a deq is performed decreases the number keeping track of how many element of the original queue should be used *) fun invalidate where "invalidate (Rev ok f f' r r') = Rev (ok-1) f f' r r'" | "invalidate (App 0 f' (x#r')) = Done r'" | "invalidate (App ok f' r') = App (ok-1) f' r'" | "invalidate s = s" (* Performs 2 steps and deals with the result *) fun exec2 :: "'a queue \ 'a queue" where "exec2 q = (case exec (exec (status q)) of Done newf \ q\status := Idle,front := newf\ | newstate \ q\status := newstate\)" (* Checks if the rear has became greater than the front, in which case the rear is cleared and a process to generate a new front is started, otherwise the queue functions normally *) definition check :: "'a queue \ 'a queue" where "check q = (if lenr q \ lenf q then exec2 q else let newstate = Rev 0 (front q) [] (rear q) [] in exec2 (q\lenf := lenf q + lenr q, status := newstate, rear := [], lenr := 0\))" (* empty queue *) definition empty :: "'a queue" where "empty = queue.make 0 [] Idle [] 0" (* Enqueue operation *) fun enq where "enq x q = check (q\rear := x#(rear q), lenr := lenr q + 1\)" (* Dequeue opertion *) fun deq where "deq q = check (q\ lenf := lenf q - 1 , front := tl (front q) , status := invalidate (status q)\)" (* Computes the "true" front of a queue *) fun front_list :: "'a queue \ 'a list" where "front_list q = (case status q of Idle \ front q | Done f \ f | Rev ok f f' r r' \ rev (take ok f') @ f @ rev r @ r' | App ok f' r' \ rev (take ok f') @ r')" (* Rear of the queue in the proper order (oldest element in head) *) definition rear_list :: "'a queue \ 'a list" where "rear_list = rev o rear" (* Queue to list projection *) fun list :: "'a queue \ 'a list" where "list q = front_list q @ rear_list q" (* Query operation (irrelevant) *) fun first where - "first q = hd (front_list q)" + "first q = hd (front q)" (* How many applications of exec are needed to reach Idle or Done status *) fun rem_steps :: "'a status \ nat" where "rem_steps (Rev ok f f' r r') = 2*length f + ok + 2" | "rem_steps (App ok f' r') = ok + 1" | "rem_steps _ = 0" (* Status invariants *) fun st_inv :: "'a status \ bool" where "st_inv (Rev ok f f' r r') = (length f + 1 = length r \ length f' = length r' \ ok \ length f')" | "st_inv (App ok f' r') = (ok \ length f' \ length f' < length r')" | "st_inv _ = True" fun steps :: "nat \ 'a status \ 'a status" where "steps n st = (exec ^^ n) st" lemma rev_steps_app: assumes inv: "st_inv (Rev ok f f' r r')" shows "steps (length f + 1) (Rev ok f f' r r') = App (length f + ok) (rev f @ f') (rev r @ r')" proof - show ?thesis using inv proof (induction f arbitrary: ok f' r r') case Nil then obtain x where "r = [x]" by (metis One_nat_def Suc_length_conv add.right_neutral add_Suc_right length_0_conv st_inv.simps(1)) then show ?case using Nil by simp next case (Cons a f) then obtain x and xs where "r = x # xs" by (metis One_nat_def Suc_length_conv add_Suc_right st_inv.simps(1)) hence r_x: "r = x # xs" by simp then show ?case using Cons Nat.funpow_add by (simp add: Nat.funpow_swap1) qed qed lemma st_inv_steps: assumes inv : "st_inv s" assumes not_idle : "s \ Idle" shows "\x. steps (rem_steps s) s = Done x" (is "?reach_done s") proof - let ?steps = "\x. steps (rem_steps x)" have app_inv: "st_inv (App ok f r) \ ?reach_done (App ok f r)" for ok f r proof (induct f arbitrary: ok r) case (Cons a f') then show ?case by (induct ok; simp add: Nat.funpow_swap1) qed simp show ?thesis proof (cases s) case (App ok f' r') then show ?thesis using inv app_inv unfolding App by simp next case (Rev ok f f' r r') have rep_split: "rem_steps (Rev ok f f' r r') = (length f + ok + 1) + (length f + 1)" by simp then have split: "\stp. ?steps (Rev ok f f' r r') stp = (steps (length f + ok + 1)) ((steps (length f + 1)) stp) " unfolding rep_split Nat.funpow_add steps.simps by simp also have f: "st_inv (App (length f + ok) (rev f @ f') (rev r @ r'))" using Rev inv by simp thus ?thesis using inv f[THEN app_inv] unfolding Rev split inv[simplified Rev,THEN rev_steps_app] by simp qed (auto simp add: not_idle) qed (* Preservation of the status invariants by exec2 *) lemma st_inv_exec: assumes st_inv: "st_inv s" shows "st_inv (exec s)" proof (cases s) next case (Rev ok f f' r r') show ?thesis proof (cases f) case Nil then show ?thesis using st_inv unfolding Rev by (simp; cases r;cases ok; cases f'; simp) next case C_a: (Cons a as) then obtain x xs where "r = x # xs" using st_inv unfolding Rev Cons by (metis One_nat_def length_Suc_conv list.size(4) st_inv.simps(1)) hence r_x: "r = x # xs" by simp then show ?thesis proof (cases as) case Nil then show ?thesis using st_inv unfolding Rev C_a Nil r_x by (simp; cases xs; simp) next case (Cons b bs) then show ?thesis using st_inv unfolding Rev C_a r_x by (simp; cases xs; simp) qed qed next case (App ok f r) then show ?thesis proof (cases ok) case (Suc ok') then obtain x xs where "f = x # xs" using st_inv unfolding App Suc by (metis Suc_le_D Zero_not_Suc list.exhaust list.size(3) st_inv.simps(2)) then show ?thesis using st_inv unfolding App Suc by (cases ok'; cases xs; simp) qed simp qed simp+ (* Preservation of the status invariants by exec2 *) lemma st_inv_exec2: assumes st_inv: "st_inv s" shows "st_inv (exec (exec s))" proof - show ?thesis using st_inv st_inv_exec by auto qed lemma st_inv_invalidate: assumes st_inv: "st_inv s" shows "st_inv (invalidate s)" proof (cases s) next case (Rev ok f f' r r') show ?thesis using st_inv unfolding Rev by auto next case (App ok f r) then show ?thesis using st_inv unfolding App by (cases ok; cases r; simp) qed simp+ (* Queue invariants *) definition invar where "invar q = (lenf q = length (front_list q) \ lenr q = length (rear_list q) \ lenr q \ lenf q \ (case status q of - Rev ok f f' r r' \ 2*lenr q \ length f' \ ok \ 0 + Rev ok f f' r r' \ 2*lenr q \ length f' \ ok \ 0 | App ok f r \ 2*lenr q \ length r | _ \ True) \ rem_steps (status q) \ 2*length (front q) \ + (\rest. front_list q = front q @ rest) \ (\x. status q \ Done x) \ st_inv (status q))" (* The empty list satisfies the invariant *) lemma invar_empty: "invar empty" by(simp add: invar_def empty_def make_def rear_list_def) +(* List lemmas *) + +lemma tl_rev_take: "\0 < ok; ok \ length f\ \ rev (take ok (x # f)) = tl (rev (take ok f)) @ [x]" +by(simp add: rev_take Suc_diff_le drop_Suc tl_drop) + +lemma tl_rev_take_Suc: + "n + 1 \ length l \ rev (take n l) = tl (rev (take (Suc n) l))" +by(simp add: rev_take tl_drop Suc_diff_Suc flip: drop_Suc) + (* Dequeue operations preserve the invariants *) lemma invar_deq: assumes inv: "invar q" shows "invar (deq q)" proof (cases q) case (fields lenf front status rear lenr) + have pre_inv: "\rest. front @ rest = front_list q" using inv unfolding fields + by(simp add: invar_def check_def; cases status; auto simp add: invar_def Let_def rear_list_def) + have tl_app: "status \ Idle \ \l. tl front @ l = tl (front @ l)" using inv unfolding fields + by (simp add: invar_def check_def; cases status; cases front;auto simp add: invar_def Let_def rear_list_def) then show ?thesis proof (cases status rule: exec.cases) case st: (1 ok x f f' y r r') then show ?thesis proof (cases f) case Nil - then show ?thesis using inv unfolding fields st Nil - by (simp add: invar_def check_def rear_list_def; cases r; auto simp add: min_absorb2 invar_def rear_list_def Let_def) + have pre: "\rest. front_list (deq q) = tl front @ rest" using inv pre_inv unfolding fields st Nil + apply (simp add: invar_def check_def; cases r; simp add: invar_def Let_def rear_list_def) + apply (erule exE) + apply (rule_tac x=rest in exI) + apply (simp add: tl_app st tl_rev_take) + apply (cases f'; auto) + done + then show ?thesis using inv unfolding fields st Nil + by (simp add: invar_def check_def rear_list_def; cases r; auto simp add: min_absorb2 invar_def rear_list_def Let_def) next case (Cons a list) - then show ?thesis using inv check_def rear_list_def - unfolding fields st Nil invar_def check_def rear_list_def - by (simp; cases r; auto simp add: min_absorb2 check_def) + then show ?thesis using pre_inv inv + unfolding fields st Nil + apply (simp add: invar_def check_def inv ; cases r; simp add: invar_def inv min_absorb2 rear_list_def) + apply (erule exE) + apply (rule conjI, force) + apply (rule_tac x=rest in exI) + apply (simp add: tl_app st tl_rev_take) + apply (cases f'; auto) + done qed next case st: (2 ok f y r) then show ?thesis proof(cases ok) case ok: 0 then show ?thesis using inv unfolding fields st by (simp add: invar_def check_def rear_list_def) next case (Suc ok') obtain fx fs where "f = fx # fs" using inv lessI less_le_trans not_less_zero unfolding fields st Suc invar_def by (metis list.exhaust list.size(3) select_convs(3) st_inv.simps(1)) hence f_x: "f = fx # fs" by simp obtain rx rs where "r = rx # rs" using inv lessI less_le_trans not_less_zero unfolding fields st Suc invar_def by (metis list.exhaust list.size(3) select_convs(3) st_inv.simps(1)) hence r_x: "r = rx # rs" by simp - then show ?thesis using inv unfolding fields st Suc invar_def rear_list_def r_x f_x - by (simp add: check_def; cases ok'; simp add: check_def min_absorb2; linarith) + then show ?thesis using pre_inv inv unfolding fields st Suc invar_def rear_list_def r_x f_x + apply (simp add: check_def; cases ok'; simp add: check_def min_absorb2) + apply (erule exE) + apply (rule conjI, arith) + apply (rule_tac x=rest in exI) + apply (simp add: tl_app st tl_rev_take_Suc) + by (metis Suc_le_length_iff length_take list.sel(3) min_absorb2 n_not_Suc_n rev_is_Nil_conv take_tl tl_Nil tl_append2) qed next case st: (3 f r) show ?thesis using inv unfolding fields st by(cases r; simp add: invar_def check_def rear_list_def) next case st: (4 ok x f r) then show ?thesis proof(cases ok) case 0 then show ?thesis using inv unfolding fields st invar_def rear_list_def by (simp add: check_def) next case (Suc ok') - then show ?thesis using inv unfolding fields st invar_def rear_list_def Suc - by (cases f; cases ok'; auto simp add: invar_def rear_list_def check_def min_absorb2) + then show ?thesis using pre_inv inv unfolding fields st invar_def rear_list_def Suc + apply (cases f; cases ok'; simp add: invar_def rear_list_def check_def min_absorb2) + apply (erule exE) + apply (rule conjI, arith) + apply (rule_tac x=rest in exI) + apply (simp add: tl_app st tl_rev_take_Suc) + by (metis length_take list.size(3) min.absorb2 nat.distinct(1) rev.simps(1) rev_rev_ident tl_append2) qed next case st: "5_1" then show ?thesis proof (cases "lenr \ lenf - 1") case True then show ?thesis using inv unfolding st fields by (simp add: check_def rear_list_def invar_def) next case overflows: False then have f_eq_r: "length front = length rear" using inv unfolding st fields by (simp add: le_antisym rear_list_def invar_def) then show ?thesis proof (cases front) case Nil show ?thesis using inv overflows unfolding st fields Nil by (cases rear; auto simp add: rear_list_def check_def Let_def invar_def) next case C_a : (Cons a as) then obtain x xs where "rear = x # xs" using inv overflows unfolding st fields Cons invar_def by (metis f_eq_r length_Suc_conv C_a) hence rear_x: "rear = x # xs" by simp then show ?thesis proof (cases as) case Nil then show ?thesis using inv overflows unfolding st fields Nil rear_x C_a by (cases xs; simp add: invar_def check_def Let_def rear_list_def) next case (Cons b bs) then show ?thesis using inv overflows unfolding st fields Cons rear_x C_a invar_def by (cases xs; cases bs; simp add: check_def Let_def rear_list_def) qed qed qed next case st: "5_2" then show ?thesis using inv unfolding fields st by (simp add: invar_def inv fields st) next case st: "5_3" then show ?thesis using inv unfolding fields st by (simp add: invar_def) next case st: "5_4" then show ?thesis using inv unfolding fields st by (simp add: invar_def) next case st: "5_5" then show ?thesis using inv unfolding fields st by (simp add: invar_def) next case st: ("5_6" v) then show ?thesis using inv unfolding fields st by (simp add: invar_def) qed qed (* Enqueue operation preserv the invariants *) lemma invar_enq: assumes inv: "invar q" shows "invar (enq x q)" proof (cases q) case (fields lenf front status rear lenr) then show ?thesis proof(cases status rule: exec.cases) case st: (1 ok x f f' y r r') then show ?thesis proof (cases f) case Nil then show ?thesis using inv unfolding fields st Nil by (simp add: invar_def check_def rear_list_def; cases r; auto simp add: min_absorb2 invar_def rear_list_def Let_def) next case (Cons a list) then show ?thesis using inv check_def rear_list_def unfolding fields st Nil invar_def check_def rear_list_def by (simp; cases r; auto simp add: min_absorb2 check_def) qed next case st: (2 ok f y r) then show ?thesis proof(cases ok) case ok: 0 then show ?thesis using inv unfolding fields st by (simp add: invar_def check_def rear_list_def) next case (Suc ok') obtain fx fs where "f = fx # fs" using inv lessI less_le_trans not_less_zero unfolding fields st Suc invar_def by (metis list.exhaust list.size(3) select_convs(3) st_inv.simps(1)) hence f_x: "f = fx # fs" by simp obtain rx rs where "r = rx # rs" using inv lessI less_le_trans not_less_zero unfolding fields st Suc invar_def by (metis list.exhaust list.size(3) select_convs(3) st_inv.simps(1)) hence r_x: "r = rx # rs" by simp then show ?thesis using inv unfolding fields st Suc invar_def rear_list_def r_x f_x by (simp add: check_def; cases ok'; simp add: check_def min_absorb2) qed next case st: (3 f r) then show ?thesis proof(cases r) case Nil then show ?thesis using inv unfolding fields st by(simp add: check_def rear_list_def Let_def invar_def) next case (Cons a list) then show ?thesis using inv unfolding fields st by (simp add: check_def rear_list_def Let_def invar_def) qed next case st: (4 ok x f r) then show ?thesis proof(cases ok) case 0 then show ?thesis using inv unfolding fields st invar_def rear_list_def by (simp add: check_def) next case (Suc ok') then show ?thesis using inv unfolding fields st invar_def rear_list_def Suc by (cases f; cases ok'; auto simp add: invar_def rear_list_def check_def min_absorb2) qed next case st: "5_1" then show ?thesis proof (cases "lenr + 1 \ lenf") case True then show ?thesis using inv unfolding st fields by (simp add: check_def rear_list_def invar_def) next case overflows: False then have f_eq_r: "length front = length rear" using inv unfolding st fields by (simp add: le_antisym rear_list_def invar_def) then show ?thesis proof (cases front) case Nil show ?thesis using inv overflows unfolding st fields Nil by (cases rear; auto simp add: rear_list_def check_def Let_def invar_def) next case C_a : (Cons a as) then obtain x xs where "rear = x # xs" using inv overflows unfolding st fields Cons invar_def by (metis f_eq_r length_Suc_conv C_a) hence rear_x: "rear = x # xs" by simp then show ?thesis proof (cases as) case Nil then show ?thesis using inv overflows unfolding st fields Nil rear_x C_a by (cases xs; simp add: invar_def check_def Let_def rear_list_def) next case (Cons b bs) then show ?thesis using inv overflows unfolding st fields Cons rear_x C_a invar_def by (cases xs; cases bs; simp add: check_def Let_def rear_list_def) qed qed qed next case st: "5_2" then show ?thesis using inv unfolding fields st by (simp add: invar_def) next case st: "5_3" then show ?thesis using inv unfolding fields st by (simp add: invar_def) next case st: "5_4" then show ?thesis using inv unfolding fields st by (simp add: invar_def) next case st: "5_5" then show ?thesis using inv unfolding fields st by (simp add: invar_def) next case st: "5_6" then show ?thesis using inv unfolding fields st by (simp add: invar_def) qed qed -(* List lemmas *) - -lemma tl_rev_take: "\0 < ok; ok \ length f\ \ rev (take ok (x # f)) = tl (rev (take ok f)) @ [x]" -by(simp add: rev_take Suc_diff_le drop_Suc tl_drop) - -lemma tl_rev_take_Suc: - "n + 1 \ length l \ rev (take n l) = tl (rev (take (Suc n) l))" -by(simp add: rev_take tl_drop Suc_diff_Suc flip: drop_Suc) - (* Correctness proof of the dequeue operation *) lemma queue_correct_deq : assumes inv: "invar q" shows "list (deq q) = tl (list q)" proof (cases q) case (fields lenf front status rear lenr) have inv_deq: "invar (deq q)" using inv invar_deq by simp then show ?thesis proof (cases status rule: exec.cases) case st: (1 ok x f f' y r r') then show ?thesis using inv inv_deq unfolding st fields apply (cases f; cases r; simp add: invar_def check_def rear_list_def min_absorb2 tl_rev_take) by (metis le_zero_eq length_take list.size(3) min.absorb2 not_le rev_is_Nil_conv tl_append2)+ next case st: (2 ok f y r) then show ?thesis proof(cases ok) case ok: 0 then show ?thesis using inv unfolding fields st by (simp add: invar_def check_def rear_list_def) next case (Suc ok') then show ?thesis using inv inv_deq unfolding fields st Suc invar_def apply (cases f; cases r; cases ok'; simp add: check_def min_absorb2 rear_list_def tl_rev_take_Suc) by (metis (no_types) length_greater_0_conv less_le_trans old.nat.distinct(2) rev_is_Nil_conv take_eq_Nil tl_append2 zero_less_Suc) qed next case st: (3 f r) then show ?thesis using inv inv_deq unfolding st fields by (cases f; cases r; simp add: invar_def check_def rear_list_def) next case st: (4 ok x f r) then show ?thesis proof(cases ok) case 0 then show ?thesis using inv inv_deq unfolding fields st invar_def rear_list_def by (simp add: check_def rear_list_def) next case (Suc ok') then show ?thesis using inv inv_deq unfolding fields st invar_def rear_list_def Suc apply (cases f; cases ok'; auto simp add: rear_list_def check_def min_absorb2 tl_rev_take_Suc) by (metis Nitpick.size_list_simp(2) length_rev length_take min.absorb2 nat.simps(3) tl_append2) qed next case st: "5_1" then show ?thesis proof (cases "lenr \ lenf - 1") case True then show ?thesis using inv inv_deq Nil_is_rev_conv append_Nil diff_is_0_eq diff_zero length_0_conv unfolding st fields by (simp add: check_def rear_list_def invar_def; metis list.sel(2) tl_append2) next case overflows: False then have f_eq_r: "length front = length rear" using inv unfolding st fields by (simp add: le_antisym rear_list_def invar_def) then show ?thesis proof (cases front) case Nil show ?thesis using inv overflows inv_deq unfolding st fields Nil by (cases rear; auto simp add: rear_list_def check_def Let_def invar_def) next case C_a : (Cons a as) then obtain x xs where "rear = x # xs" using inv overflows unfolding st fields Cons invar_def by (metis f_eq_r length_Suc_conv C_a) hence rear_x: "rear = x # xs" by simp then show ?thesis proof (cases as) case Nil then show ?thesis using inv overflows unfolding st fields Nil rear_x C_a by (cases xs; simp add: invar_def check_def Let_def rear_list_def) next case (Cons b bs) then show ?thesis using inv overflows unfolding st fields Cons rear_x C_a invar_def by (cases xs; cases bs; simp add: check_def Let_def rear_list_def) qed qed qed next case st: "5_2" then show ?thesis using inv inv_deq unfolding st fields by (simp add: invar_def check_def rear_list_def) next case st: "5_3" then show ?thesis using inv inv_deq unfolding st fields by (simp add: invar_def check_def rear_list_def) next case st: "5_4" then show ?thesis using inv inv_deq unfolding st fields by (simp add: invar_def check_def rear_list_def) next case st: "5_5" then show ?thesis using inv inv_deq unfolding st fields by (simp add: invar_def check_def rear_list_def) next case st: "5_6" then show ?thesis using inv inv_deq unfolding st fields by (simp add: invar_def check_def rear_list_def) qed qed (* Correctness proof of the enqueue operation *) lemma queue_correct_enq : assumes inv: "invar q" shows "list (enq x q) = (list q) @ [x]" proof (cases q) case (fields lenf front status rear lenr) have inv_deq: "invar (enq x q)" using inv invar_enq by simp then show ?thesis proof (cases status rule: exec.cases) case st: (1 ok x f f' y r r') then show ?thesis using inv inv_deq unfolding st fields by (cases f; cases r; simp add: invar_def check_def rear_list_def min_absorb2 tl_rev_take) next case st: (2 ok f y r) then show ?thesis proof(cases ok) case ok: 0 then show ?thesis using inv unfolding fields st by (simp add: invar_def check_def rear_list_def) next case (Suc ok') then show ?thesis using inv inv_deq unfolding fields st Suc invar_def by (cases f; cases r; cases ok'; simp add: check_def min_absorb2 rear_list_def tl_rev_take_Suc) qed next case st: (3 f r) then show ?thesis using inv inv_deq unfolding st fields by (cases f; cases r; simp add: invar_def check_def rear_list_def) next case st: (4 ok x f r) then show ?thesis proof(cases ok) case 0 then show ?thesis using inv inv_deq unfolding fields st invar_def rear_list_def by (simp add: check_def rear_list_def) next case (Suc ok') then show ?thesis using inv inv_deq unfolding fields st invar_def rear_list_def Suc by (cases f; cases ok'; auto simp add: rear_list_def check_def min_absorb2 tl_rev_take_Suc) qed next case st: "5_1" then show ?thesis proof (cases "lenr + 1 \ lenf") case True then show ?thesis using inv inv_deq Nil_is_rev_conv append_Nil diff_is_0_eq diff_zero length_0_conv unfolding st fields by (simp add: check_def rear_list_def invar_def; metis list.sel(2) tl_append2) next case overflows: False then have f_eq_r: "length front = length rear" using inv unfolding st fields by (simp add: le_antisym rear_list_def invar_def) then show ?thesis proof (cases front) case Nil show ?thesis using inv overflows inv_deq unfolding st fields Nil by (cases rear; auto simp add: rear_list_def check_def Let_def invar_def) next case C_a : (Cons a as) then obtain x xs where "rear = x # xs" using inv overflows unfolding st fields Cons invar_def by (metis f_eq_r length_Suc_conv C_a) hence rear_x: "rear = x # xs" by simp then show ?thesis proof (cases as) case Nil then show ?thesis using inv overflows unfolding st fields Nil rear_x C_a by (cases xs; simp add: invar_def check_def Let_def rear_list_def) next case (Cons b bs) then show ?thesis using inv overflows unfolding st fields Cons rear_x C_a invar_def by (cases xs; cases bs; simp add: check_def Let_def rear_list_def) qed qed qed next case st: "5_2" then show ?thesis using inv inv_deq unfolding st fields by (simp add: invar_def check_def rear_list_def) next case st: "5_3" then show ?thesis using inv inv_deq unfolding st fields by (simp add: invar_def check_def rear_list_def) next case st: "5_4" then show ?thesis using inv inv_deq unfolding st fields by (simp add: invar_def check_def rear_list_def) next case st: "5_5" then show ?thesis using inv inv_deq unfolding st fields by (simp add: invar_def check_def rear_list_def) next case st: "5_6" then show ?thesis using inv inv_deq unfolding st fields by (simp add: invar_def check_def rear_list_def) qed qed (* Constructive approach *) datatype 'a action = Deq | Enq 'a type_synonym 'a actions = "'a action list" (* Perform a given action on the queue *) fun do_act :: "'a action \ 'a queue \ 'a queue" where "do_act Deq q = deq q" | "do_act (Enq x) q = enq x q" (* Create a queue from a list of actions *) definition qfa :: "'a actions \ 'a queue" where "qfa = (\acts. foldr do_act acts empty)" (* Any queue created from list of actions satisfies the invariants *) lemma invar_qfa : "invar (qfa l)" proof(induction l) case Nil then show ?case by (simp add: qfa_def invar_empty) next case (Cons x xs) have qfa_cons: "qfa (x#xs) = do_act x (qfa xs)" by (simp add: qfa_def) then show ?case proof(cases x) case Deq then show ?thesis using invar_deq[of "qfa xs"] unfolding qfa_cons by (simp add: Cons) next case (Enq a) then show ?thesis using invar_enq[of "qfa xs"] unfolding qfa_cons by (simp add: Cons) qed qed (* Correctness proof *) lemma qfa_deq_correct: "list (deq (qfa l)) = tl (list (qfa l))" using invar_qfa queue_correct_deq by blast lemma qfa_enq_correct: "list (enq x (qfa l)) = (list (qfa l)) @ [x]" by (meson invar_qfa queue_correct_enq) fun rev_steps :: "('a list \ 'a list) \ ('a list \ 'a list)" where "rev_steps ((x#xs),ys) = (xs,x#ys)" | "rev_steps l = l" lemma first_correct : assumes inv: "invar q" assumes not_nil : "list q \ []" - shows "first q = hd(list q)" -proof (cases "front_list q") + shows "first q = hd (list q)" +proof (cases "front q") + obtain rest where front_l: "front_list q = front q @ rest" + using inv + by (auto simp add: invar_def simp del: front_list.simps) case front_nil: Nil - have rear_Nil: "rear_list q = []" using invar_def front_nil inv by force - then show ?thesis by simp + have rear_nil: "rear_list q = []" using inv unfolding invar_def rear_list_def front_nil + by (simp; cases "status q"; simp add: front_nil) + have front_nil: "front_list q = []" using inv unfolding invar_def rear_list_def front_nil + by (simp; cases "status q"; simp add: front_nil) + show ?thesis using not_nil unfolding list.simps rear_nil front_nil + by simp next - case (Cons a list) - then show ?thesis by simp + case front_cons: (Cons x xs) + show ?thesis using inv unfolding list.simps first.simps front_cons front_list.simps + apply (simp add: invar_def rear_list_def) + by (metis append_Cons front_cons list.sel(1)) qed fun is_empty :: "'a queue \ bool" where "is_empty q = (list q = [])" interpretation HMQ: Queue where empty = empty and enq = enq and first = first and deq = deq and is_empty = is_empty and list = list and invar = invar proof (standard, goal_cases) case 1 thus ?case by (simp add: empty_def make_def rear_list_def) next case 2 thus ?case using queue_correct_enq by simp next case 3 thus ?case using queue_correct_deq by simp next case 4 thus ?case using first_correct by simp next case 5 thus ?case by simp next case 6 thus ?case by (simp add: empty_def invar_def make_def rear_list_def) next case 7 thus ?case using invar_enq by simp next case 8 thus ?case using invar_deq by simp qed end \ No newline at end of file diff --git a/thys/JinjaDCI/BV/BVConform.thy b/thys/JinjaDCI/BV/BVConform.thy new file mode 100644 --- /dev/null +++ b/thys/JinjaDCI/BV/BVConform.thy @@ -0,0 +1,431 @@ +(* Title: JinjaDCI/BV/BVConform.thy + + Author: Cornelia Pusch, Gerwin Klein, Susannah Mansky + Copyright 1999 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory BV/BVConform.thy by Cornelia Pusch and Gerwin Klein + +The invariant for the type safety proof. +*) + +section \ BV Type Safety Invariant \ + +theory BVConform +imports BVSpec "../JVM/JVMExec" "../Common/Conform" +begin + +subsection \ @{text "correct_state"} definitions \ + +definition confT :: "'c prog \ heap \ val \ ty err \ bool" + ("_,_ \ _ :\\<^sub>\ _" [51,51,51,51] 50) +where + "P,h \ v :\\<^sub>\ E \ case E of Err \ True | OK T \ P,h \ v :\ T" + +notation (ASCII) + confT ("_,_ |- _ :<=T _" [51,51,51,51] 50) + +abbreviation + confTs :: "'c prog \ heap \ val list \ ty\<^sub>l \ bool" + ("_,_ \ _ [:\\<^sub>\] _" [51,51,51,51] 50) where + "P,h \ vs [:\\<^sub>\] Ts \ list_all2 (confT P h) vs Ts" + +notation (ASCII) + confTs ("_,_ |- _ [:<=T] _" [51,51,51,51] 50) + +fun Called_context :: "jvm_prog \ cname \ instr \ bool" where +"Called_context P C\<^sub>0 (New C') = (C\<^sub>0=C')" | +"Called_context P C\<^sub>0 (Getstatic C F D) = ((C\<^sub>0=D) \ (\t. P \ C has F,Static:t in D))" | +"Called_context P C\<^sub>0 (Putstatic C F D) = ((C\<^sub>0=D) \ (\t. P \ C has F,Static:t in D))" | +"Called_context P C\<^sub>0 (Invokestatic C M n) + = (\Ts T m D. (C\<^sub>0=D) \ P \ C sees M,Static:Ts \ T = m in D)" | +"Called_context P _ _ = False" + +abbreviation Called_set :: "instr set" where +"Called_set \ {i. \C. i = New C} \ {i. \C M n. i = Invokestatic C M n} + \ {i. \C F D. i = Getstatic C F D} \ {i. \C F D. i = Putstatic C F D}" + +lemma Called_context_Called_set: + "Called_context P D i \ i \ Called_set" by(cases i, auto) + +fun valid_ics :: "jvm_prog \ heap \ sheap \ cname \ mname \ pc \ init_call_status \ bool" + ("_,_,_ \\<^sub>i _" [51,51,51,51] 50) where +"valid_ics P h sh (C,M,pc,Calling C' Cs) + = (let ins = instrs_of P C M in Called_context P (last (C'#Cs)) (ins!pc) + \ is_class P C')" | +"valid_ics P h sh (C,M,pc,Throwing Cs a) + =(let ins = instrs_of P C M in \C1. Called_context P C1 (ins!pc) + \ (\obj. h a = Some obj))" | +"valid_ics P h sh (C,M,pc,Called Cs) + = (let ins = instrs_of P C M + in \C1 sobj. Called_context P C1 (ins!pc) \ sh C1 = Some sobj)" | +"valid_ics P _ _ _ = True" + +definition conf_f :: "jvm_prog \ heap \ sheap \ ty\<^sub>i \ bytecode \ frame \ bool" +where + "conf_f P h sh \ \(ST,LT) is (stk,loc,C,M,pc,ics). + P,h \ stk [:\] ST \ P,h \ loc [:\\<^sub>\] LT \ pc < size is \ P,h,sh \\<^sub>i (C,M,pc,ics)" + +lemma conf_f_def2: + "conf_f P h sh (ST,LT) is (stk,loc,C,M,pc,ics) \ + P,h \ stk [:\] ST \ P,h \ loc [:\\<^sub>\] LT \ pc < size is \ P,h,sh \\<^sub>i (C,M,pc,ics)" + by (simp add: conf_f_def) + +primrec conf_fs :: "[jvm_prog,heap,sheap,ty\<^sub>P,cname,mname,nat,ty,frame list] \ bool" +where + "conf_fs P h sh \ C\<^sub>0 M\<^sub>0 n\<^sub>0 T\<^sub>0 [] = True" +| "conf_fs P h sh \ C\<^sub>0 M\<^sub>0 n\<^sub>0 T\<^sub>0 (f#frs) = + (let (stk,loc,C,M,pc,ics) = f in + (\ST LT b Ts T mxs mxl\<^sub>0 is xt. + \ C M ! pc = Some (ST,LT) \ + (P \ C sees M,b:Ts \ T = (mxs,mxl\<^sub>0,is,xt) in C) \ + ((\D Ts' T' m D'. M\<^sub>0 \ clinit \ ics = No_ics \ + is!pc = Invoke M\<^sub>0 n\<^sub>0 \ ST!n\<^sub>0 = Class D \ + P \ D sees M\<^sub>0,NonStatic:Ts' \ T' = m in D' \ P \ C\<^sub>0 \\<^sup>* D' \ P \ T\<^sub>0 \ T') \ + (\D Ts' T' m. M\<^sub>0 \ clinit \ ics = No_ics \ + is!pc = Invokestatic D M\<^sub>0 n\<^sub>0 \ + P \ D sees M\<^sub>0,Static:Ts' \ T' = m in C\<^sub>0 \ P \ T\<^sub>0 \ T') \ + (M\<^sub>0 = clinit \ (\Cs. ics = Called Cs))) \ + conf_f P h sh (ST, LT) is f \ conf_fs P h sh \ C M (size Ts) T frs))" + +fun ics_classes :: "init_call_status \ cname list" where +"ics_classes (Calling C Cs) = Cs" | +"ics_classes (Throwing Cs a) = Cs" | +"ics_classes (Called Cs) = Cs" | +"ics_classes _ = []" + +fun frame_clinit_classes :: "frame \ cname list" where +"frame_clinit_classes (stk,loc,C,M,pc,ics) = (if M=clinit then [C] else []) @ ics_classes ics" + +abbreviation clinit_classes :: "frame list \ cname list" where +"clinit_classes frs \ concat (map frame_clinit_classes frs)" + +definition distinct_clinit :: "frame list \ bool" where +"distinct_clinit frs \ distinct (clinit_classes frs)" + +definition conf_clinit :: "jvm_prog \ sheap \ frame list \ bool" where +"conf_clinit P sh frs + \ distinct_clinit frs \ + (\C \ set(clinit_classes frs). is_class P C \ (\sfs. sh C = Some(sfs, Processing)))" + +(*************************) + +definition correct_state :: "[jvm_prog,ty\<^sub>P,jvm_state] \ bool" ("_,_ \ _ \" [61,0,0] 61) +where + "correct_state P \ \ \(xp,h,frs,sh). + case xp of + None \ (case frs of + [] \ True + | (f#fs) \ P\ h\ \ P,h\\<^sub>s sh\ \ conf_clinit P sh frs \ + (let (stk,loc,C,M,pc,ics) = f + in \b Ts T mxs mxl\<^sub>0 is xt \. + (P \ C sees M,b:Ts\T = (mxs,mxl\<^sub>0,is,xt) in C) \ + \ C M ! pc = Some \ \ + conf_f P h sh \ is f \ conf_fs P h sh \ C M (size Ts) T fs)) + | Some x \ frs = []" + +notation + correct_state ("_,_ |- _ [ok]" [61,0,0] 61) + +subsection \ Values and @{text "\"} \ + +lemma confT_Err [iff]: "P,h \ x :\\<^sub>\ Err" + by (simp add: confT_def) + +lemma confT_OK [iff]: "P,h \ x :\\<^sub>\ OK T = (P,h \ x :\ T)" + by (simp add: confT_def) + +lemma confT_cases: + "P,h \ x :\\<^sub>\ X = (X = Err \ (\T. X = OK T \ P,h \ x :\ T))" + by (cases X) auto + +lemma confT_hext [intro?, trans]: + "\ P,h \ x :\\<^sub>\ T; h \ h' \ \ P,h' \ x :\\<^sub>\ T" + by (cases T) (blast intro: conf_hext)+ + +lemma confT_widen [intro?, trans]: + "\ P,h \ x :\\<^sub>\ T; P \ T \\<^sub>\ T' \ \ P,h \ x :\\<^sub>\ T'" + by (cases T', auto intro: conf_widen) + + +subsection \ Stack and Registers \ + +lemmas confTs_Cons1 [iff] = list_all2_Cons1 [of "confT P h"] for P h + +lemma confTs_confT_sup: + "\ P,h \ loc [:\\<^sub>\] LT; n < size LT; LT!n = OK T; P \ T \ T' \ + \ P,h \ (loc!n) :\ T'" +(*<*) + apply (frule list_all2_lengthD) + apply (drule list_all2_nthD, simp) + apply simp + apply (erule conf_widen, assumption+) + done +(*>*) + +lemma confTs_hext [intro?]: + "P,h \ loc [:\\<^sub>\] LT \ h \ h' \ P,h' \ loc [:\\<^sub>\] LT" + by (fast elim: list_all2_mono confT_hext) + +lemma confTs_widen [intro?, trans]: + "P,h \ loc [:\\<^sub>\] LT \ P \ LT [\\<^sub>\] LT' \ P,h \ loc [:\\<^sub>\] LT'" + by (rule list_all2_trans, rule confT_widen) + +lemma confTs_map [iff]: + "\vs. (P,h \ vs [:\\<^sub>\] map OK Ts) = (P,h \ vs [:\] Ts)" + by (induct Ts) (auto simp: list_all2_Cons2) + +lemma reg_widen_Err [iff]: + "\LT. (P \ replicate n Err [\\<^sub>\] LT) = (LT = replicate n Err)" + by (induct n) (auto simp: list_all2_Cons1) + +lemma confTs_Err [iff]: + "P,h \ replicate n v [:\\<^sub>\] replicate n Err" + by (induct n) auto + +subsection \ valid @{text "init_call_status"} \ + +lemma valid_ics_shupd: +assumes "P,h,sh \\<^sub>i (C, M, pc, ics)" and "distinct (C'#ics_classes ics)" +shows "P,h,sh(C' \ (sfs, i')) \\<^sub>i (C, M, pc, ics)" +using assms by(cases ics; clarsimp simp: fun_upd_apply) fastforce + +subsection \ correct-frame \ + +lemma conf_f_Throwing: +assumes "conf_f P h sh (ST, LT) is (stk, loc, C, M, pc, Called Cs)" + and "is_class P C'" and "h xcp = Some obj" and "sh C' = Some(sfs,Processing)" +shows "conf_f P h sh (ST, LT) is (stk, loc, C, M, pc, Throwing (C' # Cs) xcp)" +using assms by(auto simp: conf_f_def2) + +lemma conf_f_shupd: +assumes "conf_f P h sh (ST,LT) ins f" + and "i = Processing + \ (distinct (C#ics_classes (ics_of f)) \ (curr_method f = clinit \ C \ curr_class f))" +shows "conf_f P h (sh(C \ (sfs, i))) (ST,LT) ins f" +using assms + by(cases f, cases "ics_of f"; clarsimp simp: conf_f_def2 fun_upd_apply) fastforce+ + +lemma conf_f_shupd': +assumes "conf_f P h sh (ST,LT) ins f" + and "sh C = Some(sfs,i)" +shows "conf_f P h (sh(C \ (sfs', i))) (ST,LT) ins f" +using assms + by(cases f, cases "ics_of f"; clarsimp simp: conf_f_def2 fun_upd_apply) fastforce+ + +subsection \ correct-frames \ + +lemmas [simp del] = fun_upd_apply + +lemma conf_fs_hext: + "\C M n T\<^sub>r. + \ conf_fs P h sh \ C M n T\<^sub>r frs; h \ h' \ \ conf_fs P h' sh \ C M n T\<^sub>r frs" +(*<*) +apply (induct frs) + apply simp +apply clarify +apply (simp (no_asm_use)) +apply clarify +apply (unfold conf_f_def) +apply (simp (no_asm_use)) +apply clarify +apply (fastforce elim!: confs_hext confTs_hext) +done +(*>*) + + +lemma conf_fs_shupd: +assumes "conf_fs P h sh \ C\<^sub>0 M n T frs" + and dist: "distinct (C#clinit_classes frs)" +shows "conf_fs P h (sh(C \ (sfs, i))) \ C\<^sub>0 M n T frs" +using assms proof(induct frs arbitrary: C\<^sub>0 C M n T) + case (Cons f' frs') + then obtain stk' loc' C' M' pc' ics' where f': "f' = (stk',loc',C',M',pc',ics')" by(cases f') + with assms Cons obtain ST LT b Ts T1 mxs mxl\<^sub>0 ins xt where + ty: "\ C' M' ! pc' = Some (ST,LT)" and + meth: "P \ C' sees M',b:Ts \ T1 = (mxs,mxl\<^sub>0,ins,xt) in C'" and + conf: "conf_f P h sh (ST, LT) ins f'" and + confs: "conf_fs P h sh \ C' M' (size Ts) T1 frs'" by clarsimp + + from f' Cons.prems(2) have + "distinct (C#ics_classes (ics_of f')) \ (curr_method f' = clinit \ C \ curr_class f')" + by fastforce + with conf_f_shupd[where C=C, OF conf] have + conf': "conf_f P h (sh(C \ (sfs, i))) (ST, LT) ins f'" by simp + + from Cons.prems(2) have dist': "distinct (C # clinit_classes frs')" + by(auto simp: distinct_length_2_or_more) + from Cons.hyps[OF confs dist'] have + confs': "conf_fs P h (sh(C \ (sfs, i))) \ C' M' (length Ts) T1 frs'" by simp + + from conf' confs' ty meth f' Cons.prems show ?case by(fastforce dest: sees_method_fun) +qed(simp) + +lemma conf_fs_shupd': +assumes "conf_fs P h sh \ C\<^sub>0 M n T frs" + and shC: "sh C = Some(sfs,i)" +shows "conf_fs P h (sh(C \ (sfs', i))) \ C\<^sub>0 M n T frs" +using assms proof(induct frs arbitrary: C\<^sub>0 C M n T sfs i sfs') + case (Cons f' frs') + then obtain stk' loc' C' M' pc' ics' where f': "f' = (stk',loc',C',M',pc',ics')" by(cases f') + with assms Cons obtain ST LT b Ts T1 mxs mxl\<^sub>0 ins xt where + ty: "\ C' M' ! pc' = Some (ST,LT)" and + meth: "P \ C' sees M',b:Ts \ T1 = (mxs,mxl\<^sub>0,ins,xt) in C'" and + conf: "conf_f P h sh (ST, LT) ins f'" and + confs: "conf_fs P h sh \ C' M' (size Ts) T1 frs'" and + shC': "sh C = Some(sfs,i)" by clarsimp + + have conf': "conf_f P h (sh(C \ (sfs', i))) (ST, LT) ins f'" by(rule conf_f_shupd'[OF conf shC']) + + from Cons.hyps[OF confs shC'] have + confs': "conf_fs P h (sh(C \ (sfs', i))) \ C' M' (length Ts) T1 frs'" by simp + + from conf' confs' ty meth f' Cons.prems show ?case by(fastforce dest: sees_method_fun) +qed(simp) + +subsection \ correctness wrt @{term clinit} use \ + +lemma conf_clinit_Cons: +assumes "conf_clinit P sh (f#frs)" +shows "conf_clinit P sh frs" +proof - + from assms have dist: "distinct_clinit (f#frs)" + by(cases "curr_method f = clinit", auto simp: conf_clinit_def) + then have dist': "distinct_clinit frs" by(simp add: distinct_clinit_def) + + with assms show ?thesis by(cases frs; fastforce simp: conf_clinit_def) +qed + +lemma conf_clinit_Cons_Cons: + "conf_clinit P sh (f'#f#frs) \ conf_clinit P sh (f'#frs)" + by(auto simp: conf_clinit_def distinct_clinit_def) + +lemma conf_clinit_diff: +assumes "conf_clinit P sh ((stk,loc,C,M,pc,ics)#frs)" +shows "conf_clinit P sh ((stk',loc',C,M,pc',ics)#frs)" +using assms by(cases "M = clinit", simp_all add: conf_clinit_def distinct_clinit_def) + +lemma conf_clinit_diff': +assumes "conf_clinit P sh ((stk,loc,C,M,pc,ics)#frs)" +shows "conf_clinit P sh ((stk',loc',C,M,pc',No_ics)#frs)" +using assms by(cases "M = clinit", simp_all add: conf_clinit_def distinct_clinit_def) + +lemma conf_clinit_Called_Throwing: + "conf_clinit P sh ((stk', loc', C', clinit, pc', ics') # (stk, loc, C, M, pc, Called Cs) # fs) + \ conf_clinit P sh ((stk, loc, C, M, pc, Throwing (C' # Cs) xcp) # fs)" + by(simp add: conf_clinit_def distinct_clinit_def) + +lemma conf_clinit_Throwing: + "conf_clinit P sh ((stk, loc, C, M, pc, Throwing (C'#Cs) xcp) # fs) + \ conf_clinit P sh ((stk, loc, C, M, pc, Throwing Cs xcp) # fs)" + by(simp add: conf_clinit_def distinct_clinit_def) + +lemma conf_clinit_Called: + "\ conf_clinit P sh ((stk, loc, C, M, pc, Called (C'#Cs)) # frs); + P \ C' sees clinit,Static: [] \ Void=(mxs',mxl',ins',xt') in C' \ + \ conf_clinit P sh (create_init_frame P C' # (stk, loc, C, M, pc, Called Cs) # frs)" + by(simp add: conf_clinit_def distinct_clinit_def) + +lemma conf_clinit_Cons_nclinit: +assumes "conf_clinit P sh frs" and nclinit: "M \ clinit" +shows "conf_clinit P sh ((stk, loc, C, M, pc, No_ics) # frs)" +proof - + from nclinit + have "clinit_classes ((stk, loc, C, M, pc, No_ics) # frs) = clinit_classes frs" by simp + with assms show ?thesis by(simp add: conf_clinit_def distinct_clinit_def) +qed + +lemma conf_clinit_Invoke: +assumes "conf_clinit P sh ((stk, loc, C, M, pc, ics) # frs)" and "M' \ clinit" +shows "conf_clinit P sh ((stk', loc', C', M', pc', No_ics) # (stk, loc, C, M, pc, No_ics) # frs)" + using assms conf_clinit_Cons_nclinit conf_clinit_diff' by auto + +lemma conf_clinit_nProc_dist: +assumes "conf_clinit P sh frs" + and "\sfs. sh C \ Some(sfs,Processing)" +shows "distinct (C # clinit_classes frs)" +using assms by(auto simp: conf_clinit_def distinct_clinit_def) + + +lemma conf_clinit_shupd: +assumes "conf_clinit P sh frs" + and dist: "distinct (C#clinit_classes frs)" +shows "conf_clinit P (sh(C \ (sfs, i))) frs" +using assms by(simp add: conf_clinit_def fun_upd_apply) + +lemma conf_clinit_shupd': +assumes "conf_clinit P sh frs" + and "sh C = Some(sfs,i)" +shows "conf_clinit P (sh(C \ (sfs', i))) frs" +using assms by(fastforce simp: conf_clinit_def fun_upd_apply) + +lemma conf_clinit_shupd_Called: +assumes "conf_clinit P sh ((stk,loc,C,M,pc,Calling C' Cs)#frs)" + and dist: "distinct (C'#clinit_classes ((stk,loc,C,M,pc,Calling C' Cs)#frs))" + and cls: "is_class P C'" +shows "conf_clinit P (sh(C' \ (sfs, Processing))) ((stk,loc,C,M,pc,Called (C'#Cs))#frs)" +using assms by(clarsimp simp: conf_clinit_def fun_upd_apply distinct_clinit_def) + +lemma conf_clinit_shupd_Calling: +assumes "conf_clinit P sh ((stk,loc,C,M,pc,Calling C' Cs)#frs)" + and dist: "distinct (C'#clinit_classes ((stk,loc,C,M,pc,Calling C' Cs)#frs))" + and cls: "is_class P C'" +shows "conf_clinit P (sh(C' \ (sfs, Processing))) + ((stk,loc,C,M,pc,Calling (fst(the(class P C'))) (C'#Cs))#frs)" +using assms by(clarsimp simp: conf_clinit_def fun_upd_apply distinct_clinit_def) + +subsection \ correct state \ + +lemma correct_state_Cons: +assumes cr: "P,\ |- (xp,h,f#frs,sh) [ok]" +shows "P,\ |- (xp,h,frs,sh) [ok]" +proof - + from cr have dist: "conf_clinit P sh (f#frs)" + by(simp add: correct_state_def) + then have "conf_clinit P sh frs" by(rule conf_clinit_Cons) + + with cr show ?thesis by(cases frs; fastforce simp: correct_state_def) +qed + +lemma correct_state_shupd: +assumes cs: "P,\ |- (xp,h,frs,sh) [ok]" and shC: "sh C = Some(sfs,i)" + and dist: "distinct (C#clinit_classes frs)" +shows "P,\ |- (xp,h,frs,sh(C \ (sfs, i'))) [ok]" +using assms +proof(cases xp) + case None with assms show ?thesis + proof(cases frs) + case (Cons f' frs') + let ?sh = "sh(C \ (sfs, i'))" + + obtain stk' loc' C' M' pc' ics' where f': "f' = (stk',loc',C',M',pc',ics')" by(cases f') + with cs Cons None obtain b Ts T mxs mxl\<^sub>0 ins xt ST LT where + meth: "P \ C' sees M',b:Ts\T = (mxs,mxl\<^sub>0,ins,xt) in C'" + and ty: "\ C' M' ! pc' = Some (ST,LT)" and conf: "conf_f P h sh (ST,LT) ins f'" + and confs: "conf_fs P h sh \ C' M' (size Ts) T frs'" + and confc: "conf_clinit P sh frs" + and h_ok: "P\ h\" and sh_ok: "P,h \\<^sub>s sh \" + by(auto simp: correct_state_def) + + from Cons dist have dist': "distinct (C#clinit_classes frs')" + by(auto simp: distinct_length_2_or_more) + + from shconf_upd_obj[OF sh_ok shconfD[OF sh_ok shC]] have sh_ok': "P,h \\<^sub>s ?sh \" + by simp + + from conf f' valid_ics_shupd Cons dist have conf': "conf_f P h ?sh (ST,LT) ins f'" + by(auto simp: conf_f_def2 fun_upd_apply) + have confs': "conf_fs P h ?sh \ C' M' (size Ts) T frs'" by(rule conf_fs_shupd[OF confs dist']) + + have confc': "conf_clinit P ?sh frs" by(rule conf_clinit_shupd[OF confc dist]) + + with h_ok sh_ok' meth ty conf' confs' f' Cons None show ?thesis + by(fastforce simp: correct_state_def) + qed(simp add: correct_state_def) +qed(simp add: correct_state_def) + +lemma correct_state_Throwing_ex: +assumes correct: "P,\ \ (xp,h,(stk,loc,C,M,pc,ics)#frs,sh)\" +shows "\Cs a. ics = Throwing Cs a \ \obj. h a = Some obj" +using correct by(clarsimp simp: correct_state_def conf_f_def) + +end diff --git a/thys/JinjaDCI/BV/BVExample.thy b/thys/JinjaDCI/BV/BVExample.thy new file mode 100644 --- /dev/null +++ b/thys/JinjaDCI/BV/BVExample.thy @@ -0,0 +1,579 @@ +(* Title: Jinja/BV/BVExample.thy + + Author: Gerwin Klein +*) + +section \ Example Welltypings \label{sec:BVExample} \ + +theory BVExample +imports "../JVM/JVMListExample" BVSpecTypeSafe BVExec + "HOL-Library.Code_Target_Numeral" +begin + +text \ + This theory shows type correctness of the example program in section + \ref{sec:JVMListExample} (p. \pageref{sec:JVMListExample}) by + explicitly providing a welltyping. It also shows that the start + state of the program conforms to the welltyping; hence type safe + execution is guaranteed. +\ + +subsection "Setup" + +lemma distinct_classes': + "list_name \ test_name" + "list_name \ Object" + "list_name \ ClassCast" + "list_name \ OutOfMemory" + "list_name \ NullPointer" + "test_name \ Object" + "test_name \ OutOfMemory" + "test_name \ ClassCast" + "test_name \ NullPointer" + "ClassCast \ NullPointer" + "ClassCast \ Object" + "NullPointer \ Object" + "OutOfMemory \ ClassCast" + "OutOfMemory \ NullPointer" + "OutOfMemory \ Object" + by (simp_all add: list_name_def test_name_def Object_def NullPointer_def + OutOfMemory_def ClassCast_def) + +lemmas distinct_classes = distinct_classes' distinct_classes' [symmetric] + +lemma distinct_fields: + "val_name \ next_name" + "next_name \ val_name" + by (simp_all add: val_name_def next_name_def) + +text \ Abbreviations for definitions we will have to use often in the +proofs below: \ +lemmas system_defs = SystemClasses_def ObjectC_def NullPointerC_def + OutOfMemoryC_def ClassCastC_def +lemmas class_defs = list_class_def test_class_def + +text \ These auxiliary proofs are for efficiency: class lookup, +subclass relation, method and field lookup are computed only once: +\ +lemma class_Object [simp]: + "class E Object = Some (undefined, [],[])" + by (simp add: class_def system_defs E_def) + +lemma class_NullPointer [simp]: + "class E NullPointer = Some (Object, [], [])" + by (simp add: class_def system_defs E_def distinct_classes) + +lemma class_OutOfMemory [simp]: + "class E OutOfMemory = Some (Object, [], [])" + by (simp add: class_def system_defs E_def distinct_classes) + +lemma class_ClassCast [simp]: + "class E ClassCast = Some (Object, [], [])" + by (simp add: class_def system_defs E_def distinct_classes) + +lemma class_list [simp]: + "class E list_name = Some list_class" + by (simp add: class_def system_defs E_def distinct_classes) + +lemma class_test [simp]: + "class E test_name = Some test_class" + by (simp add: class_def system_defs E_def distinct_classes) + +lemma E_classes [simp]: + "{C. is_class E C} = {list_name, test_name, NullPointer, + ClassCast, OutOfMemory, Object}" + by (auto simp add: is_class_def class_def system_defs E_def class_defs) + +text \ The subclass releation spelled out: \ +lemma subcls1: + "subcls1 E = {(list_name,Object), (test_name,Object), (NullPointer, Object), + (ClassCast, Object), (OutOfMemory, Object)}" +(*<*) + apply (simp add: subcls1_def2) + apply (simp add: class_defs system_defs E_def class_def) + (* FIXME: cannot simply expand class names, since + inequality proofs on strings are too inefficient *) + apply (auto simp: distinct_classes split!: if_splits) + done +(*>*) + +text \ The subclass relation is acyclic; hence its converse is well founded: \ +lemma notin_rtrancl: + "(a,b) \ r\<^sup>* \ a \ b \ (\y. (a,y) \ r) \ False" + by (auto elim: converse_rtranclE) + +lemma acyclic_subcls1_E: "acyclic (subcls1 E)" +(*<*) + apply (rule acyclicI) + apply (simp add: subcls1) + apply (auto dest!: tranclD) + apply (auto elim!: notin_rtrancl simp add: distinct_classes) + done +(*>*) + +lemma wf_subcls1_E: "wf ((subcls1 E)\)" +(*<*) + apply (rule finite_acyclic_wf_converse) + apply (simp add: subcls1) + apply (rule acyclic_subcls1_E) + done +(*>*) + +text \ Method and field lookup: \ + +lemma method_append [simp]: + "method E list_name append_name = + (list_name, [Class list_name], Void, 3, 0, append_ins, [(1, 2, NullPointer, 7, 0)])" +(*<*) + apply (insert class_list) + apply (unfold list_class_def) + apply (fastforce simp add: Method_def distinct_classes intro: method_def2 Methods.intros) + done +(*>*) + +lemma method_makelist [simp]: + "method E test_name makelist_name = + (test_name, [], Void, 3, 2, make_list_ins, [])" +(*<*) + apply (insert class_test) + apply (unfold test_class_def) + apply (fastforce simp add: Method_def distinct_classes intro: method_def2 Methods.intros) + done +(*>*) + +lemma field_val [simp]: + "field E list_name val_name = (list_name, Integer)" +(*<*) + apply (insert class_list) + apply (unfold list_class_def) + apply (fastforce simp add: sees_field_def distinct_classes intro: field_def2 Fields.intros) + done +(*>*) + +lemma field_next [simp]: + "field E list_name next_name = (list_name, Class list_name)" +(*<*) + apply (insert class_list) + apply (unfold list_class_def) + apply (fastforce simp add: distinct_fields sees_field_def distinct_classes intro: field_def2 Fields.intros) + done +(*>*) + +lemma [simp]: "fields E Object = []" + by (fastforce intro: fields_def2 Fields.intros) + +lemma [simp]: "fields E NullPointer = []" + by (fastforce simp add: distinct_classes intro: fields_def2 Fields.intros) + +lemma [simp]: "fields E ClassCast = []" + by (fastforce simp add: distinct_classes intro: fields_def2 Fields.intros) + +lemma [simp]: "fields E OutOfMemory = []" + by (fastforce simp add: distinct_classes intro: fields_def2 Fields.intros) + +lemma [simp]: "fields E test_name = []" +(*<*) + apply (insert class_test) + apply (unfold test_class_def) + apply (fastforce simp add: distinct_classes intro: fields_def2 Fields.intros) + done +(*>*) + +lemmas [simp] = is_class_def + + +subsection "Program structure" + +text \ + The program is structurally wellformed: +\ +lemma wf_struct: + "wf_prog (\G C mb. True) E" (is "wf_prog ?mb E") +(*<*) +proof - + have "distinct_fst E" + by (simp add: system_defs E_def class_defs distinct_classes) + moreover + have "set SystemClasses \ set E" by (simp add: system_defs E_def) + hence "wf_syscls E" by (rule wf_syscls) + moreover + have "wf_cdecl ?mb E ObjectC" by (simp add: wf_cdecl_def ObjectC_def) + moreover + have "wf_cdecl ?mb E NullPointerC" + by (auto elim: notin_rtrancl + simp add: wf_cdecl_def distinct_classes NullPointerC_def subcls1) + moreover + have "wf_cdecl ?mb E ClassCastC" + by (auto elim: notin_rtrancl + simp add: wf_cdecl_def distinct_classes ClassCastC_def subcls1) + moreover + have "wf_cdecl ?mb E OutOfMemoryC" + by (auto elim: notin_rtrancl + simp add: wf_cdecl_def distinct_classes OutOfMemoryC_def subcls1) + moreover + have "wf_cdecl ?mb E (list_name, list_class)" + apply (auto elim!: notin_rtrancl + simp add: wf_cdecl_def wf_fdecl_def list_class_def + wf_mdecl_def subcls1) + apply (auto simp add: distinct_classes distinct_fields Method_def elim: Methods.cases) + done + moreover + have "wf_cdecl ?mb E (test_name, test_class)" + apply (auto elim!: notin_rtrancl + simp add: wf_cdecl_def wf_fdecl_def test_class_def + wf_mdecl_def subcls1) + apply (auto simp add: distinct_classes distinct_fields Method_def elim: Methods.cases) + done + ultimately + show ?thesis by (simp add: wf_prog_def E_def SystemClasses_def) +qed +(*>*) + +subsection "Welltypings" +text \ + We show welltypings of the methods @{term append_name} in class @{term list_name}, + and @{term makelist_name} in class @{term test_name}: +\ +lemmas eff_simps [simp] = eff_def norm_eff_def xcpt_eff_def +(*declare app'Invoke [simp del]*) + +definition phi_append :: ty\<^sub>m ("\\<^sub>a") +where + "\\<^sub>a \ map (\(x,y). Some (x, map OK y)) [ + ( [], [Class list_name, Class list_name]), + ( [Class list_name], [Class list_name, Class list_name]), + ( [Class list_name], [Class list_name, Class list_name]), + ( [Class list_name, Class list_name], [Class list_name, Class list_name]), + ( [Class list_name, Class list_name], [Class list_name, Class list_name]), + ([NT, Class list_name, Class list_name], [Class list_name, Class list_name]), + ( [Boolean, Class list_name], [Class list_name, Class list_name]), + + ( [Class Object], [Class list_name, Class list_name]), + ( [], [Class list_name, Class list_name]), + ( [Class list_name], [Class list_name, Class list_name]), + ( [Class list_name, Class list_name], [Class list_name, Class list_name]), + ( [], [Class list_name, Class list_name]), + ( [Void], [Class list_name, Class list_name]), + + ( [Class list_name], [Class list_name, Class list_name]), + ( [Class list_name, Class list_name], [Class list_name, Class list_name]), + ( [Void], [Class list_name, Class list_name])]" + +text \ + The next definition and three proof rules implement an algorithm to + enumarate natural numbers. The command @{text "apply (elim pc_end pc_next pc_0"} + transforms a goal of the form + @{prop [display] "pc < n \ P pc"} + into a series of goals + @{prop [display] "P 0"} + @{prop [display] "P (Suc 0)"} + + @{text "\"} + + @{prop [display] "P n"} +\ +definition intervall :: "nat \ nat \ nat \ bool" ("_ \ [_, _')") +where + "x \ [a, b) \ a \ x \ x < b" + +lemma pc_0: "x < n \ (x \ [0, n) \ P x) \ P x" + by (simp add: intervall_def) + +lemma pc_next: "x \ [n0, n) \ P n0 \ (x \ [Suc n0, n) \ P x) \ P x" +(*<*) + apply (cases "x=n0") + apply (auto simp add: intervall_def) + done +(*>*) + +lemma pc_end: "x \ [n,n) \ P x" + by (unfold intervall_def) arith + + +lemma types_append [simp]: "check_types E 3 (Suc (Suc 0)) (map OK \\<^sub>a)" +(*<*) + by (auto simp add: check_types_def phi_append_def JVM_states_unfold) +(*>*) + +lemma wt_append [simp]: + "wt_method E list_name [Class list_name] Void 3 0 append_ins + [(Suc 0, 2, NullPointer, 7, 0)] \\<^sub>a" +(*<*) + apply (simp add: wt_method_def wt_start_def wt_instr_def) + apply (simp add: append_ins_def phi_append_def) + apply clarify + apply (drule sym) + apply (erule_tac P="x = y" for x y in rev_mp) + apply (elim pc_end pc_next pc_0) + apply (simp add: relevant_entries_def is_relevant_entry_def) + apply (fastforce simp add: matches_ex_entry_def subcls1 + relevant_entries_def is_relevant_entry_def sees_field_def list_class_def + distinct_classes distinct_fields intro: Fields.intros) + apply (simp add: relevant_entries_def is_relevant_entry_def) + apply (fastforce simp add: + relevant_entries_def is_relevant_entry_def sees_field_def list_class_def + distinct_classes distinct_fields intro: Fields.intros) + apply (simp add: relevant_entries_def is_relevant_entry_def) + apply (simp add: relevant_entries_def is_relevant_entry_def) + apply (fastforce simp add: relevant_entries_def is_relevant_entry_def subcls1) + apply (simp add: relevant_entries_def is_relevant_entry_def) + apply (simp add: relevant_entries_def is_relevant_entry_def) + apply (simp add: relevant_entries_def is_relevant_entry_def) + apply (fastforce simp add: + relevant_entries_def is_relevant_entry_def sees_field_def list_class_def + distinct_classes distinct_fields intro: Fields.intros) + apply (simp add: relevant_entries_def is_relevant_entry_def) + apply (simp add: relevant_entries_def is_relevant_entry_def) + apply (simp add: relevant_entries_def is_relevant_entry_def) + apply (fastforce simp add: + relevant_entries_def is_relevant_entry_def list_class_def + distinct_classes Method_def intro: Methods.intros) + apply (simp add: relevant_entries_def is_relevant_entry_def) + done +(*>*) + +text \ Some abbreviations for readability \ +abbreviation "Clist == Class list_name" +abbreviation "Ctest == Class test_name" + +definition phi_makelist :: ty\<^sub>m ("\\<^sub>m") +where + "\\<^sub>m \ map (\(x,y). Some (x, y)) [ + ( [], [OK Ctest, Err , Err ]), + ( [Clist], [OK Ctest, Err , Err ]), + ( [], [OK Clist, Err , Err ]), + ( [Clist], [OK Clist, Err , Err ]), + ( [Integer, Clist], [OK Clist, Err , Err ]), + + ( [], [OK Clist, Err , Err ]), + ( [Clist], [OK Clist, Err , Err ]), + ( [], [OK Clist, OK Clist, Err ]), + ( [Clist], [OK Clist, OK Clist, Err ]), + ( [Integer, Clist], [OK Clist, OK Clist, Err ]), + + ( [], [OK Clist, OK Clist, Err ]), + ( [Clist], [OK Clist, OK Clist, Err ]), + ( [], [OK Clist, OK Clist, OK Clist]), + ( [Clist], [OK Clist, OK Clist, OK Clist]), + ( [Integer, Clist], [OK Clist, OK Clist, OK Clist]), + + ( [], [OK Clist, OK Clist, OK Clist]), + ( [Clist], [OK Clist, OK Clist, OK Clist]), + ( [Clist, Clist], [OK Clist, OK Clist, OK Clist]), + ( [Void], [OK Clist, OK Clist, OK Clist]), + ( [], [OK Clist, OK Clist, OK Clist]), + ( [Clist], [OK Clist, OK Clist, OK Clist]), + ( [Clist, Clist], [OK Clist, OK Clist, OK Clist]), + ( [Void], [OK Clist, OK Clist, OK Clist])]" + +lemma types_makelist [simp]: "check_types E 3 (Suc (Suc (Suc 0))) (map OK \\<^sub>m)" +(*<*) + by (auto simp add: check_types_def phi_makelist_def JVM_states_unfold) +(*>*) + +lemma wt_makelist [simp]: + "wt_method E test_name [] Void 3 2 make_list_ins [] \\<^sub>m" +(*<*) + apply (simp add: wt_method_def) + apply (unfold make_list_ins_def phi_makelist_def) + apply (simp add: wt_start_def eval_nat_numeral) + apply (simp add: wt_instr_def) + apply clarify + apply (drule sym) + apply (erule_tac P="x = y" for x y in rev_mp) + apply (elim pc_end pc_next pc_0) + apply (simp add: relevant_entries_def is_relevant_entry_def) + apply (simp add: relevant_entries_def is_relevant_entry_def) + apply (simp add: relevant_entries_def is_relevant_entry_def) + apply (simp add: relevant_entries_def is_relevant_entry_def) + apply (fastforce simp add: + relevant_entries_def is_relevant_entry_def sees_field_def list_class_def + distinct_classes intro: Fields.intros) + apply (simp add: relevant_entries_def is_relevant_entry_def) + apply (simp add: relevant_entries_def is_relevant_entry_def) + apply (simp add: relevant_entries_def is_relevant_entry_def) + apply (simp add: relevant_entries_def is_relevant_entry_def) + apply (fastforce simp add: + relevant_entries_def is_relevant_entry_def sees_field_def list_class_def + distinct_classes intro: Fields.intros) + apply (simp add: relevant_entries_def is_relevant_entry_def) + apply (simp add: relevant_entries_def is_relevant_entry_def) + apply (simp add: relevant_entries_def is_relevant_entry_def) + apply (simp add: relevant_entries_def is_relevant_entry_def) + apply (fastforce simp add: + relevant_entries_def is_relevant_entry_def sees_field_def list_class_def + distinct_classes intro: Fields.intros) + apply (simp add: relevant_entries_def is_relevant_entry_def) + apply (simp add: relevant_entries_def is_relevant_entry_def) + apply (fastforce simp add: + relevant_entries_def is_relevant_entry_def list_class_def + distinct_classes Method_def intro: Methods.intros) + apply (simp add: relevant_entries_def is_relevant_entry_def) + apply (simp add: relevant_entries_def is_relevant_entry_def) + apply (simp add: relevant_entries_def is_relevant_entry_def) + apply (fastforce simp add: + relevant_entries_def is_relevant_entry_def list_class_def + distinct_classes Method_def intro: Methods.intros) + apply (simp add: relevant_entries_def is_relevant_entry_def) + done +(*>*) + +lemma wf_md'E: + "\ wf_prog wf_md P; + \C S fs ms m.\(C,S,fs,ms) \ set P; m \ set ms\ \ wf_md' P C m \ + \ wf_prog wf_md' P" +(*<*) + apply (simp add: wf_prog_def) + apply auto + apply (simp add: wf_cdecl_def wf_mdecl_def) + apply fastforce + done +(*>*) + +text \ The whole program is welltyped: \ +definition Phi :: ty\<^sub>P ("\") +where + "\ C mn \ if C = test_name \ mn = makelist_name then \\<^sub>m else + if C = list_name \ mn = append_name then \\<^sub>a else []" + +lemma wf_prog: + "wf_jvm_prog\<^bsub>\\<^esub> E" +(*<*) + apply (unfold wf_jvm_prog_phi_def) + apply (rule wf_md'E [OF wf_struct]) + apply (simp add: E_def) + apply clarify + apply (fold E_def) + apply (simp add: system_defs class_defs Phi_def) + apply auto + apply (simp add: distinct_classes) + done +(*>*) + + +subsection "Conformance" +text \ Execution of the program will be typesafe, because its + start state conforms to the welltyping: \ + +lemma "E,\ \ start_state E test_name makelist_name \" +(*<*) + apply (rule BV_correct_initial) + apply (rule wf_prog) + apply (fastforce simp add: test_class_def distinct_classes Method_def intro: Methods.intros) + done +(*>*) + + +subsection "Example for code generation: inferring method types" + +definition test_kil :: "jvm_prog \ cname \ ty list \ ty \ nat \ nat \ + ex_table \ instr list \ ty\<^sub>i' err list" +where + "test_kil G C pTs rT mxs mxl et instr \ + (let first = Some ([],(OK (Class C))#(map OK pTs)@(replicate mxl Err)); + start = OK first#(replicate (size instr - 1) (OK None)) + in kiljvm G mxs (1+size pTs+mxl) rT instr et start)" + + +lemma [code]: + "unstables r step ss = + fold (\p A. if \stable r step ss p then insert p A else A) [0..stable r step ss p then {p} else {})" + apply (unfold unstables_def) + apply (rule equalityI) + apply (rule subsetI) + apply (erule CollectE) + apply (erule conjE) + apply (rule UN_I) + apply simp + apply simp + apply (rule subsetI) + apply (erule UN_E) + apply (case_tac "\ stable r step ss p") + apply simp+ + done + also have "\f. (UN p:{..) \ (\p. if \ stable r step ss p then {p} else {}) = + (\p A. if \stable r step ss p then insert p A else A)" + by(auto simp add: fun_eq_iff) + finally show ?thesis . +qed + +definition some_elem :: "'a set \ 'a" where [code del]: + "some_elem = (%S. SOME x. x : S)" +code_printing + constant some_elem \ (SML) "(case/ _ of/ Set/ xs/ =>/ hd/ xs)" + +text \ This code setup is just a demonstration and \emph{not} sound! \ +notepad begin + have "some_elem (set [False, True]) = False" by eval + moreover have "some_elem (set [True, False]) = True" by eval + ultimately have False by (simp add: some_elem_def) +end + +lemma [code]: + "iter f step ss w = while (\(ss, w). \ Set.is_empty w) + (\(ss, w). + let p = some_elem w in propa f (step p (ss ! p)) ss (w - {p})) + (ss, w)" + unfolding iter_def Set.is_empty_def some_elem_def .. + +lemma JVM_sup_unfold [code]: + "JVM_SemiType.sup S m n = lift2 (Opt.sup + (Product.sup (Listn.sup (SemiType.sup S)) + (\x y. OK (map2 (lift2 (SemiType.sup S)) x y))))" + apply (unfold JVM_SemiType.sup_def JVM_SemiType.sl_def Opt.esl_def Err.sl_def + stk_esl_def loc_sl_def Product.esl_def + Listn.sl_def upto_esl_def SemiType.esl_def Err.esl_def) + by simp + +lemmas [code] = SemiType.sup_def [unfolded exec_lub_def] JVM_le_unfold + +lemmas [code] = lesub_def plussub_def + +lemma [code]: + "is_refT T = (case T of NT \ True | Class C \ True | _ \ False)" + by (simp add: is_refT_def split: ty.split) + +declare app\<^sub>i.simps [code] + +lemma [code]: + "app\<^sub>i (Getfield F C, P, pc, mxs, T\<^sub>r, (T#ST, LT)) = + Predicate.holds (Predicate.bind (sees_field_i_i_i_o_i P C F C) (\T\<^sub>f. if P \ T \ Class C then Predicate.single () else bot))" +by(auto simp add: Predicate.holds_eq intro: sees_field_i_i_i_o_iI elim: sees_field_i_i_i_o_iE) + +lemma [code]: + "app\<^sub>i (Putfield F C, P, pc, mxs, T\<^sub>r, (T\<^sub>1#T\<^sub>2#ST, LT)) = + Predicate.holds (Predicate.bind (sees_field_i_i_i_o_i P C F C) (\T\<^sub>f. if P \ T\<^sub>2 \ (Class C) \ P \ T\<^sub>1 \ T\<^sub>f then Predicate.single () else bot))" +by(auto simp add: Predicate.holds_eq simp del: eval_bind split: if_split_asm elim!: sees_field_i_i_i_o_iE Predicate.bindE intro: Predicate.bindI sees_field_i_i_i_o_iI) + +lemma [code]: + "app\<^sub>i (Invoke M n, P, pc, mxs, T\<^sub>r, (ST,LT)) = + (n < length ST \ + (ST!n \ NT \ + (case ST!n of + Class C \ Predicate.holds (Predicate.bind (Method_i_i_i_o_o_o_o P C M) (\(Ts, T, m, D). if P \ rev (take n ST) [\] Ts then Predicate.single () else bot)) + | _ \ False)))" +by (fastforce simp add: Predicate.holds_eq simp del: eval_bind split: ty.split_asm if_split_asm intro: bindI Method_i_i_i_o_o_o_oI elim!: bindE Method_i_i_i_o_o_o_oE) + +lemmas [code] = + SemiType.sup_def [unfolded exec_lub_def] + widen.equation + is_relevant_class.simps + +definition test1 where + "test1 = test_kil E list_name [Class list_name] Void 3 0 + [(Suc 0, 2, NullPointer, 7, 0)] append_ins" +definition test2 where + "test2 = test_kil E test_name [] Void 3 2 [] make_list_ins" +definition test3 where "test3 = \\<^sub>a" +definition test4 where "test4 = \\<^sub>m" + +ML_val \ + if @{code test1} = @{code map} @{code OK} @{code test3} then () else error "wrong result"; + if @{code test2} = @{code map} @{code OK} @{code test4} then () else error "wrong result" +\ + +end diff --git a/thys/JinjaDCI/BV/BVExec.thy b/thys/JinjaDCI/BV/BVExec.thy new file mode 100644 --- /dev/null +++ b/thys/JinjaDCI/BV/BVExec.thy @@ -0,0 +1,238 @@ +(* Title: JinjaDCI/BV/BVExec.thy + + Author: Tobias Nipkow, Gerwin Klein, Susannah Mansky + Copyright 2000 TUM, 2020 UIUC + + Based on the Jinja theory BV/BVExec.thy by Tobias Nipkow and Gerwin Klein +*) + +section \ Kildall for the JVM \label{sec:JVM} \ + +theory BVExec +imports Jinja.Abstract_BV TF_JVM +begin + +definition kiljvm :: "jvm_prog \ nat \ nat \ ty \ + instr list \ ex_table \ ty\<^sub>i' err list \ ty\<^sub>i' err list" +where + "kiljvm P mxs mxl T\<^sub>r is xt \ + kildall (JVM_SemiType.le P mxs mxl) (JVM_SemiType.sup P mxs mxl) + (exec P mxs T\<^sub>r xt is)" + +definition wt_kildall :: "jvm_prog \ cname \ staticb \ ty list \ ty \ nat \ nat \ + instr list \ ex_table \ bool" +where + "wt_kildall P C' b Ts T\<^sub>r mxs mxl\<^sub>0 is xt \ + 0 < size is \ + (let first = Some ([],(case b of Static \ [] | NonStatic \ [OK (Class C')]) + @(map OK Ts)@(replicate mxl\<^sub>0 Err)); + start = (OK first)#(replicate (size is - 1) (OK None)); + result = kiljvm P mxs + ((case b of Static \ 0 | NonStatic \ 1)+size Ts+mxl\<^sub>0) + T\<^sub>r is xt start + in \n < size is. result!n \ Err)" + +definition wf_jvm_prog\<^sub>k :: "jvm_prog \ bool" +where + "wf_jvm_prog\<^sub>k P \ + wf_prog (\P C' (M,b,Ts,T\<^sub>r,(mxs,mxl\<^sub>0,is,xt)). wt_kildall P C' b Ts T\<^sub>r mxs mxl\<^sub>0 is xt) P" + + +theorem (in start_context) is_bcv_kiljvm: + "is_bcv r Err step (size is) A (kiljvm P mxs mxl T\<^sub>r is xt)" +(*<*) + apply (insert wf) + apply (unfold kiljvm_def) + apply (fold r_def f_def step_def_exec) + apply (rule is_bcv_kildall) + apply simp apply (rule Semilat.intro) + apply (fold sl_def2) + apply (erule semilat_JVM) + apply simp + apply blast + apply (simp add: JVM_le_unfold) + apply (rule exec_pres_type) + apply (rule bounded_step) + apply (erule step_mono) + done +(*>*) + +(* FIXME: move? *) +lemma subset_replicate [intro?]: "set (replicate n x) \ {x}" + by (induct n) auto + +lemma in_set_replicate: + assumes "x \ set (replicate n y)" + shows "x = y" +(*<*) +proof - + note assms + also have "set (replicate n y) \ {y}" .. + finally show ?thesis by simp +qed +(*>*) + +lemma (in start_context) start_in_A [intro?]: + "0 < size is \ start \ list (size is) A" + using Ts C +(*<*) + apply (simp add: JVM_states_unfold) + apply (cases b; force intro!: listI list_appendI dest!: in_set_replicate) + done +(*>*) + + +theorem (in start_context) wt_kil_correct: + assumes wtk: "wt_kildall P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt" + shows "\\s. wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt \s" +(*<*) +proof - + from wtk obtain res where + result: "res = kiljvm P mxs mxl T\<^sub>r is xt start" and + success: "\n < size is. res!n \ Err" and + instrs: "0 < size is" + by (unfold wt_kildall_def) simp + + have bcv: "is_bcv r Err step (size is) A (kiljvm P mxs mxl T\<^sub>r is xt)" + by (rule is_bcv_kiljvm) + + from instrs have "start \ list (size is) A" .. + with bcv success result have + "\ts\list (size is) A. start [\\<^sub>r] ts \ wt_step r Err step ts" + by (unfold is_bcv_def) blast + then obtain \s' where + in_A: "\s' \ list (size is) A" and + s: "start [\\<^sub>r] \s'" and + w: "wt_step r Err step \s'" + by blast + hence wt_err_step: "wt_err_step (sup_state_opt P) step \s'" + by (simp add: wt_err_step_def JVM_le_Err_conv) + + from in_A have l: "size \s' = size is" by simp + moreover { + from in_A have "check_types P mxs mxl \s'" by (simp add: check_types_def) + also from w have "\x \ set \s'. x \ Err" + by (auto simp add: wt_step_def all_set_conv_all_nth) + hence [symmetric]: "map OK (map ok_val \s') = \s'" + by (auto intro!: map_idI simp add: wt_step_def) + finally have "check_types P mxs mxl (map OK (map ok_val \s'))" . + } + moreover { + from s have "start!0 \\<^sub>r \s'!0" by (rule le_listD) simp + moreover + from instrs w l + have "\s'!0 \ Err" by (unfold wt_step_def) simp + then obtain \s0 where "\s'!0 = OK \s0" by auto + ultimately + have "wt_start P C b Ts mxl\<^sub>0 (map ok_val \s')" using l instrs + by (unfold wt_start_def) + (cases b; simp add: lesub_def JVM_le_Err_conv Err.le_def) + } + moreover + from in_A have "set \s' \ A" by simp + with wt_err_step bounded_step + have "wt_app_eff (sup_state_opt P) app eff (map ok_val \s')" + by (auto intro: wt_err_imp_wt_app_eff simp add: l) + ultimately + have "wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt (map ok_val \s')" + using instrs by (simp add: wt_method_def2 check_types_def del: map_map) + thus ?thesis by blast +qed +(*>*) + + +theorem (in start_context) wt_kil_complete: + assumes wtm: "wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt \s" + shows "wt_kildall P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt" +(*<*) +proof - + from wtm obtain + instrs: "0 < size is" and + length: "length \s = length is" and + ck_type: "check_types P mxs mxl (map OK \s)" and + wt_start: "wt_start P C b Ts mxl\<^sub>0 \s" and + app_eff: "wt_app_eff (sup_state_opt P) app eff \s" + by (simp add: wt_method_def2 check_types_def) + + from ck_type + have in_A: "set (map OK \s) \ A" + by (simp add: check_types_def) + with app_eff in_A bounded_step + have "wt_err_step (sup_state_opt P) (err_step (size \s) app eff) (map OK \s)" + by - (erule wt_app_eff_imp_wt_err, + auto simp add: exec_def length states_def) + hence wt_err: "wt_err_step (sup_state_opt P) step (map OK \s)" + by (simp add: length) + have is_bcv: "is_bcv r Err step (size is) A (kiljvm P mxs mxl T\<^sub>r is xt)" + by (rule is_bcv_kiljvm) + moreover from instrs have "start \ list (size is) A" .. + moreover + let ?\s = "map OK \s" + have less_\s: "start [\\<^sub>r] ?\s" + proof (rule le_listI) + from length instrs + show "length start = length (map OK \s)" by simp + next + fix n + from wt_start have "P \ ok_val (start!0) \' \s!0" + by (cases b; simp add: wt_start_def) + moreover from instrs length have "0 < length \s" by simp + ultimately have "start!0 \\<^sub>r ?\s!0" + by (simp add: JVM_le_Err_conv lesub_def) + moreover { + fix n' + have "OK None \\<^sub>r ?\s!n" + by (auto simp add: JVM_le_Err_conv Err.le_def lesub_def + split: err.splits) + hence "\n = Suc n'; n < size start\ \ start!n \\<^sub>r ?\s!n" by simp + } + ultimately + show "n < size start \ start!n \\<^sub>r ?\s!n" by (cases n, blast+) + qed + moreover + from ck_type length + have "?\s \ list (size is) A" + by (auto intro!: listI simp add: check_types_def) + moreover + from wt_err have "wt_step r Err step ?\s" + by (simp add: wt_err_step_def JVM_le_Err_conv) + ultimately + have "\p. p < size is \ kiljvm P mxs mxl T\<^sub>r is xt start ! p \ Err" + by (unfold is_bcv_def) blast + with instrs + show "wt_kildall P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt" by (unfold wt_kildall_def) simp +qed +(*>*) + + +theorem jvm_kildall_correct: + "wf_jvm_prog\<^sub>k P = wf_jvm_prog P" +(*<*) +proof + let ?\ = "\C M. let (C,b,Ts,T\<^sub>r,(mxs,mxl\<^sub>0,is,xt)) = method P C M in + SOME \s. wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt \s" + + \ \soundness\ + assume wt: "wf_jvm_prog\<^sub>k P" + hence "wf_jvm_prog\<^bsub>?\\<^esub> P" + apply (unfold wf_jvm_prog_phi_def wf_jvm_prog\<^sub>k_def) + apply (erule wf_prog_lift) + apply (auto dest!: start_context.wt_kil_correct [OF start_context.intro] + intro: someI) + apply (erule sees_method_is_class) + done + thus "wf_jvm_prog P" by (unfold wf_jvm_prog_def) fast +next + \ \completeness\ + assume wt: "wf_jvm_prog P" + thus "wf_jvm_prog\<^sub>k P" + apply (unfold wf_jvm_prog_def wf_jvm_prog_phi_def wf_jvm_prog\<^sub>k_def) + apply (clarify) + apply (erule wf_prog_lift) + apply (auto intro!: start_context.wt_kil_complete start_context.intro) + apply (erule sees_method_is_class) + done +qed +(*>*) + +end diff --git a/thys/JinjaDCI/BV/BVNoTypeError.thy b/thys/JinjaDCI/BV/BVNoTypeError.thy new file mode 100644 --- /dev/null +++ b/thys/JinjaDCI/BV/BVNoTypeError.thy @@ -0,0 +1,394 @@ +(* Title: JinjaDCI/BV/BVNoTypeErrors.thy + + Author: Gerwin Klein, Susannah Mansky + Copyright GPL + + Based on the Jinja theory BV/BVNoTypeErrors.thy by Gerwin Klein +*) + +section \ Welltyped Programs produce no Type Errors \ + +theory BVNoTypeError +imports "../JVM/JVMDefensive" BVSpecTypeSafe +begin + +lemma has_methodI: + "P \ C sees M,b:Ts\T = m in D \ P \ C has M,b" + by (unfold has_method_def) blast + +text \ + Some simple lemmas about the type testing functions of the + defensive JVM: +\ +lemma typeof_NoneD [simp,dest]: "typeof v = Some x \ \is_Addr v" + by (cases v) auto + +lemma is_Ref_def2: + "is_Ref v = (v = Null \ (\a. v = Addr a))" + by (cases v) (auto simp add: is_Ref_def) + +lemma [iff]: "is_Ref Null" by (simp add: is_Ref_def2) + +lemma is_RefI [intro, simp]: "P,h \ v :\ T \ is_refT T \ is_Ref v" +(*<*) + apply (cases T) + apply (auto simp add: is_refT_def is_Ref_def dest: conf_ClassD) + done +(*>*) + +lemma is_IntgI [intro, simp]: "P,h \ v :\ Integer \ is_Intg v" +(*<*) + apply (unfold conf_def) + apply auto + done +(*>*) + +lemma is_BoolI [intro, simp]: "P,h \ v :\ Boolean \ is_Bool v" +(*<*) + apply (unfold conf_def) + apply auto + done +(*>*) + +declare defs1 [simp del] + +lemma wt_jvm_prog_states_NonStatic: + "\ wf_jvm_prog\<^bsub>\\<^esub> P; P \ C sees M,NonStatic: Ts\T = (mxs, mxl, ins, et) in C; + \ C M ! pc = \; pc < size ins \ + \ OK \ \ states P mxs (1+size Ts+mxl)" +(*<*) + apply (unfold wf_jvm_prog_phi_def) + apply (drule (1) sees_wf_mdecl) + apply (simp add: wf_mdecl_def wt_method_def check_types_def) + apply (blast intro: nth_in) + done +(*>*) + +lemma wt_jvm_prog_states_Static: + "\ wf_jvm_prog\<^bsub>\\<^esub> P; P \ C sees M,Static: Ts\T = (mxs, mxl, ins, et) in C; + \ C M ! pc = \; pc < size ins \ + \ OK \ \ states P mxs (size Ts+mxl)" +(*<*) + apply (unfold wf_jvm_prog_phi_def) + apply (drule (1) sees_wf_mdecl) + apply (simp add: wf_mdecl_def wt_method_def check_types_def) + apply (blast intro: nth_in) + done +(*>*) + +text \ + The main theorem: welltyped programs do not produce type errors if they + are started in a conformant state. +\ +theorem no_type_error: + fixes \ :: jvm_state + assumes welltyped: "wf_jvm_prog\<^bsub>\\<^esub> P" and conforms: "P,\ \ \ \" + shows "exec_d P \ \ TypeError" +(*<*) +proof - + from welltyped obtain mb where wf: "wf_prog mb P" by (fast dest: wt_jvm_progD) + + obtain xcp h frs sh where s [simp]: "\ = (xcp, h, frs, sh)" by (cases \) + + from conforms have "xcp \ None \ frs = [] \ check P \" + by (unfold correct_state_def check_def) auto + moreover { + assume "\(xcp \ None \ frs = [])" + then obtain stk reg C M pc ics frs' where + xcp [simp]: "xcp = None" and + frs [simp]: "frs = (stk,reg,C,M,pc,ics)#frs'" + by (clarsimp simp add: neq_Nil_conv) + + from conforms obtain ST LT b Ts T mxs mxl ins xt where + hconf: "P \ h \" and + shconf: "P,h \\<^sub>s sh \" and + meth: "P \ C sees M,b:Ts\T = (mxs, mxl, ins, xt) in C" and + \: "\ C M ! pc = Some (ST,LT)" and + frame: "conf_f P h sh (ST,LT) ins (stk,reg,C,M,pc,ics)" and + frames: "conf_fs P h sh \ C M (size Ts) T frs'" + by (fastforce simp add: correct_state_def dest: sees_method_fun) + + from frame obtain + stk: "P,h \ stk [:\] ST" and + reg: "P,h \ reg [:\\<^sub>\] LT" and + pc: "pc < size ins" + by (simp add: conf_f_def) + + from welltyped meth \ pc + have "OK (Some (ST, LT)) \ states P mxs (1+size Ts+mxl) + \ OK (Some (ST, LT)) \ states P mxs (size Ts+mxl)" + by (cases b, auto dest: wt_jvm_prog_states_NonStatic wt_jvm_prog_states_Static) + hence "size ST \ mxs" by (auto simp add: JVM_states_unfold) + with stk have mxs: "size stk \ mxs" + by (auto dest: list_all2_lengthD) + + from welltyped meth pc + have "P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M" + by (rule wt_jvm_prog_impl_wt_instr) + hence app\<^sub>0: "app (ins!pc) P mxs T pc (size ins) xt (\ C M!pc) " + by (simp add: wt_instr_def) + with \ have eff: + "\(pc',s')\set (eff (ins ! pc) P pc xt (\ C M ! pc)). pc' < size ins" + by (unfold app_def) simp + + from app\<^sub>0 \ have app: + "xcpt_app (ins!pc) P pc mxs xt (ST,LT) \ app\<^sub>i (ins!pc, P, pc, mxs, T, (ST,LT))" + by (clarsimp simp add: app_def) + + with eff stk reg + have "check_instr (ins!pc) P h stk reg C M pc frs' sh" + proof (cases "ins!pc") + case (Getfield F C) + with app stk reg \ obtain v vT stk' where + field: "P \ C sees F,NonStatic:vT in C" and + stk: "stk = v # stk'" and + conf: "P,h \ v :\ Class C" + by auto + from conf have is_Ref: "is_Ref v" by auto + moreover { + assume "v \ Null" + with conf field is_Ref wf + have "\D vs. h (the_Addr v) = Some (D,vs) \ P \ D \\<^sup>* C" + by (auto dest!: non_npD) + } + ultimately show ?thesis using Getfield field stk hconf + apply clarsimp + apply (rule conjI, fastforce) + apply clarsimp + apply (drule has_visible_field) + apply (drule (1) has_field_mono) + apply (drule (1) hconfD) + apply (unfold oconf_def has_field_def) + apply clarsimp + apply (fastforce dest: has_fields_fun) + done + next + case (Getstatic C F D) + with app stk reg \ obtain vT where + field: "P \ C sees F,Static:vT in D" + by auto + + then show ?thesis using Getstatic field stk shconf + apply clarsimp + apply (rule conjI, fastforce) + apply clarsimp + apply (drule has_visible_field) + apply (drule has_field_idemp) + apply (drule (1) shconfD) + apply (unfold soconf_def has_field_def) + apply clarsimp + apply (fastforce dest: has_fields_fun) + done + next + case (Putfield F C) + with app stk reg \ obtain v ref vT stk' where + field: "P \ C sees F,NonStatic:vT in C" and + stk: "stk = v # ref # stk'" and + confv: "P,h \ v :\ vT" and + confr: "P,h \ ref :\ Class C" + by fastforce + from confr have is_Ref: "is_Ref ref" by simp + moreover { + assume "ref \ Null" + with confr field is_Ref wf + have "\D vs. h (the_Addr ref) = Some (D,vs) \ P \ D \\<^sup>* C" + by (auto dest: non_npD) + } + ultimately show ?thesis using Putfield field stk confv by fastforce + next + case (Invoke M' n) + with app have n: "n < size ST" by simp + + from stk have [simp]: "size stk = size ST" by (rule list_all2_lengthD) + + { assume "stk!n = Null" with n Invoke have ?thesis by simp } + moreover { + assume "ST!n = NT" + with n stk have "stk!n = Null" by (auto simp: list_all2_conv_all_nth) + with n Invoke have ?thesis by simp + } + moreover { + assume Null: "stk!n \ Null" and NT: "ST!n \ NT" + + from NT app Invoke + obtain D D' Ts T m where + D: "ST!n = Class D" and + M': "P \ D sees M',NonStatic: Ts\T = m in D'" and + Ts: "P \ rev (take n ST) [\] Ts" + by auto + + from D stk n have "P,h \ stk!n :\ Class D" + by (auto simp: list_all2_conv_all_nth) + with Null obtain a C' fs where + [simp]: "stk!n = Addr a" "h a = Some (C',fs)" and + "P \ C' \\<^sup>* D" + by (fastforce dest!: conf_ClassD) + + with M' wf obtain m' Ts' T' D'' where + C': "P \ C' sees M',NonStatic: Ts'\T' = m' in D''" and + Ts': "P \ Ts [\] Ts'" + by (auto dest!: sees_method_mono) + + from stk have "P,h \ take n stk [:\] take n ST" .. + hence "P,h \ rev (take n stk) [:\] rev (take n ST)" .. + also note Ts also note Ts' + finally have "P,h \ rev (take n stk) [:\] Ts'" . + + with Invoke Null n C' + have ?thesis by (auto simp add: is_Ref_def2 has_methodI) + } + ultimately show ?thesis by blast + next + case (Invokestatic C M' n) + with app have n: "n \ size ST" by simp + + from stk have [simp]: "size stk = size ST" by (rule list_all2_lengthD) + + from app Invokestatic + obtain D Ts T m where + M': "P \ C sees M',Static: Ts\T = m in D" and + Ts: "P \ rev (take n ST) [\] Ts" + by auto + + from stk have "P,h \ take n stk [:\] take n ST" .. + hence "P,h \ rev (take n stk) [:\] rev (take n ST)" .. + also note Ts + finally have "P,h \ rev (take n stk) [:\] Ts" . + + with Invokestatic n M' + show ?thesis by (auto simp add: is_Ref_def2 has_methodI) + next + case Return + show ?thesis + proof(cases "M = clinit") + case True + have "is_class P C" by(rule sees_method_is_class[OF meth]) + with wf_sees_clinit[OF wf] + obtain m where "P \ C sees clinit,Static: [] \ Void = m in C" + by(fastforce simp: is_class_def) + + with stk app \ meth frames True Return + show ?thesis by (auto simp add: has_methodI) + next + case False with stk app \ meth frames Return + show ?thesis by (auto intro: has_methodI) + qed + qed (auto simp add: list_all2_lengthD) + hence "check P \" using meth pc mxs by (auto simp: check_def intro: has_methodI) + } ultimately + have "check P \" by blast + thus "exec_d P \ \ TypeError" .. +qed +(*>*) + + +text \ + The theorem above tells us that, in welltyped programs, the + defensive machine reaches the same result as the aggressive + one (after arbitrarily many steps). +\ +theorem welltyped_aggressive_imp_defensive: + "wf_jvm_prog\<^bsub>\\<^esub> P \ P,\ \ \ \ \ P \ \ -jvm\ \' + \ P \ (Normal \) -jvmd\ (Normal \')" +(*<*) + apply (simp only: exec_all_def) + apply (erule rtrancl_induct) + apply (simp add: exec_all_d_def1) + apply simp + apply (simp only: exec_all_def [symmetric]) + apply (frule BV_correct, assumption+) + apply (drule no_type_error, assumption, drule no_type_error_commutes, simp) + apply (simp add: exec_all_d_def1) + apply (rule rtrancl_trans, assumption) + apply (drule exec_1_d_NormalI) + apply auto + done +(*>*) + + +text \ + As corollary we get that the aggressive and the defensive machine + are equivalent for welltyped programs (if started in a conformant + state or in the canonical start state) +\ +corollary welltyped_commutes: + fixes \ :: jvm_state + assumes wf: "wf_jvm_prog\<^bsub>\\<^esub> P" and conforms: "P,\ \ \ \" + shows "P \ (Normal \) -jvmd\ (Normal \') = P \ \ -jvm\ \'" + apply rule + apply (erule defensive_imp_aggressive) + apply (erule welltyped_aggressive_imp_defensive [OF wf conforms]) + done + +corollary welltyped_initial_commutes: + assumes wf: "wf_jvm_prog P" + assumes nstart: "\ is_class P Start" + assumes meth: "P \ C sees M,Static:[]\Void = b in C" + assumes nclinit: "M \ clinit" + assumes Obj_start_m: + "(\b' Ts' T' m' D'. P \ Object sees start_m, b' : Ts'\T' = m' in D' + \ b' = Static \ Ts' = [] \ T' = Void)" + defines start: "\ \ start_state P" + shows "start_prog P C M \ (Normal \) -jvmd\ (Normal \') = start_prog P C M \ \ -jvm\ \'" +proof - + from wf obtain \ where wf': "wf_jvm_prog\<^bsub>\\<^esub> P" by (auto simp: wf_jvm_prog_def) + let ?\ = "\_start \" + from start_prog_wf_jvm_prog_phi[where \'="?\", OF wf' nstart meth nclinit \_start Obj_start_m] + have "wf_jvm_prog\<^bsub>?\\<^esub>(start_prog P C M)" by simp + moreover + from wf' nstart meth nclinit \_start(2) have "start_prog P C M,?\ \ \ \" + unfolding start by (rule BV_correct_initial) + ultimately show ?thesis by (rule welltyped_commutes) +qed + + +lemma not_TypeError_eq [iff]: + "x \ TypeError = (\t. x = Normal t)" + by (cases x) auto + +locale cnf = + fixes P and \ and \ + assumes wf: "wf_jvm_prog\<^bsub>\\<^esub> P" + assumes cnf: "correct_state P \ \" + +theorem (in cnf) no_type_errors: + "P \ (Normal \) -jvmd\ \' \ \' \ TypeError" + apply (unfold exec_all_d_def1) + apply (erule rtrancl_induct) + apply simp + apply (fold exec_all_d_def1) + apply (insert cnf wf) + apply clarsimp + apply (drule defensive_imp_aggressive) + apply (frule (2) BV_correct) + apply (auto simp add: exec_1_d_eq dest: no_type_error) + done + +locale start = + fixes P and C and M and \ and T and b and P\<^sub>0 + assumes wf: "wf_jvm_prog P" + assumes nstart: "\ is_class P Start" + assumes sees: "P \ C sees M,Static:[]\Void = b in C" + assumes nclinit: "M \ clinit" + assumes Obj_start_m: "(\b' Ts' T' m' D'. P \ Object sees start_m, b' : Ts'\T' = m' in D' + \ b' = Static \ Ts' = [] \ T' = Void)" + defines "\ \ Normal (start_state P)" + defines [simp]: "P\<^sub>0 \ start_prog P C M" + +corollary (in start) bv_no_type_error: + shows "P\<^sub>0 \ \ -jvmd\ \' \ \' \ TypeError" +proof - + from wf obtain \ where wf': "wf_jvm_prog\<^bsub>\\<^esub> P" by (auto simp: wf_jvm_prog_def) + let ?\ = "\_start \" + from start_prog_wf_jvm_prog_phi[where \'="?\", OF wf' nstart sees nclinit \_start Obj_start_m] + have "wf_jvm_prog\<^bsub>?\\<^esub>P\<^sub>0" by simp + moreover + from BV_correct_initial[where \'="?\", OF wf' nstart sees nclinit \_start(2)] + have "correct_state P\<^sub>0 ?\ (start_state P)" by simp + ultimately have "cnf P\<^sub>0 ?\ (start_state P)" by (rule cnf.intro) + moreover assume "P\<^sub>0 \ \ -jvmd\ \'" + ultimately show ?thesis by (unfold \_def) (rule cnf.no_type_errors) +qed + + +end diff --git a/thys/JinjaDCI/BV/BVSpec.thy b/thys/JinjaDCI/BV/BVSpec.thy new file mode 100644 --- /dev/null +++ b/thys/JinjaDCI/BV/BVSpec.thy @@ -0,0 +1,104 @@ +(* Title: JinjaDCI/BV/BVSpec.thy + + Author: Cornelia Pusch, Gerwin Klein, Susannah Mansky + Copyright 1999 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory BV/BVSpec.thy by Tobias Nipkow +*) + +section \ The Bytecode Verifier \label{sec:BVSpec} \ + +theory BVSpec +imports Effect +begin + +text \ + This theory contains a specification of the BV. The specification + describes correct typings of method bodies; it corresponds + to type \emph{checking}. +\ + + +definition + \ \The method type only contains declared classes:\ + check_types :: "'m prog \ nat \ nat \ ty\<^sub>i' err list \ bool" +where + "check_types P mxs mxl \s \ set \s \ states P mxs mxl" + + \ \An instruction is welltyped if it is applicable and its effect\ + \ \is compatible with the type at all successor instructions:\ +definition + wt_instr :: "['m prog,ty,nat,pc,ex_table,instr,pc,ty\<^sub>m] \ bool" + ("_,_,_,_,_ \ _,_ :: _" [60,0,0,0,0,0,0,61] 60) +where + "P,T,mxs,mpc,xt \ i,pc :: \s \ + app i P mxs T pc mpc xt (\s!pc) \ + (\(pc',\') \ set (eff i P pc xt (\s!pc)). P \ \' \' \s!pc')" + + \ \The type at @{text "pc=0"} conforms to the method calling convention:\ +definition wt_start :: "['m prog,cname,staticb,ty list,nat,ty\<^sub>m] \ bool" +where + "wt_start P C b Ts mxl\<^sub>0 \s \ +case b of NonStatic \ P \ Some ([],OK (Class C)#map OK Ts@replicate mxl\<^sub>0 Err) \' \s!0 + | Static \ P \ Some ([],map OK Ts@replicate mxl\<^sub>0 Err) \' \s!0" + + \ \A method is welltyped if the body is not empty,\ + \ \if the method type covers all instructions and mentions\ + \ \declared classes only, if the method calling convention is respected, and\ + \ \if all instructions are welltyped.\ +definition wt_method :: "['m prog,cname,staticb,ty list,ty,nat,nat,instr list, + ex_table,ty\<^sub>m] \ bool" +where + "wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt \s \ + 0 < size is \ size \s = size is \ + check_types P mxs ((case b of Static \ 0 | NonStatic \ 1)+size Ts+mxl\<^sub>0) (map OK \s) \ + wt_start P C b Ts mxl\<^sub>0 \s \ + (\pc < size is. P,T\<^sub>r,mxs,size is,xt \ is!pc,pc :: \s)" + + \ \A program is welltyped if it is wellformed and all methods are welltyped\ +definition wf_jvm_prog_phi :: "ty\<^sub>P \ jvm_prog \ bool" ("wf'_jvm'_prog\<^bsub>_\<^esub>") +where + "wf_jvm_prog\<^bsub>\\<^esub> \ + wf_prog (\P C (M,b,Ts,T\<^sub>r,(mxs,mxl\<^sub>0,is,xt)). + wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt (\ C M))" + +definition wf_jvm_prog :: "jvm_prog \ bool" +where + "wf_jvm_prog P \ \\. wf_jvm_prog\<^bsub>\\<^esub> P" + +lemma wt_jvm_progD: + "wf_jvm_prog\<^bsub>\\<^esub> P \ \wt. wf_prog wt P" +(*<*) by (unfold wf_jvm_prog_phi_def, blast) (*>*) + +lemma wt_jvm_prog_impl_wt_instr: + "\ wf_jvm_prog\<^bsub>\\<^esub> P; + P \ C sees M,b:Ts \ T = (mxs,mxl\<^sub>0,ins,xt) in C; pc < size ins \ + \ P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M" +(*<*) + apply (unfold wf_jvm_prog_phi_def) + apply (drule (1) sees_wf_mdecl) + apply (simp add: wf_mdecl_def wt_method_def) + done +(*>*) + +lemma wt_jvm_prog_impl_wt_start: + "\ wf_jvm_prog\<^bsub>\\<^esub> P; + P \ C sees M,b:Ts \ T = (mxs,mxl\<^sub>0,ins,xt) in C \ \ + 0 < size ins \ wt_start P C b Ts mxl\<^sub>0 (\ C M)" +(*<*) + apply (unfold wf_jvm_prog_phi_def) + apply (drule (1) sees_wf_mdecl) + apply (simp add: wf_mdecl_def wt_method_def) + done +(*>*) + +lemma wf_jvm_prog_nclinit: +assumes wtp: "wf_jvm_prog\<^bsub>\\<^esub> P" + and meth: "P \ C sees M, b : Ts\T = (mxs, mxl\<^sub>0, ins, xt) in D" + and wt: "P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M" + and pc: "pc < length ins" and \: "\ C M ! pc = Some(ST,LT)" + and ins: "ins ! pc = Invokestatic C\<^sub>0 M\<^sub>0 n" +shows "M\<^sub>0 \ clinit" + using assms by(simp add: wf_jvm_prog_phi_def wt_instr_def app_def) + +end diff --git a/thys/JinjaDCI/BV/BVSpecTypeSafe.thy b/thys/JinjaDCI/BV/BVSpecTypeSafe.thy new file mode 100644 --- /dev/null +++ b/thys/JinjaDCI/BV/BVSpecTypeSafe.thy @@ -0,0 +1,2341 @@ +(* Title: JinjaDCI/BV/BVSpecTypeSafe.thy + + Author: Cornelia Pusch, Gerwin Klein, Susannah Mansky + Copyright 1999 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory BV/BVSpecTypeSafe.thy by Cornelia Pusch and Gerwin Klein +*) + + +section \ BV Type Safety Proof \label{sec:BVSpecTypeSafe} \ + +theory BVSpecTypeSafe +imports BVConform StartProg +begin + +text \ + This theory contains proof that the specification of the bytecode + verifier only admits type safe programs. +\ + +subsection \ Preliminaries \ + +text \ + Simp and intro setup for the type safety proof: +\ +lemmas defs1 = correct_state_def conf_f_def wt_instr_def eff_def norm_eff_def app_def xcpt_app_def + +lemmas widen_rules [intro] = conf_widen confT_widen confs_widens confTs_widen + + +subsection \ Exception Handling \ + + +text \ + For the @{text Invoke} instruction the BV has checked all handlers + that guard the current @{text pc}. +\ +lemma Invoke_handlers: + "match_ex_table P C pc xt = Some (pc',d') \ + \(f,t,D,h,d) \ set (relevant_entries P (Invoke n M) pc xt). + P \ C \\<^sup>* D \ pc \ {f.. pc' = h \ d' = d" + by (induct xt) (auto simp: relevant_entries_def matches_ex_entry_def + is_relevant_entry_def split: if_split_asm) + +text \ + For the @{text Invokestatic} instruction the BV has checked all handlers + that guard the current @{text pc}. +\ +lemma Invokestatic_handlers: + "match_ex_table P C pc xt = Some (pc',d') \ + \(f,t,D,h,d) \ set (relevant_entries P (Invokestatic C\<^sub>0 n M) pc xt). + P \ C \\<^sup>* D \ pc \ {f.. pc' = h \ d' = d" + by (induct xt) (auto simp: relevant_entries_def matches_ex_entry_def + is_relevant_entry_def split: if_split_asm) + +text \ + For the instrs in @{text Called_set} the BV has checked all handlers + that guard the current @{text pc}. +\ +lemma Called_set_handlers: + "match_ex_table P C pc xt = Some (pc',d') \ i \ Called_set \ + \(f,t,D,h,d) \ set (relevant_entries P i pc xt). + P \ C \\<^sup>* D \ pc \ {f.. pc' = h \ d' = d" + by (induct xt) (auto simp: relevant_entries_def matches_ex_entry_def + is_relevant_entry_def split: if_split_asm) + +text \ + We can prove separately that the recursive search for exception + handlers (@{text find_handler}) in the frame stack results in + a conforming state (if there was no matching exception handler + in the current frame). We require that the exception is a valid + heap address, and that the state before the exception occurred + conforms. +\ +lemma uncaught_xcpt_correct: + assumes wt: "wf_jvm_prog\<^bsub>\\<^esub> P" + assumes h: "h xcp = Some obj" + shows "\f. P,\ \ (None, h, f#frs, sh)\ + \ curr_method f \ clinit \ P,\ \ find_handler P xcp h frs sh \" + (is "\f. ?correct (None, h, f#frs, sh) \ ?prem f \ ?correct (?find frs)") +(*<*) +proof (induct frs) + \ \the base + case is trivial as it should be\ + show "?correct (?find [])" by (simp add: correct_state_def) +next + \ \we will need both forms @{text wf_jvm_prog} and @{text wf_prog} later\ + from wt obtain mb where wf: "wf_prog mb P" by (simp add: wf_jvm_prog_phi_def) + + \ \the assumptions for the cons case:\ + fix f f' frs' assume cr: "?correct (None, h, f#f'#frs', sh)" + assume pr: "?prem f" + + \ \the induction hypothesis:\ + assume IH: "\f. ?correct (None, h, f#frs', sh) \ ?prem f \ ?correct (?find frs')" + + from cr pr conf_clinit_Cons[where frs="f'#frs'" and f=f] obtain + confc: "conf_clinit P sh (f'#frs')" + and cr': "?correct (None, h, f'#frs', sh)" by(fastforce simp: correct_state_def) + + obtain stk loc C M pc ics where [simp]: "f' = (stk,loc,C,M,pc,ics)" by (cases f') + + from cr' obtain b Ts T mxs mxl\<^sub>0 ins xt where + meth: "P \ C sees M,b:Ts \ T = (mxs,mxl\<^sub>0,ins,xt) in C" + by (simp add: correct_state_def, blast) + + hence xt[simp]: "ex_table_of P C M = xt" by simp + + have cls: "is_class P C" by(rule sees_method_is_class'[OF meth]) + from cr' obtain sfs where + sfs: "M = clinit \ sh C = Some(sfs,Processing)" by(fastforce simp: defs1 conf_clinit_def) + + show "?correct (?find (f'#frs'))" + proof (cases "match_ex_table P (cname_of h xcp) pc xt") + case None with cr' IH[of f'] show ?thesis + proof(cases "M=clinit") + case True then show ?thesis using xt cr' IH[of f'] None h conf_clinit_Called_Throwing + conf_f_Throwing[where h=h and sh=sh, OF _ cls h sfs] + by(cases frs', auto simp: correct_state_def image_iff) fastforce + qed(auto) + next + fix pc_d + assume "match_ex_table P (cname_of h xcp) pc xt = Some pc_d" + then obtain pc' d' where + match: "match_ex_table P (cname_of h xcp) pc xt = Some (pc',d')" + (is "?match (cname_of h xcp) = _") + by (cases pc_d) auto + + from wt meth cr' [simplified] + have wti: "P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M" + by (fastforce simp: correct_state_def conf_f_def + dest: sees_method_fun + elim!: wt_jvm_prog_impl_wt_instr) + + from cr' obtain ST LT where \: "\ C M ! pc = Some (ST, LT)" + by(fastforce dest: sees_method_fun simp: correct_state_def) + + from cr' \ meth have conf': "conf_f P h sh (ST, LT) ins f'" + by (unfold correct_state_def) (fastforce dest: sees_method_fun) + hence loc: "P,h \ loc [:\\<^sub>\] LT" and + stk: "P,h \ stk [:\] ST" by (unfold conf_f_def) auto + hence [simp]: "size stk = size ST" by (simp add: list_all2_lengthD) + + from cr meth pr + obtain D n M' where + ins: "ins!pc = Invoke n M' \ ins!pc = Invokestatic D n M'" (is "_ = ?i \ _ = ?i'") + by(fastforce dest: sees_method_fun simp: correct_state_def) + + with match obtain f1 t D where + rel: "(f1,t,D,pc',d') \ set (relevant_entries P (ins!pc) pc xt)" and + D: "P \ cname_of h xcp \\<^sup>* D" + by(fastforce dest: Invoke_handlers Invokestatic_handlers) + + from rel have + "(pc', Some (Class D # drop (size ST - d') ST, LT)) \ set (xcpt_eff (ins!pc) P pc (ST,LT) xt)" + (is "(_, Some (?ST',_)) \ _") + by (force simp: xcpt_eff_def image_def) + with wti \ obtain + pc: "pc' < size ins" and + "P \ Some (?ST', LT) \' \ C M ! pc'" + by (clarsimp simp: defs1) blast + then obtain ST' LT' where + \': "\ C M ! pc' = Some (ST',LT')" and + less: "P \ (?ST', LT) \\<^sub>i (ST',LT')" + by (auto simp: sup_state_opt_any_Some) + + let ?f = "(Addr xcp # drop (length stk - d') stk, loc, C, M, pc',No_ics)" + have "conf_f P h sh (ST',LT') ins ?f" + proof - + from wf less loc have "P,h \ loc [:\\<^sub>\] LT'" by simp blast + moreover from D h have "P,h \ Addr xcp :\ Class D" + by (simp add: conf_def obj_ty_def case_prod_unfold) + with less stk + have "P,h \ Addr xcp # drop (length stk - d') stk [:\] ST'" + by (auto intro!: list_all2_dropI) + ultimately show ?thesis using pc conf' by(auto simp: conf_f_def) + qed + + with cr' match \' meth pc + show ?thesis by (unfold correct_state_def) + (cases "M=clinit"; fastforce dest: sees_method_fun simp: conf_clinit_def distinct_clinit_def) + qed +qed +(*>*) + +text \ + The requirement of lemma @{text uncaught_xcpt_correct} (that + the exception is a valid reference on the heap) is always met + for welltyped instructions and conformant states: +\ +lemma exec_instr_xcpt_h: + "\ fst (exec_instr (ins!pc) P h stk vars C M pc ics frs sh) = Some xcp; + P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M; + P,\ \ (None, h, (stk,loc,C,M,pc,ics)#frs, sh)\ \ + \ \obj. h xcp = Some obj" + (is "\ ?xcpt; ?wt; ?correct \ \ ?thesis") +(*<*) +proof - + note [simp] = split_beta + note [split] = if_split_asm option.split_asm + + assume wt: ?wt ?correct + hence pre: "preallocated h" by (simp add: correct_state_def hconf_def) + + assume xcpt: ?xcpt + with exec_instr_xcpts have + opt: "ins!pc = Throw \ xcp \ {a. \x \ sys_xcpts. a = addr_of_sys_xcpt x}" by simp + + with pre show ?thesis + proof (cases "ins!pc") + case Throw with xcpt wt pre show ?thesis + by (clarsimp iff: list_all2_Cons2 simp: defs1) + (auto dest: non_npD simp: is_refT_def elim: preallocatedE) + qed (auto elim: preallocatedE) +qed +(*>*) + +lemma exec_step_xcpt_h: +assumes xcpt: "fst (exec_step P h stk vars C M pc ics frs sh) = Some xcp" + and ins: "instrs_of P C M = ins" + and wti: "P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M" + and correct: "P,\ \ (None, h, (stk,loc,C,M,pc,ics)#frs, sh)\" +shows "\obj. h xcp = Some obj" +proof - + from correct have pre: "preallocated h" by(simp add: defs1 hconf_def) + { fix C' Cs assume ics[simp]: "ics = Calling C' Cs" + with xcpt have "xcp = addr_of_sys_xcpt NoClassDefFoundError" + by(cases ics, auto simp: split_beta split: init_state.splits if_split_asm) + with pre have ?thesis using preallocated_def by force + } + moreover + { fix Cs a assume [simp]: "ics = Throwing Cs a" + with xcpt have eq: "a = xcp" by(cases Cs; simp) + + from correct have "P,h,sh \\<^sub>i (C,M,pc,ics)" by(auto simp: defs1) + with eq have ?thesis by simp + } + moreover + { fix Cs assume ics: "ics = No_ics \ ics = Called Cs" + with exec_instr_xcpt_h[OF _ wti correct] xcpt ins have ?thesis by(cases Cs, auto) + } + ultimately show ?thesis by(cases ics, auto) +qed + +lemma conf_sys_xcpt: + "\preallocated h; C \ sys_xcpts\ \ P,h \ Addr (addr_of_sys_xcpt C) :\ Class C" + by (auto elim: preallocatedE) + +lemma match_ex_table_SomeD: + "match_ex_table P C pc xt = Some (pc',d') \ + \(f,t,D,h,d) \ set xt. matches_ex_entry P C pc (f,t,D,h,d) \ h = pc' \ d=d'" + by (induct xt) (auto split: if_split_asm) + +text \ + Finally we can state that, whenever an exception occurs, the + next state always conforms: +\ +lemma xcpt_correct: + fixes \' :: jvm_state + assumes wtp: "wf_jvm_prog\<^bsub>\\<^esub> P" + assumes meth: "P \ C sees M,b:Ts\T=(mxs,mxl\<^sub>0,ins,xt) in C" + assumes wt: "P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M" + assumes xp: "fst (exec_step P h stk loc C M pc ics frs sh) = Some xcp" + assumes s': "Some \' = exec (P, None, h, (stk,loc,C,M,pc,ics)#frs, sh)" + assumes correct: "P,\ \ (None, h, (stk,loc,C,M,pc,ics)#frs, sh)\" + shows "P,\ \ \'\" +(*<*) +proof - + from wtp obtain wfmb where wf: "wf_prog wfmb P" + by (simp add: wf_jvm_prog_phi_def) + + from meth have ins[simp]: "instrs_of P C M = ins" by simp + have cls: "is_class P C" by(rule sees_method_is_class[OF meth]) + from correct obtain sfs where + sfs: "M = clinit \ sh C = Some(sfs,Processing)" + by(auto simp: correct_state_def conf_clinit_def conf_f_def2) + + note conf_sys_xcpt [elim!] + note xp' = meth s' xp + + from correct meth + obtain ST LT where + h_ok: "P \ h \" and + sh_ok: "P,h \\<^sub>s sh \" and + \_pc: "\ C M ! pc = Some (ST, LT)" and + frame: "conf_f P h sh (ST,LT) ins (stk,loc,C,M,pc,ics)" and + frames: "conf_fs P h sh \ C M (size Ts) T frs" and + confc: "conf_clinit P sh ((stk,loc,C,M,pc,ics)#frs)" and + vics: "P,h,sh \\<^sub>i (C,M,pc,ics)" + by(auto simp: defs1 dest: sees_method_fun) + + from frame obtain + stk: "P,h \ stk [:\] ST" and + loc: "P,h \ loc [:\\<^sub>\] LT" and + pc: "pc < size ins" + by (unfold conf_f_def) auto + + from h_ok have preh: "preallocated h" by (simp add: hconf_def) + + note wtp + moreover + from exec_step_xcpt_h[OF xp ins wt correct] + obtain obj where h: "h xcp = Some obj" by clarify + moreover note correct + ultimately + have fh: "curr_method (stk,loc,C,M,pc,ics) \ clinit + \ P,\ \ find_handler P xcp h frs sh \" by (rule uncaught_xcpt_correct) + with xp' + have "M \ clinit \ \Cs a. ics \ Throwing Cs a + \ match_ex_table P (cname_of h xcp) pc xt = None \ ?thesis" + (is "?nc \ ?t \ ?m (cname_of h xcp) = _ \ _" is "?nc \ ?t \ ?match = _ \ _") + by(cases ics; simp add: split_beta) + moreover + from correct xp' conf_clinit_Called_Throwing conf_f_Throwing[where h=h and sh=sh, OF _ cls h sfs] + have "M = clinit \ \Cs a. ics \ Throwing Cs a + \ match_ex_table P (cname_of h xcp) pc xt = None \ ?thesis" + by(cases frs, auto simp: correct_state_def image_iff split_beta) fastforce + moreover + { fix pc_d assume "?match = Some pc_d" + then obtain pc' d' where some_handler: "?match = Some (pc',d')" + by (cases pc_d) auto + + from stk have [simp]: "size stk = size ST" .. + + from wt \_pc have + eff: "\(pc', s')\set (xcpt_eff (ins!pc) P pc (ST,LT) xt). + pc' < size ins \ P \ s' \' \ C M!pc'" + by (auto simp: defs1) + + from some_handler obtain f t D where + xt: "(f,t,D,pc',d') \ set xt" and + "matches_ex_entry P (cname_of h xcp) pc (f,t,D,pc',d')" + by (auto dest: match_ex_table_SomeD) + + hence match: "P \ cname_of h xcp \\<^sup>* D" "pc \ {f.. ics = Called (C'#Cs)" + + let ?stk' = "Addr xcp # drop (length stk - d') stk" + let ?f = "(?stk', loc, C, M, pc', No_ics)" + from some_handler xp' ics + have \': "\' = (None, h, ?f#frs, sh)" + by (cases ics; simp add: split_beta) + + from xp ics have "xcp = addr_of_sys_xcpt NoClassDefFoundError" + by(cases ics, auto simp: split_beta split: init_state.splits if_split_asm) + with match preh have conf: "P,h \ Addr xcp :\ Class D" by fastforce + + from correct ics obtain C1 where "Called_context P C1 (ins!pc)" + by(fastforce simp: correct_state_def conf_f_def2) + then have "ins!pc \ Called_set" by(rule Called_context_Called_set) + with xt match have "(f,t,D,pc',d') \ set (relevant_entries P (ins!pc) pc xt)" + by(auto simp: relevant_entries_def is_relevant_entry_def) + + with eff obtain ST' LT' where + \_pc': "\ C M ! pc' = Some (ST', LT')" and + pc': "pc' < size ins" and + less: "P \ (Class D # drop (size ST - d') ST, LT) \\<^sub>i (ST', LT')" + by (fastforce simp: xcpt_eff_def sup_state_opt_any_Some) + + with conf loc stk conf_f_def2 frame ics have "conf_f P h sh (ST',LT') ins ?f" + by (auto simp: defs1 intro: list_all2_dropI) + with meth h_ok frames \_pc' \' sh_ok confc ics + have ?thesis + by (unfold correct_state_def) + (auto dest: sees_method_fun conf_clinit_diff' sees_method_is_class; fastforce) + } + moreover + { assume ics: "ics = No_ics \ ics = Called []" + + let ?stk' = "Addr xcp # drop (length stk - d') stk" + let ?f = "(?stk', loc, C, M, pc', No_ics)" + from some_handler xp' ics + have \': "\' = (None, h, ?f#frs, sh)" + by (cases ics; simp add: split_beta) + + from xp ics obtain + "(f,t,D,pc',d') \ set (relevant_entries P (ins!pc) pc xt)" and + conf: "P,h \ Addr xcp :\ Class D" + proof (cases "ins!pc") + case Return + with xp ics have False by(cases ics; cases frs, auto simp: split_beta split: if_split_asm) + then show ?thesis by simp + next + case New with xp match + have "is_relevant_entry P (ins!pc) pc (f,t,D,pc',d')" + by (simp add: is_relevant_entry_def) + moreover + from xp wt correct obtain obj where xcp: "h xcp = Some obj" + by (blast dest: exec_step_xcpt_h[OF _ ins]) + ultimately + show ?thesis using xt match + by (auto simp: relevant_entries_def conf_def case_prod_unfold intro: that) + next + case Getfield with xp ics + have xcp: "xcp = addr_of_sys_xcpt NullPointer \ xcp = addr_of_sys_xcpt NoSuchFieldError + \ xcp = addr_of_sys_xcpt IncompatibleClassChangeError" + by (cases ics; simp add: split_beta split: if_split_asm staticb.splits) + with Getfield match preh have "is_relevant_entry P (ins!pc) pc (f,t,D,pc',d')" + by (fastforce simp: is_relevant_entry_def) + with match preh xt xcp + show ?thesis by(fastforce simp: relevant_entries_def intro: that) + next + case Getstatic with xp match + have "is_relevant_entry P (ins!pc) pc (f,t,D,pc',d')" + by (simp add: is_relevant_entry_def) + moreover + from xp wt correct obtain obj where xcp: "h xcp = Some obj" + by (blast dest: exec_step_xcpt_h[OF _ ins]) + ultimately + show ?thesis using xt match + by (auto simp: relevant_entries_def conf_def case_prod_unfold intro: that) + next + case Putfield with xp ics + have xcp: "xcp = addr_of_sys_xcpt NullPointer \ xcp = addr_of_sys_xcpt NoSuchFieldError + \ xcp = addr_of_sys_xcpt IncompatibleClassChangeError" + by (cases ics; simp add: split_beta split: if_split_asm staticb.splits) + with Putfield match preh have "is_relevant_entry P (ins!pc) pc (f,t,D,pc',d')" + by (fastforce simp: is_relevant_entry_def) + with match preh xt xcp + show ?thesis by (fastforce simp: relevant_entries_def intro: that) + next + case Putstatic with xp match + have "is_relevant_entry P (ins!pc) pc (f,t,D,pc',d')" + by (simp add: is_relevant_entry_def) + moreover + from xp wt correct obtain obj where xcp: "h xcp = Some obj" + by (blast dest: exec_step_xcpt_h[OF _ ins]) + ultimately + show ?thesis using xt match + by (auto simp: relevant_entries_def conf_def case_prod_unfold intro: that) + next + case Checkcast with xp ics + have [simp]: "xcp = addr_of_sys_xcpt ClassCast" + by (cases ics; simp add: split_beta split: if_split_asm) + with Checkcast match preh have "is_relevant_entry P (ins!pc) pc (f,t,D,pc',d')" + by (simp add: is_relevant_entry_def) + with match preh xt + show ?thesis by (fastforce simp: relevant_entries_def intro: that) + next + case Invoke with xp match + have "is_relevant_entry P (ins!pc) pc (f,t,D,pc',d')" + by (simp add: is_relevant_entry_def) + moreover + from xp wt correct obtain obj where xcp: "h xcp = Some obj" + by (blast dest: exec_step_xcpt_h[OF _ ins]) + ultimately + show ?thesis using xt match + by (auto simp: relevant_entries_def conf_def case_prod_unfold intro: that) + next + case Invokestatic with xp match + have "is_relevant_entry P (ins!pc) pc (f,t,D,pc',d')" + by (simp add: is_relevant_entry_def) + moreover + from xp wt correct obtain obj where xcp: "h xcp = Some obj" + by (blast dest: exec_step_xcpt_h[OF _ ins]) + ultimately + show ?thesis using xt match + by (auto simp: relevant_entries_def conf_def case_prod_unfold intro: that) + next + case Throw with xp match preh + have "is_relevant_entry P (ins!pc) pc (f,t,D,pc',d')" + by (simp add: is_relevant_entry_def) + moreover + from xp wt correct obtain obj where xcp: "h xcp = Some obj" + by (blast dest: exec_step_xcpt_h[OF _ ins]) + ultimately + show ?thesis using xt match + by (auto simp: relevant_entries_def conf_def case_prod_unfold intro: that) + qed(cases ics, (auto)[5])+ + + with eff obtain ST' LT' where + \_pc': "\ C M ! pc' = Some (ST', LT')" and + pc': "pc' < size ins" and + less: "P \ (Class D # drop (size ST - d') ST, LT) \\<^sub>i (ST', LT')" + by (fastforce simp: xcpt_eff_def sup_state_opt_any_Some) + + with conf loc stk conf_f_def2 frame ics have "conf_f P h sh (ST',LT') ins ?f" + by (auto simp: defs1 intro: list_all2_dropI) + with meth h_ok frames \_pc' \' sh_ok confc ics + have ?thesis + by (unfold correct_state_def) (auto dest: sees_method_fun conf_clinit_diff'; fastforce) + } + ultimately + have "\Cs a. ics \ Throwing Cs a \ ?thesis" by(cases ics; metis list.exhaust) + } + moreover + { fix Cs a assume "ics = Throwing Cs a" + with xp' have ics: "ics = Throwing [] xcp" by(cases Cs; clarsimp) + + let ?frs = "(stk,loc,C,M,pc,No_ics)#frs" + + have eT: "exec_step P h stk loc C M pc (Throwing [] xcp) frs sh = (Some xcp, h, ?frs, sh)" + by auto + with xp' ics have \'_fh: "\' = find_handler P xcp h ?frs sh" by simp + + from meth have [simp]: "xt = ex_table_of P C M" by simp + + let ?match = "match_ex_table P (cname_of h xcp) pc xt" + + { assume clinit: "M = clinit" and None: "?match = None" + note asms = clinit None + + have "P,\ |- find_handler P xcp h ?frs sh [ok]" + proof(cases frs) + case Nil + with h_ok sh_ok asms show "P,\ |- find_handler P xcp h ?frs sh [ok]" + by(simp add: correct_state_def) + next + case [simp]: (Cons f' frs') + obtain stk' loc' C' M' pc' ics' where + [simp]: "f' = (stk',loc',C',M',pc',ics')" by(cases f') + + have cls: "is_class P C" by(rule sees_method_is_class[OF meth]) + have shC: "sh C = Some(sfs,Processing)" by(rule sfs[OF clinit]) + + from correct obtain b Ts T mxs' mxl\<^sub>0' ins' xt' ST' LT' where + meth': "P \ C' sees M', b : Ts\T = (mxs', mxl\<^sub>0', ins', xt') in C'" and + \_pc': "\ C' M' ! pc' = \(ST', LT')\" and + frame': "conf_f P h sh (ST',LT') ins' (stk', loc', C', M', pc', ics')" and + frames': "conf_fs P h sh \ C' M' (length Ts) T frs'" and + confc': "conf_clinit P sh ((stk',loc',C',M',pc',ics')#frs')" + by(auto dest: conf_clinit_Cons simp: correct_state_def) + + from meth' have + ins'[simp]: "instrs_of P C' M' = ins'" + and [simp]: "xt' = ex_table_of P C' M'" by simp+ + + let ?f' = "case ics' of Called Cs' \ (stk',loc',C',M',pc',Throwing (C#Cs') xcp) + | _ \ (stk',loc',C',M',pc',ics')" + + from asms confc have confc_T: "conf_clinit P sh (?f'#frs')" + by(cases ics', auto simp: conf_clinit_def distinct_clinit_def) + + from asms conf_f_Throwing[where h=h and sh=sh, OF _ cls h shC] frame' have + frame_T: "conf_f P h sh (ST', LT') ins' ?f'" by(cases ics'; simp) + with h_ok sh_ok meth' \_pc' confc_T frames' + have "P,\ |- (None, h, ?f'#frs', sh) [ok]" + by(cases ics') (fastforce simp: correct_state_def)+ + + with asms show ?thesis by(cases ics'; simp) + qed + } + moreover + { assume asms: "M \ clinit" "?match = None" + + from asms uncaught_xcpt_correct[OF wtp h correct] + have "P,\ |- find_handler P xcp h frs sh [ok]" by simp + with asms have "P,\ |- find_handler P xcp h ?frs sh [ok]" by auto + } + moreover + { fix pc_d assume some_handler: "?match = \pc_d\" + (is "?match = \pc_d\") + then obtain pc1 d1 where sh': "?match = Some(pc1,d1)" by(cases pc_d, simp) + + let ?stk' = "Addr xcp # drop (length stk - d1) stk" + let ?f = "(?stk', loc, C, M, pc1, No_ics)" + + from stk have [simp]: "size stk = size ST" .. + + from wt \_pc have + eff: "\(pc1, s')\set (xcpt_eff (ins!pc) P pc (ST,LT) xt). + pc1 < size ins \ P \ s' \' \ C M!pc1" + by (auto simp: defs1) + + from match_ex_table_SomeD[OF sh'] obtain f t D where + xt: "(f,t,D,pc1,d1) \ set xt" and + "matches_ex_entry P (cname_of h xcp) pc (f,t,D,pc1,d1)" by auto + + hence match: "P \ cname_of h xcp \\<^sup>* D" "pc \ {f.. Called_set" by(rule Called_context_Called_set) + with match xt xp ics obtain + res: "(f,t,D,pc1,d1) \ set (relevant_entries P (ins!pc) pc xt)" + by(auto simp: relevant_entries_def is_relevant_entry_def) + + with h match xt xp ics have conf: "P,h \ Addr xcp :\ Class D" + by (auto simp: relevant_entries_def conf_def case_prod_unfold) + + with eff res obtain ST1 LT1 where + \_pc1: "\ C M ! pc1 = Some (ST1, LT1)" and + pc1: "pc1 < size ins" and + less1: "P \ (Class D # drop (size ST - d1) ST, LT) \\<^sub>i (ST1, LT1)" + by (fastforce simp: xcpt_eff_def sup_state_opt_any_Some) + + with conf loc stk conf_f_def2 frame ics have frame1: "conf_f P h sh (ST1,LT1) ins ?f" + by (auto simp: defs1 intro: list_all2_dropI) + + from \_pc1 h_ok sh_ok meth frame1 frames conf_clinit_diff'[OF confc] have + "P,\ |- (None, h, ?f # frs, sh) [ok]" by(fastforce simp: correct_state_def) + with sh' have "P,\ |- find_handler P xcp h ?frs sh [ok]" by auto + } + ultimately + have cr': "P,\ |- find_handler P xcp h ?frs sh [ok]" by(cases "?match") blast+ + + with \'_fh have ?thesis by simp + } + ultimately + show ?thesis by (cases "?match") blast+ +qed +(*>*) + +(**********Non-exception Single-step correctness*************************) +declare defs1 [simp] + +subsection \ Initialization procedure steps \ + +text \ + In this section we prove that, for states that result in a step of the + initialization procedure rather than an instruction execution, the state + after execution of the step still conforms. +\ + +lemma Calling_correct: + fixes \' :: jvm_state + assumes wtprog: "wf_jvm_prog\<^bsub>\\<^esub> P" + assumes mC: "P \ C sees M,b:Ts\T=(mxs,mxl\<^sub>0,ins,xt) in C" + assumes s': "Some \' = exec (P, None, h, (stk,loc,C,M,pc,ics)#frs, sh)" + assumes cf: "P,\ \ (None, h, (stk,loc,C,M,pc,ics)#frs, sh)\" + assumes xc: "fst (exec_step P h stk loc C M pc ics frs sh) = None" + assumes ics: "ics = Calling C' Cs" + + shows "P,\ \ \'\" +proof - + from wtprog obtain wfmb where wf: "wf_prog wfmb P" + by (simp add: wf_jvm_prog_phi_def) + + from mC cf obtain ST LT where + h_ok: "P \ h \" and + sh_ok: "P,h \\<^sub>s sh \" and + \: "\ C M ! pc = Some (ST,LT)" and + stk: "P,h \ stk [:\] ST" and loc: "P,h \ loc [:\\<^sub>\] LT" and + pc: "pc < size ins" and + frame: "conf_f P h sh (ST, LT) ins (stk,loc,C,M,pc,ics)" and + fs: "conf_fs P h sh \ C M (size Ts) T frs" and + confc: "conf_clinit P sh ((stk,loc,C,M,pc,ics)#frs)" and + vics: "P,h,sh \\<^sub>i (C,M,pc,ics)" + by (fastforce dest: sees_method_fun) + + with ics have confc\<^sub>0: "conf_clinit P sh ((stk,loc,C,M,pc,Calling C' Cs)#frs)" by simp + + from vics ics have cls': "is_class P C'" by auto + + { assume None: "sh C' = None" + + let ?sh = "sh(C' \ (sblank P C', Prepared))" + + obtain FDTs where + flds: "P \ C' has_fields FDTs" using wf_Fields_Ex[OF wf cls'] by clarsimp + + from shconf_upd_obj[where C=C', OF sh_ok soconf_sblank[OF flds]] + have sh_ok': "P,h \\<^sub>s ?sh \" by simp + + from None have "\sfs. sh C' \ Some(sfs,Processing)" by simp + with conf_clinit_nProc_dist[OF confc] have + dist': "distinct (C' # clinit_classes ((stk, loc, C, M, pc, ics) # frs))" by simp + then have dist'': "distinct (C' # clinit_classes frs)" by simp + + have confc': "conf_clinit P ?sh ((stk, loc, C, M, pc, ics) # frs)" + by(rule conf_clinit_shupd[OF confc dist']) + have fs': "conf_fs P h ?sh \ C M (size Ts) T frs" by(rule conf_fs_shupd[OF fs dist'']) + from vics ics have vics': "P,h,?sh \\<^sub>i (C, M, pc, ics)" by auto + + from s' ics None have "\' = (None, h, (stk, loc, C, M, pc, ics)#frs, ?sh)" by auto + + with mC h_ok sh_ok' \ stk loc pc fs' confc vics' confc' frame None + have ?thesis by fastforce + } + moreover + { fix a assume "sh C' = Some a" + then obtain sfs i where shC'[simp]: "sh C' = Some(sfs,i)" by(cases a, simp) + + from confc ics have last: "\sobj. sh (last(C'#Cs)) = Some sobj" + by(fastforce simp: conf_clinit_def) + + let "?f" = "\ics'. (stk, loc, C, M, pc, ics'::init_call_status)" + + { assume i: "i = Done \ i = Processing" + let ?ics = "Called Cs" + + from last vics ics have vics': "P,h,sh \\<^sub>i (C, M, pc, ?ics)" by auto + from confc ics have confc': "conf_clinit P sh (?f ?ics#frs)" + by(cases "M=clinit"; clarsimp simp: conf_clinit_def distinct_clinit_def) + + from i s' ics have "\' = (None, h, ?f ?ics#frs, sh)" by auto + + with mC h_ok sh_ok \ stk loc pc fs confc' vics' frame ics + have ?thesis by fastforce + } + moreover + { assume i[simp]: "i = Error" + let ?a = "addr_of_sys_xcpt NoClassDefFoundError" + let ?ics = "Throwing Cs ?a" + + from h_ok have preh: "preallocated h" by (simp add: hconf_def) + then obtain obj where ha: "h ?a = Some obj" by(clarsimp simp: preallocated_def sys_xcpts_def) + with vics ics have vics': "P,h,sh \\<^sub>i (C, M, pc, ?ics)" by auto + + from confc ics have confc'': "conf_clinit P sh (?f ?ics#frs)" + by(cases "M=clinit"; clarsimp simp: conf_clinit_def distinct_clinit_def) + + from s' ics have \': "\' = (None, h, ?f ?ics#frs, sh)" by auto + + from mC h_ok sh_ok \ stk loc pc fs confc'' vics \' ics ha + have ?thesis by fastforce + } + moreover + { assume i[simp]: "i = Prepared" + let ?sh = "sh(C' \ (sfs,Processing))" + let ?D = "fst(the(class P C'))" + let ?ics = "if C' = Object then Called (C'#Cs) else Calling ?D (C'#Cs)" + + from shconf_upd_obj[where C=C', OF sh_ok shconfD[OF sh_ok shC']] + have sh_ok': "P,h \\<^sub>s ?sh \" by simp + + from cls' have "C' \ Object \ P \ C' \\<^sup>* ?D" by(auto simp: is_class_def intro!: subcls1I) + with is_class_supclass[OF wf _ cls'] have D: "C' \ Object \ is_class P ?D" by simp + + from i have "\sfs. sh C' \ Some(sfs,Processing)" by simp + with conf_clinit_nProc_dist[OF confc\<^sub>0] have + dist': "distinct (C' # clinit_classes ((stk, loc, C, M, pc, Calling C' Cs) # frs))" by fast + then have dist'': "distinct (C' # clinit_classes frs)" by simp + + from conf_clinit_shupd_Calling[OF confc\<^sub>0 dist' cls'] + conf_clinit_shupd_Called[OF confc\<^sub>0 dist' cls'] + have confc': "conf_clinit P ?sh (?f ?ics#frs)" by clarsimp + with last ics have "\sobj. ?sh (last(C'#Cs)) = Some sobj" + by(auto simp: conf_clinit_def fun_upd_apply) + with D vics ics have vics': "P,h,?sh \\<^sub>i (C, M, pc, ?ics)" by auto + + have fs': "conf_fs P h ?sh \ C M (size Ts) T frs" by(rule conf_fs_shupd[OF fs dist'']) + + from frame vics' have frame': "conf_f P h ?sh (ST, LT) ins (?f ?ics)" by simp + + from i s' ics have "\' = (None, h, ?f ?ics#frs, ?sh)" by(auto simp: if_split_asm) + + with mC h_ok sh_ok' \ stk loc pc fs' confc' frame' ics + have ?thesis by fastforce + } + ultimately have ?thesis by(cases i, auto) + } + ultimately show ?thesis by(cases "sh C'", auto) +qed + +lemma Throwing_correct: + fixes \' :: jvm_state + assumes wtprog: "wf_jvm_prog\<^bsub>\\<^esub> P" + assumes mC: "P \ C sees M,b:Ts\T=(mxs,mxl\<^sub>0,ins,xt) in C" + assumes s': "Some \' = exec (P, None, h, (stk,loc,C,M,pc,ics)#frs, sh)" + assumes cf: "P,\ \ (None, h, (stk,loc,C,M,pc,ics)#frs, sh)\" + assumes xc: "fst (exec_step P h stk loc C M pc ics frs sh) = None" + assumes ics: "ics = Throwing (C'#Cs) a" + + shows "P,\ \ \'\" +proof - + from wtprog obtain wfmb where wf: "wf_prog wfmb P" + by (simp add: wf_jvm_prog_phi_def) + + from mC cf obtain ST LT where + h_ok: "P \ h \" and + sh_ok: "P,h \\<^sub>s sh \" and + \: "\ C M ! pc = Some (ST,LT)" and + stk: "P,h \ stk [:\] ST" and loc: "P,h \ loc [:\\<^sub>\] LT" and + pc: "pc < size ins" and + frame: "conf_f P h sh (ST, LT) ins (stk,loc,C,M,pc,ics)" and + fs: "conf_fs P h sh \ C M (size Ts) T frs" and + confc: "conf_clinit P sh ((stk,loc,C,M,pc,ics)#frs)" and + vics: "P,h,sh \\<^sub>i (C,M,pc,ics)" + by (fastforce dest: sees_method_fun) + + with ics have confc\<^sub>0: "conf_clinit P sh ((stk,loc,C,M,pc,Throwing (C'#Cs) a)#frs)" by simp + + from frame ics mC have + cc: "\C1. Called_context P C1 (ins ! pc)" by(clarsimp simp: conf_f_def2) + + from frame ics obtain obj where ha: "h a = Some obj" by(auto simp: conf_f_def2) + + from confc ics obtain sfs i where shC': "sh C' = Some(sfs,i)" by(clarsimp simp: conf_clinit_def) + then have sfs: "P,h,C' \\<^sub>s sfs \" by(rule shconfD[OF sh_ok]) + + from s' ics + have \': "\' = (None, h, (stk,loc,C,M,pc,Throwing Cs a)#frs, sh(C' \ (fst(the(sh C')), Error)))" + (is "\' = (None, h, ?f'#frs, ?sh')") + by simp + + from confc ics have dist: "distinct (C' # clinit_classes (?f' # frs))" + by (simp add: conf_clinit_def distinct_clinit_def) + then have dist': "distinct (C' # clinit_classes frs)" by simp + + from conf_clinit_Throwing confc ics have confc': "conf_clinit P sh (?f' # frs)" by simp + + from shconf_upd_obj[OF sh_ok sfs] shC' have "P,h \\<^sub>s ?sh' \" by simp + moreover + have "conf_fs P h ?sh' \ C M (length Ts) T frs" by(rule conf_fs_shupd[OF fs dist']) + moreover + have "conf_clinit P ?sh' (?f' # frs)" by(rule conf_clinit_shupd[OF confc' dist]) + moreover note \' h_ok mC \ pc stk loc ha cc + ultimately show "P,\ \ \' \" by fastforce +qed + +lemma Called_correct: + fixes \' :: jvm_state + assumes wtprog: "wf_jvm_prog\<^bsub>\\<^esub> P" + assumes mC: "P \ C sees M,b:Ts\T=(mxs,mxl\<^sub>0,ins,xt) in C" + assumes s': "Some \' = exec (P, None, h, (stk,loc,C,M,pc,ics)#frs, sh)" + assumes cf: "P,\ \ (None, h, (stk,loc,C,M,pc,ics)#frs, sh)\" + assumes xc: "fst (exec_step P h stk loc C M pc ics frs sh) = None" + assumes ics[simp]: "ics = Called (C'#Cs)" + + shows "P,\ \ \'\" +proof - + from wtprog obtain wfmb where wf: "wf_prog wfmb P" + by (simp add: wf_jvm_prog_phi_def) + + from mC cf obtain ST LT where + h_ok: "P \ h \" and + sh_ok: "P,h \\<^sub>s sh \" and + \: "\ C M ! pc = Some (ST,LT)" and + stk: "P,h \ stk [:\] ST" and loc: "P,h \ loc [:\\<^sub>\] LT" and + pc: "pc < size ins" and + frame: "conf_f P h sh (ST, LT) ins (stk,loc,C,M,pc,ics)" and + fs: "conf_fs P h sh \ C M (size Ts) T frs" and + confc: "conf_clinit P sh ((stk,loc,C,M,pc,ics)#frs)" and + vics: "P,h,sh \\<^sub>i (C,M,pc,ics)" + by (fastforce dest: sees_method_fun) + + then have confc\<^sub>0: "conf_clinit P sh ((stk,loc,C,M,pc,Called (C'#Cs))#frs)" by simp + + from frame mC obtain C1 sobj where + ss: "Called_context P C1 (ins ! pc)" and + shC1: "sh C1 = Some sobj" by(clarsimp simp: conf_f_def2) + + from confc wf_sees_clinit[OF wf] obtain mxs' mxl' ins' xt' where + clinit: "P \ C' sees clinit,Static: [] \ Void=(mxs',mxl',ins',xt') in C'" + by(fastforce simp: conf_clinit_def is_class_def) + + let ?loc' = "replicate mxl' undefined" + + from s' clinit + have \': "\' = (None, h, ([],?loc',C',clinit,0,No_ics)#(stk,loc,C,M,pc,Called Cs)#frs, sh)" + (is "\' = (None, h, ?if#?f'#frs, sh)") + by simp + + with wtprog clinit + obtain start: "wt_start P C' Static [] mxl' (\ C' clinit)" and ins': "ins' \ []" + by (auto dest: wt_jvm_prog_impl_wt_start) + then obtain LT\<^sub>0 where LT\<^sub>0: "\ C' clinit ! 0 = Some ([], LT\<^sub>0)" + by (clarsimp simp: wt_start_def defs1 sup_state_opt_any_Some split: staticb.splits) + moreover + have "conf_f P h sh ([], LT\<^sub>0) ins' ?if" + proof - + let ?LT = "replicate mxl' Err" + have "P,h \ ?loc' [:\\<^sub>\] ?LT" by simp + also from start LT\<^sub>0 have "P \ \ [\\<^sub>\] LT\<^sub>0" by (simp add: wt_start_def) + finally have "P,h \ ?loc' [:\\<^sub>\] LT\<^sub>0" . + thus ?thesis using ins' by simp + qed + moreover + from conf_clinit_Called confc clinit have "conf_clinit P sh (?if # ?f' # frs)" by simp + moreover note \' h_ok sh_ok mC \ pc stk loc clinit ss shC1 fs + ultimately show "P,\ \ \' \" by fastforce +qed + +subsection \ Single Instructions \ + +text \ + In this section we prove for each single (welltyped) instruction + that the state after execution of the instruction still conforms. + Since we have already handled exceptions above, we can now assume that + no exception occurs in this step. For instructions that may call + the initialization procedure, we cover the calling and non-calling + cases separately. +\ + +lemma Invoke_correct: + fixes \' :: jvm_state + assumes wtprog: "wf_jvm_prog\<^bsub>\\<^esub> P" + assumes meth_C: "P \ C sees M,b:Ts\T=(mxs,mxl\<^sub>0,ins,xt) in C" + assumes ins: "ins ! pc = Invoke M' n" + assumes wti: "P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M" + assumes \': "Some \' = exec (P, None, h, (stk,loc,C,M,pc,ics)#frs, sh)" + assumes approx: "P,\ \ (None, h, (stk,loc,C,M,pc,ics)#frs, sh)\" + assumes no_xcp: "fst (exec_step P h stk loc C M pc ics frs sh) = None" + shows "P,\ \ \'\" +(*<*) +proof - + from meth_C approx ins have [simp]: "ics = No_ics" by(cases ics, auto) + + note split_paired_Ex [simp del] + + from wtprog obtain wfmb where wfprog: "wf_prog wfmb P" + by (simp add: wf_jvm_prog_phi_def) + + from ins meth_C approx obtain ST LT where + heap_ok: "P\ h\" and + \_pc: "\ C M!pc = Some (ST,LT)" and + frame: "conf_f P h sh (ST,LT) ins (stk,loc,C,M,pc,ics)" and + frames: "conf_fs P h sh \ C M (size Ts) T frs" and + confc: "conf_clinit P sh ((stk,loc,C,M,pc,ics)#frs)" + by (fastforce dest: sees_method_fun) + + from ins wti \_pc + have n: "n < size ST" by simp + + { assume "stk!n = Null" + with ins no_xcp meth_C have False by (simp add: split_beta) + hence ?thesis .. + } + moreover + { assume "ST!n = NT" + moreover + from frame have "P,h \ stk [:\] ST" by simp + with n have "P,h \ stk!n :\ ST!n" by (simp add: list_all2_conv_all_nth) + ultimately + have "stk!n = Null" by simp + with ins no_xcp meth_C have False by (simp add: split_beta) + hence ?thesis .. + } + moreover { + assume NT: "ST!n \ NT" and Null: "stk!n \ Null" + + from NT ins wti \_pc obtain D D' b Ts T m ST' LT' where + D: "ST!n = Class D" and + pc': "pc+1 < size ins" and + m_D: "P \ D sees M',b: Ts\T = m in D'" and + Ts: "P \ rev (take n ST) [\] Ts" and + \': "\ C M ! (pc+1) = Some (ST', LT')" and + LT': "P \ LT [\\<^sub>\] LT'" and + ST': "P \ (T # drop (n+1) ST) [\] ST'" and + b[simp]: "b = NonStatic" + by (clarsimp simp: sup_state_opt_any_Some) + + from frame obtain + stk: "P,h \ stk [:\] ST" and + loc: "P,h \ loc [:\\<^sub>\] LT" by simp + + from n stk D have "P,h \ stk!n :\ Class D" + by (auto simp: list_all2_conv_all_nth) + with Null obtain a C' fs where + Addr: "stk!n = Addr a" and + obj: "h a = Some (C',fs)" and + C'subD: "P \ C' \\<^sup>* D" + by (fastforce dest!: conf_ClassD) + + with wfprog m_D no_xcp + obtain Ts' T' D'' mxs' mxl' ins' xt' where + m_C': "P \ C' sees M',NonStatic: Ts'\T' = (mxs',mxl',ins',xt') in D''" and + T': "P \ T' \ T" and + Ts': "P \ Ts [\] Ts'" + by (auto dest: sees_method_mono) + with wf_NonStatic_nclinit wtprog have nclinit: "M' \ clinit" by(simp add: wf_jvm_prog_phi_def) + + have D''subD': "P \ D'' \\<^sup>* D'" by(rule sees_method_decl_mono[OF C'subD m_D m_C']) + + let ?loc' = "Addr a # rev (take n stk) @ replicate mxl' undefined" + let ?f' = "([], ?loc', D'', M', 0, No_ics)" + let ?f = "(stk, loc, C, M, pc, ics)" + + from Addr obj m_C' ins \' meth_C no_xcp + have s': "\' = (None, h, ?f' # ?f # frs, sh)" by simp + + from Ts n have [simp]: "size Ts = n" + by (auto dest: list_all2_lengthD simp: min_def) + with Ts' have [simp]: "size Ts' = n" + by (auto dest: list_all2_lengthD) + + from m_C' wfprog + obtain mD'': "P \ D'' sees M',NonStatic:Ts'\T'=(mxs',mxl',ins',xt') in D''" + by (fast dest: sees_method_idemp) + moreover + with wtprog + obtain start: "wt_start P D'' NonStatic Ts' mxl' (\ D'' M')" and ins': "ins' \ []" + by (auto dest: wt_jvm_prog_impl_wt_start) + then obtain LT\<^sub>0 where LT\<^sub>0: "\ D'' M' ! 0 = Some ([], LT\<^sub>0)" + by (clarsimp simp: wt_start_def defs1 sup_state_opt_any_Some split: staticb.splits) + moreover + have "conf_f P h sh ([], LT\<^sub>0) ins' ?f'" + proof - + let ?LT = "OK (Class D'') # (map OK Ts') @ (replicate mxl' Err)" + + from stk have "P,h \ take n stk [:\] take n ST" .. + hence "P,h \ rev (take n stk) [:\] rev (take n ST)" by simp + also note Ts also note Ts' finally + have "P,h \ rev (take n stk) [:\\<^sub>\] map OK Ts'" by simp + also + have "P,h \ replicate mxl' undefined [:\\<^sub>\] replicate mxl' Err" + by simp + also from m_C' have "P \ C' \\<^sup>* D''" by (rule sees_method_decl_above) + with obj have "P,h \ Addr a :\ Class D''" by (simp add: conf_def) + ultimately + have "P,h \ ?loc' [:\\<^sub>\] ?LT" by simp + also from start LT\<^sub>0 have "P \ \ [\\<^sub>\] LT\<^sub>0" by (simp add: wt_start_def) + finally have "P,h \ ?loc' [:\\<^sub>\] LT\<^sub>0" . + thus ?thesis using ins' nclinit by simp + qed + moreover + have "conf_clinit P sh (?f'#?f#frs)" using conf_clinit_Invoke[OF confc nclinit] by simp + ultimately + have ?thesis using s' \_pc approx meth_C m_D T' ins D nclinit D''subD' + by(fastforce dest: sees_method_fun [of _ C]) + } + ultimately show ?thesis by blast +qed +(*>*) + +lemma Invokestatic_nInit_correct: + fixes \' :: jvm_state + assumes wtprog: "wf_jvm_prog\<^bsub>\\<^esub> P" + assumes meth_C: "P \ C sees M,b:Ts\T=(mxs,mxl\<^sub>0,ins,xt) in C" + assumes ins: "ins ! pc = Invokestatic D M' n" and nclinit: "M' \ clinit" + assumes wti: "P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M" + assumes \': "Some \' = exec (P, None, h, (stk,loc,C,M,pc,ics)#frs, sh)" + assumes approx: "P,\ \ (None, h, (stk,loc,C,M,pc,ics)#frs, sh)\" + assumes no_xcp: "fst (exec_step P h stk loc C M pc ics frs sh) = None" + assumes cs: "ics = Called [] \ (ics = No_ics \ (\sfs. sh (fst(method P D M')) = Some(sfs, Done)))" + shows "P,\ \ \'\" +(*<*) +proof - + note split_paired_Ex [simp del] + + from wtprog obtain wfmb where wfprog: "wf_prog wfmb P" + by (simp add: wf_jvm_prog_phi_def) + + from ins meth_C approx obtain ST LT where + heap_ok: "P\ h\" and + \_pc: "\ C M!pc = Some (ST,LT)" and + frame: "conf_f P h sh (ST,LT) ins (stk,loc,C,M,pc,ics)" and + frames: "conf_fs P h sh \ C M (size Ts) T frs" and + confc: "conf_clinit P sh ((stk,loc,C,M,pc,ics)#frs)" + by (fastforce dest: sees_method_fun) + + from ins wti \_pc have n: "n \ size ST" by simp + + from ins wti \_pc obtain D' b Ts T mxs' mxl' ins' xt' ST' LT' where + pc': "pc+1 < size ins" and + m_D: "P \ D sees M',b: Ts\T = (mxs',mxl',ins',xt') in D'" and + Ts: "P \ rev (take n ST) [\] Ts" and + \': "\ C M ! (pc+1) = Some (ST', LT')" and + LT': "P \ LT [\\<^sub>\] LT'" and + ST': "P \ (T # drop n ST) [\] ST'" and + b[simp]: "b = Static" + by (clarsimp simp: sup_state_opt_any_Some) + + from frame obtain + stk: "P,h \ stk [:\] ST" and + loc: "P,h \ loc [:\\<^sub>\] LT" by simp + + let ?loc' = "rev (take n stk) @ replicate mxl' undefined" + let ?f' = "([], ?loc', D', M', 0, No_ics)" + let ?f = "(stk, loc, C, M, pc, No_ics)" + + from m_D ins \' meth_C no_xcp cs + have s': "\' = (None, h, ?f' # ?f # frs, sh)" by auto + + from Ts n have [simp]: "size Ts = n" + by (auto dest: list_all2_lengthD) + + from m_D wfprog b + obtain mD': "P \ D' sees M',Static:Ts\T=(mxs',mxl',ins',xt') in D'" + by (fast dest: sees_method_idemp) + moreover + with wtprog + obtain start: "wt_start P D' Static Ts mxl' (\ D' M')" and ins': "ins' \ []" + by (auto dest: wt_jvm_prog_impl_wt_start) + then obtain LT\<^sub>0 where LT\<^sub>0: "\ D' M' ! 0 = Some ([], LT\<^sub>0)" + by (clarsimp simp: wt_start_def defs1 sup_state_opt_any_Some split: staticb.splits) + moreover + have "conf_f P h sh ([], LT\<^sub>0) ins' ?f'" + proof - + let ?LT = "(map OK Ts) @ (replicate mxl' Err)" + + from stk have "P,h \ take n stk [:\] take n ST" .. + hence "P,h \ rev (take n stk) [:\] rev (take n ST)" by simp + also note Ts finally + have "P,h \ rev (take n stk) [:\\<^sub>\] map OK Ts" by simp + also + have "P,h \ replicate mxl' undefined [:\\<^sub>\] replicate mxl' Err" + by simp + also from m_D have "P \ D \\<^sup>* D'" by (rule sees_method_decl_above) + ultimately + have "P,h \ ?loc' [:\\<^sub>\] ?LT" by simp + also from start LT\<^sub>0 have "P \ \ [\\<^sub>\] LT\<^sub>0" by (simp add: wt_start_def) + finally have "P,h \ ?loc' [:\\<^sub>\] LT\<^sub>0" . + thus ?thesis using ins' by simp + qed + moreover + have "conf_clinit P sh (?f'#?f#frs)" by(rule conf_clinit_Invoke[OF confc nclinit]) + ultimately + show ?thesis using s' \_pc approx meth_C m_D ins nclinit + by (fastforce dest: sees_method_fun [of _ C]) +qed +(*>*) + +lemma Invokestatic_Init_correct: + fixes \' :: jvm_state + assumes wtprog: "wf_jvm_prog\<^bsub>\\<^esub> P" + assumes meth_C: "P \ C sees M,b:Ts\T=(mxs,mxl\<^sub>0,ins,xt) in C" + assumes ins: "ins ! pc = Invokestatic D M' n" and nclinit: "M' \ clinit" + assumes wti: "P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M" + assumes \': "Some \' = exec (P, None, h, (stk,loc,C,M,pc,No_ics)#frs, sh)" + assumes approx: "P,\ \ (None, h, (stk,loc,C,M,pc,No_ics)#frs, sh)\" + assumes no_xcp: "fst (exec_step P h stk loc C M pc No_ics frs sh) = None" + assumes nDone: "\sfs. sh (fst(method P D M')) \ Some(sfs, Done)" + shows "P,\ \ \'\" +(*<*) +proof - + note split_paired_Ex [simp del] + + from wtprog obtain wfmb where wfprog: "wf_prog wfmb P" + by (simp add: wf_jvm_prog_phi_def) + + from ins meth_C approx obtain ST LT where + heap_ok: "P\ h\" and + \_pc: "\ C M!pc = Some (ST,LT)" and + stk: "P,h \ stk [:\] ST" and loc: "P,h \ loc [:\\<^sub>\] LT" and + pc: "pc < size ins" and + frames: "conf_fs P h sh \ C M (size Ts) T frs" and + confc: "conf_clinit P sh ((stk,loc,C,M,pc,No_ics)#frs)" and + pc: "pc < size ins" + by (fastforce dest: sees_method_fun) + + from ins wti \_pc obtain D' b Ts T mxs' mxl' ins' xt' where + m_D: "P \ D sees M',b: Ts\T = (mxs',mxl',ins',xt') in D'" and + b[simp]: "b = Static" + by clarsimp + + let ?f = "(stk, loc, C, M, pc, Calling D' [])" + + from m_D ins \' meth_C no_xcp nDone + have s': "\' = (None, h, ?f # frs, sh)" by(auto split: init_state.splits) + + have cls: "is_class P D'" by(rule sees_method_is_class'[OF m_D]) + + from confc have confc': "conf_clinit P sh (?f#frs)" + by(auto simp: conf_clinit_def distinct_clinit_def split: if_split_asm) + with s' \_pc approx meth_C m_D ins nclinit stk loc pc cls frames + show ?thesis by(fastforce dest: sees_method_fun [of _ C]) +qed +(*>*) + +declare list_all2_Cons2 [iff] + +lemma Return_correct: + fixes \' :: jvm_state + assumes wt_prog: "wf_jvm_prog\<^bsub>\\<^esub> P" + assumes meth: "P \ C sees M,b:Ts\T=(mxs,mxl\<^sub>0,ins,xt) in C" + assumes ins: "ins ! pc = Return" + assumes wt: "P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M" + assumes s': "Some \' = exec (P, None, h, (stk,loc,C,M,pc,ics)#frs, sh)" + assumes correct: "P,\ \ (None, h, (stk,loc,C,M,pc,ics)#frs, sh)\" + + shows "P,\ \ \'\" +(*<*) +proof - + from meth correct ins have [simp]: "ics = No_ics" by(cases ics, auto) + + from wt_prog + obtain wfmb where wf: "wf_prog wfmb P" by (simp add: wf_jvm_prog_phi_def) + + from meth ins s' + have "frs = [] \ ?thesis" by (simp add: correct_state_def) + moreover + { fix f frs' assume frs': "frs = f#frs'" + then obtain stk' loc' C' M' pc' ics' where + f: "f = (stk',loc',C',M',pc',ics')" by (cases f) + + from correct meth + obtain ST LT where + h_ok: "P \ h \" and + sh_ok: "P,h \\<^sub>s sh \" and + \_pc: "\ C M ! pc = Some (ST, LT)" and + frame: "conf_f P h sh (ST, LT) ins (stk,loc,C,M,pc,ics)" and + frames: "conf_fs P h sh \ C M (size Ts) T frs" and + confc: "conf_clinit P sh frs" + by (auto dest: sees_method_fun conf_clinit_Cons simp: correct_state_def) + + from \_pc ins wt + obtain U ST\<^sub>0 where "ST = U # ST\<^sub>0" "P \ U \ T" + by (simp add: wt_instr_def app_def) blast + with wf frame + have hd_stk: "P,h \ hd stk :\ T" by (auto simp: conf_f_def) + + from f frs' frames meth + obtain ST' LT' b' Ts'' T'' mxs' mxl\<^sub>0' ins' xt' where + \': "\ C' M' ! pc' = Some (ST', LT')" and + meth_C': "P \ C' sees M',b':Ts''\T''=(mxs',mxl\<^sub>0',ins',xt') in C'" and + frame': "conf_f P h sh (ST',LT') ins' f" and + conf_fs: "conf_fs P h sh \ C' M' (size Ts'') T'' frs'" + by clarsimp + + from f frame' obtain + stk': "P,h \ stk' [:\] ST'" and + loc': "P,h \ loc' [:\\<^sub>\] LT'" and + pc': "pc' < size ins'" + by (simp add: conf_f_def) + + { assume b[simp]: "b = NonStatic" + + from wf_NonStatic_nclinit[OF wf] meth have nclinit[simp]: "M \ clinit" by simp + + from f frs' meth ins s' + have \': + "\' = (None,h,(hd stk#(drop (1+size Ts) stk'),loc',C',M',pc'+1,ics')#frs',sh)" + (is "\' = (None,h,?f'#frs',sh)") + by simp + from f frs' confc conf_clinit_diff have confc'': "conf_clinit P sh (?f'#frs')" by blast + + with \' meth_C' f frs' frames meth + obtain D Ts' T' m D' where + ins': "ins' ! pc' = Invoke M (size Ts)" and + D: "ST' ! (size Ts) = Class D" and + meth_D: "P \ D sees M,b: Ts'\T' = m in D'" and + T': "P \ T \ T'" and + CsubD': "P \ C \\<^sup>* D'" + by(auto dest: sees_method_fun sees_method_fun[OF sees_method_idemp]) + + from wt_prog meth_C' pc' + have "P,T'',mxs',size ins',xt' \ ins'!pc',pc' :: \ C' M'" + by (rule wt_jvm_prog_impl_wt_instr) + with ins' \' D meth_D + obtain ST'' LT'' where + \_suc: "\ C' M' ! Suc pc' = Some (ST'', LT'')" and + less: "P \ (T' # drop (size Ts+1) ST', LT') \\<^sub>i (ST'', LT'')" and + suc_pc': "Suc pc' < size ins'" + by (clarsimp simp: sup_state_opt_any_Some) + + from hd_stk T' have hd_stk': "P,h \ hd stk :\ T'" .. + + have frame'': + "conf_f P h sh (ST'',LT'') ins' ?f'" + proof - + from stk' + have "P,h \ drop (1+size Ts) stk' [:\] drop (1+size Ts) ST'" .. + moreover + with hd_stk' less + have "P,h \ hd stk # drop (1+size Ts) stk' [:\] ST''" by auto + moreover + from wf loc' less have "P,h \ loc' [:\\<^sub>\] LT''" by auto + moreover note suc_pc' + moreover + from f frs' frames (* ics' = No_ics *) + have "P,h,sh \\<^sub>i (C', M', Suc pc', ics')" by auto + ultimately show ?thesis by (simp add: conf_f_def) + qed + + with \' frs' f meth h_ok sh_ok hd_stk \_suc frames confc'' meth_C' \' + have ?thesis by(fastforce dest: sees_method_fun [of _ C']) + } + moreover + { assume b[simp]: "b = Static" and nclinit[simp]: "M \ clinit" + + from f frs' meth ins s' + have \': + "\' = (None,h,(hd stk#(drop (size Ts) stk'),loc',C',M',pc'+1,ics')#frs',sh)" + (is "\' = (None,h,?f'#frs',sh)") + by simp + from f frs' confc conf_clinit_diff have confc'': "conf_clinit P sh (?f'#frs')" by blast + + with \' meth_C' f frs' frames meth + obtain D Ts' T' m where + ins': "ins' ! pc' = Invokestatic D M (size Ts)" and + meth_D: "P \ D sees M,b: Ts'\T' = m in C" and + T': "P \ T \ T'" + by(auto dest: sees_method_fun sees_method_mono2[OF _ wf sees_method_idemp]) + + from wt_prog meth_C' pc' + have "P,T'',mxs',size ins',xt' \ ins'!pc',pc' :: \ C' M'" + by (rule wt_jvm_prog_impl_wt_instr) + with ins' \' meth_D + obtain ST'' LT'' where + \_suc: "\ C' M' ! Suc pc' = Some (ST'', LT'')" and + less: "P \ (T' # drop (size Ts) ST', LT') \\<^sub>i (ST'', LT'')" and + suc_pc': "Suc pc' < size ins'" + by (clarsimp simp: sup_state_opt_any_Some) + + from hd_stk T' have hd_stk': "P,h \ hd stk :\ T'" .. + + have frame'': + "conf_f P h sh (ST'',LT'') ins' ?f'" + proof - + from stk' + have "P,h \ drop (size Ts) stk' [:\] drop (size Ts) ST'" .. + moreover + with hd_stk' less + have "P,h \ hd stk # drop (size Ts) stk' [:\] ST''" by auto + moreover + from wf loc' less have "P,h \ loc' [:\\<^sub>\] LT''" by auto + moreover note suc_pc' + moreover + from f frs' frames (* ics' = No_ics *) + have "P,h,sh \\<^sub>i (C', M', Suc pc', ics')" by auto + ultimately show ?thesis by (simp add: conf_f_def) + qed + + with \' frs' f meth h_ok sh_ok hd_stk \_suc frames confc'' meth_C' \' + have ?thesis by(fastforce dest: sees_method_fun [of _ C']) + } + moreover + { assume b[simp]: "b = Static" and clinit[simp]: "M = clinit" + + from frs' meth ins s' + have \': + "\' = (None,h,frs,sh(C\(fst(the(sh C)), Done)))" (is "\' = (None,h,frs,?sh)") + by simp + + from correct have dist': "distinct (C # clinit_classes frs)" + by(simp add: conf_clinit_def distinct_clinit_def) + + from f frs' correct have confc1: + "conf_clinit P sh ((stk, loc, C, clinit, pc, No_ics) # (stk',loc',C',M',pc',ics') # frs')" + by simp + then have ics_dist: "distinct (C # ics_classes ics')" + by(simp add: conf_clinit_def distinct_clinit_def) + + from conf_clinit_Cons_Cons[OF confc1] have dist'': "distinct (C # clinit_classes frs')" + by(simp add: conf_clinit_def distinct_clinit_def) + + from correct shconf_upd_obj[OF sh_ok _ [OF shconfD[OF sh_ok]]] + have sh'_ok: "P,h \\<^sub>s ?sh \" by(clarsimp simp: conf_clinit_def) + + have frame'': + "conf_f P h ?sh (ST',LT') ins' f" + proof - + note stk' loc' pc' f valid_ics_shupd[OF _ ics_dist] + moreover + from f frs' frames + have "P,h,sh \\<^sub>i (C', M', pc', ics')" by auto + ultimately show ?thesis by (simp add: conf_f_def2) + qed + have conf_fs': "conf_fs P h ?sh \ C' M' (length Ts'') T'' frs'" + by(rule conf_fs_shupd[OF conf_fs dist'']) + + have confc'': "conf_clinit P ?sh frs" by(rule conf_clinit_shupd[OF confc dist']) + + from \' f frs' h_ok sh'_ok conf_fs' frame'' \' stk' loc' pc' meth_C' confc'' + have ?thesis by(fastforce dest: sees_method_fun) + } + ultimately have ?thesis by (cases b) blast+ + } + ultimately + show ?thesis by (cases frs) blast+ +qed +(*>*) + +declare sup_state_opt_any_Some [iff] +declare not_Err_eq [iff] + +lemma Load_correct: +"\ wf_prog wt P; + P \ C sees M,b:Ts\T=(mxs,mxl\<^sub>0,ins,xt) in C; + ins!pc = Load idx; + P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M; + Some \' = exec (P, None, h, (stk,loc,C,M,pc,ics)#frs, sh); + P,\ \ (None, h, (stk,loc,C,M,pc,ics)#frs, sh)\ \ +\ P,\ \ \'\" +(*<*) + apply(subgoal_tac "ics = No_ics") + prefer 2 apply(cases ics, (auto)[4]) + apply clarsimp + apply (drule (1) sees_method_fun) + apply(fastforce elim!: confTs_confT_sup conf_clinit_diff) + done +(*>*) + +declare [[simproc del: list_to_set_comprehension]] + +lemma Store_correct: +"\ wf_prog wt P; + P \ C sees M,b:Ts\T=(mxs,mxl\<^sub>0,ins,xt) in C; + ins!pc = Store idx; + P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M; + Some \' = exec (P, None, h, (stk,loc,C,M,pc,ics)#frs, sh); + P,\ \ (None, h, (stk,loc,C,M,pc,ics)#frs, sh)\ \ +\ P,\ \ \'\" +(*<*) + apply(subgoal_tac "ics = No_ics") + prefer 2 apply(cases ics, (auto)[4]) + apply clarsimp + apply (drule (1) sees_method_fun) + apply (blast intro!: list_all2_update_cong conf_clinit_diff)+ + done +(*>*) + + +lemma Push_correct: +"\ wf_prog wt P; + P \ C sees M,b:Ts\T=(mxs,mxl\<^sub>0,ins,xt) in C; + ins!pc = Push v; + P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M; + Some \' = exec (P, None, h, (stk,loc,C,M,pc,ics)#frs, sh); + P,\ \ (None, h, (stk,loc,C,M,pc,ics)#frs, sh)\ \ +\ P,\ \ \'\" +(*<*) + apply(subgoal_tac "ics = No_ics") + prefer 2 apply(cases ics, (auto)[4]) + apply clarsimp + apply (drule (1) sees_method_fun) + apply (blast dest: typeof_lit_conf conf_clinit_diff)+ + done +(*>*) + + +lemma Cast_conf2: + "\ wf_prog ok P; P,h \ v :\ T; is_refT T; cast_ok P C h v; + P \ Class C \ T'; is_class P C\ + \ P,h \ v :\ T'" +(*<*) + apply (unfold cast_ok_def is_refT_def) + apply (frule Class_widen) + apply (elim exE disjE) + apply simp + apply simp + apply simp + apply (clarsimp simp: conf_def obj_ty_def) + apply (cases v) + apply (auto intro: rtrancl_trans) + done +(*>*) + + +lemma Checkcast_correct: +"\ wf_jvm_prog\<^bsub>\\<^esub> P; + P \ C sees M,b:Ts\T=(mxs,mxl\<^sub>0,ins,xt) in C; + ins!pc = Checkcast D; + P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M; + Some \' = exec (P, None, h, (stk,loc,C,M,pc,ics)#frs, sh) ; + P,\ \ (None, h, (stk,loc,C,M,pc,ics)#frs, sh)\; + fst (exec_step P h stk loc C M pc ics frs sh) = None \ +\ P,\ \ \'\" +(*<*) + apply(subgoal_tac "ics = No_ics") + prefer 2 apply(cases ics, (auto)[4]) + apply (clarsimp simp: wf_jvm_prog_phi_def split: if_split_asm) + apply (drule (1) sees_method_fun) + apply (blast intro: Cast_conf2 dest: sees_method_fun conf_clinit_diff) + done +(*>*) + +declare split_paired_All [simp del] + +lemmas widens_Cons [iff] = list_all2_Cons1 [of "widen P"] for P + +lemma Getfield_correct: + fixes \' :: jvm_state + assumes wf: "wf_prog wt P" + assumes mC: "P \ C sees M,b:Ts\T=(mxs,mxl\<^sub>0,ins,xt) in C" + assumes i: "ins!pc = Getfield F D" + assumes wt: "P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M" + assumes s': "Some \' = exec (P, None, h, (stk,loc,C,M,pc,ics)#frs, sh)" + assumes cf: "P,\ \ (None, h, (stk,loc,C,M,pc,ics)#frs, sh)\" + assumes xc: "fst (exec_step P h stk loc C M pc ics frs sh) = None" + + shows "P,\ \ \'\" +(*<*) +proof - + from mC cf i have [simp]: "ics = No_ics" by(cases ics, auto) + + from mC cf obtain ST LT where + "h\": "P \ h \" and + "sh\": "P,h \\<^sub>s sh \" and + \: "\ C M ! pc = Some (ST,LT)" and + stk: "P,h \ stk [:\] ST" and loc: "P,h \ loc [:\\<^sub>\] LT" and + pc: "pc < size ins" and + fs: "conf_fs P h sh \ C M (size Ts) T frs" and + confc: "conf_clinit P sh ((stk,loc,C,M,pc,ics)#frs)" + by (fastforce dest: sees_method_fun) + + from i \ wt obtain oT ST'' vT ST' LT' vT' where + oT: "P \ oT \ Class D" and + ST: "ST = oT # ST''" and + F: "P \ D sees F,NonStatic:vT in D" and + pc': "pc+1 < size ins" and + \': "\ C M ! (pc+1) = Some (vT'#ST', LT')" and + ST': "P \ ST'' [\] ST'" and LT': "P \ LT [\\<^sub>\] LT'" and + vT': "P \ vT \ vT'" + by fastforce + + from stk ST obtain ref stk' where + stk': "stk = ref#stk'" and + ref: "P,h \ ref :\ oT" and + ST'': "P,h \ stk' [:\] ST''" + by auto + + from stk' i mC s' xc have "ref \ Null" + by (simp add: split_beta split:if_split_asm) + moreover from ref oT have "P,h \ ref :\ Class D" .. + ultimately obtain a D' fs where + a: "ref = Addr a" and h: "h a = Some (D', fs)" and D': "P \ D' \\<^sup>* D" + by (blast dest: non_npD) + + from D' F have has_field: "P \ D' has F,NonStatic:vT in D" + by (blast intro: has_field_mono has_visible_field) + moreover from "h\" h have "P,h \ (D', fs) \" by (rule hconfD) + ultimately obtain v where v: "fs (F, D) = Some v" "P,h \ v :\ vT" + by (clarsimp simp: oconf_def has_field_def) + (blast dest: has_fields_fun) + + from conf_clinit_diff[OF confc] + have confc': "conf_clinit P sh ((v#stk',loc,C,M,pc+1,ics)#frs)" by simp + + from a h i mC s' stk' v xc has_field + have "\' = (None, h, (v#stk',loc,C,M,pc+1,ics)#frs, sh)" + by(simp add: split_beta split: if_split_asm) + moreover + from ST'' ST' have "P,h \ stk' [:\] ST'" .. + moreover + from v vT' have "P,h \ v :\ vT'" by blast + moreover + from loc LT' have "P,h \ loc [:\\<^sub>\] LT'" .. + moreover + note "h\" "sh\" mC \' pc' v fs confc' + ultimately + show "P,\ \ \' \" by fastforce +qed +(*>*) + +lemma Getstatic_nInit_correct: + fixes \' :: jvm_state + assumes wf: "wf_prog wt P" + assumes mC: "P \ C sees M,b:Ts\T=(mxs,mxl\<^sub>0,ins,xt) in C" + assumes i: "ins!pc = Getstatic C' F D" + assumes wt: "P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M" + assumes s': "Some \' = exec (P, None, h, (stk,loc,C,M,pc,ics)#frs, sh)" + assumes cf: "P,\ \ (None, h, (stk,loc,C,M,pc,ics)#frs, sh)\" + assumes xc: "fst (exec_step P h stk loc C M pc ics frs sh) = None" + assumes cs: "ics = Called [] \ (ics = No_ics \ (\sfs. sh (fst(field P D F)) = Some(sfs, Done)))" + + shows "P,\ \ \'\" +(*<*) +proof - + from mC cf obtain ST LT where + "h\": "P \ h \" and + "sh\": "P,h \\<^sub>s sh \" and + \: "\ C M ! pc = Some (ST,LT)" and + stk: "P,h \ stk [:\] ST" and loc: "P,h \ loc [:\\<^sub>\] LT" and + pc: "pc < size ins" and + fs: "conf_fs P h sh \ C M (size Ts) T frs" and + confc: "conf_clinit P sh ((stk,loc,C,M,pc,ics)#frs)" and + vics: "P,h,sh \\<^sub>i (C,M,pc,ics)" + by (fastforce dest: sees_method_fun) + + from i \ wt cs obtain vT ST' LT' vT' where + F: "P \ C' sees F,Static:vT in D" and + pc': "pc+1 < size ins" and + \': "\ C M ! (pc+1) = Some (vT'#ST', LT')" and + ST': "P \ ST [\] ST'" and LT': "P \ LT [\\<^sub>\] LT'" and + vT': "P \ vT \ vT'" + by fastforce + + with mC i vics obtain sobj where + cc': "ics = Called [] \ Called_context P D (ins!pc) \ sh D = Some sobj" + by(fastforce dest: has_visible_field) + + from field_def2[OF sees_field_idemp[OF F]] have D[simp]: "fst(field P D F) = D" by simp + from cs cc' obtain sfs i where shD: "sh D = Some(sfs,i)" by(cases sobj, auto) + + note has_field_idemp[OF has_visible_field[OF F]] + moreover from "sh\" shD have "P,h,D \\<^sub>s sfs \" by (rule shconfD) + ultimately obtain v where v: "sfs F = Some v" "P,h \ v :\ vT" + by (clarsimp simp: soconf_def has_field_def) blast + + from i mC s' v xc F cs cc' shD + have "\' = (None, h, (v#stk,loc,C,M,pc+1,No_ics)#frs, sh)" + by(fastforce simp: split_beta split: if_split_asm init_call_status.splits) + moreover + from stk ST' have "P,h \ stk [:\] ST'" .. + moreover + from v vT' have "P,h \ v :\ vT'" by blast + moreover + from loc LT' have "P,h \ loc [:\\<^sub>\] LT'" .. + moreover + have "conf_clinit P sh ((v#stk,loc,C,M,pc+1,No_ics)#frs)" by(rule conf_clinit_diff'[OF confc]) + moreover + note "h\" "sh\" mC \' pc' v fs + ultimately + show "P,\ \ \' \" by fastforce +qed +(*>*) + +lemma Getstatic_Init_correct: + fixes \' :: jvm_state + assumes wf: "wf_prog wt P" + assumes mC: "P \ C sees M,b:Ts\T=(mxs,mxl\<^sub>0,ins,xt) in C" + assumes i: "ins!pc = Getstatic C' F D" + assumes wt: "P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M" + assumes s': "Some \' = exec (P, None, h, (stk,loc,C,M,pc,No_ics)#frs, sh)" + assumes cf: "P,\ \ (None, h, (stk,loc,C,M,pc,No_ics)#frs, sh)\" + assumes xc: "fst (exec_step P h stk loc C M pc No_ics frs sh) = None" + assumes nDone: "\sfs. sh (fst(field P D F)) \ Some(sfs, Done)" + + shows "P,\ \ \'\" +(*<*) +proof - + from mC cf obtain ST LT where + "h\": "P \ h \" and + "sh\": "P,h \\<^sub>s sh \" and + \: "\ C M ! pc = Some (ST,LT)" and + stk: "P,h \ stk [:\] ST" and loc: "P,h \ loc [:\\<^sub>\] LT" and + pc: "pc < size ins" and + fs: "conf_fs P h sh \ C M (size Ts) T frs" and + confc: "conf_clinit P sh ((stk,loc,C,M,pc,No_ics)#frs)" + by (fastforce dest: sees_method_fun) + + from i \ wt nDone obtain vT where + F: "P \ C' sees F,Static:vT in D" + by fastforce + then have has_field: "P \ C' has F,Static:vT in D" by(rule has_visible_field) + + from field_def2[OF sees_field_idemp[OF F]] has_field_is_class'[OF has_field] obtain + D[simp]: "fst(field P D F) = D" and + cls: "is_class P D" by simp + + from i mC s' xc F nDone + have "\' = (None, h, (stk,loc,C,M,pc,Calling D [])#frs, sh)" + by(auto simp: split_beta split: if_split_asm init_state.splits) + moreover + from confc have "conf_clinit P sh ((stk,loc,C,M,pc,Calling D [])#frs)" + by(auto simp: conf_clinit_def distinct_clinit_def split: if_split_asm) + moreover + note loc stk "h\" "sh\" mC \ pc fs i has_field cls + ultimately + show "P,\ \ \' \" by fastforce +qed +(*>*) + +lemma Putfield_correct: + fixes \' :: jvm_state + assumes wf: "wf_prog wt P" + assumes mC: "P \ C sees M,b:Ts\T=(mxs,mxl\<^sub>0,ins,xt) in C" + assumes i: "ins!pc = Putfield F D" + assumes wt: "P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M" + assumes s': "Some \' = exec (P, None, h, (stk,loc,C,M,pc,ics)#frs, sh)" + assumes cf: "P,\ \ (None, h, (stk,loc,C,M,pc,ics)#frs, sh)\" + assumes xc: "fst (exec_step P h stk loc C M pc ics frs sh) = None" + + shows "P,\ \ \'\" +(*<*) +proof - + from mC cf i have [simp]: "ics = No_ics" by(cases ics, auto) + + from mC cf obtain ST LT where + "h\": "P \ h \" and + "sh\": "P,h \\<^sub>s sh \" and + \: "\ C M ! pc = Some (ST,LT)" and + stk: "P,h \ stk [:\] ST" and loc: "P,h \ loc [:\\<^sub>\] LT" and + pc: "pc < size ins" and + fs: "conf_fs P h sh \ C M (size Ts) T frs" and + confc: "conf_clinit P sh ((stk,loc,C,M,pc,ics) # frs)" + by (fastforce dest: sees_method_fun) + + from i \ wt obtain vT vT' oT ST'' ST' LT' where + ST: "ST = vT # oT # ST''" and + field: "P \ D sees F,NonStatic:vT' in D" and + oT: "P \ oT \ Class D" and vT: "P \ vT \ vT'" and + pc': "pc+1 < size ins" and + \': "\ C M!(pc+1) = Some (ST',LT')" and + ST': "P \ ST'' [\] ST'" and LT': "P \ LT [\\<^sub>\] LT'" + by clarsimp + + from stk ST obtain v ref stk' where + stk': "stk = v#ref#stk'" and + v: "P,h \ v :\ vT" and + ref: "P,h \ ref :\ oT" and + ST'': "P,h \ stk' [:\] ST''" + by auto + + from stk' i mC s' xc have "ref \ Null" by (auto simp: split_beta) + moreover from ref oT have "P,h \ ref :\ Class D" .. + ultimately obtain a D' fs where + a: "ref = Addr a" and h: "h a = Some (D', fs)" and D': "P \ D' \\<^sup>* D" + by (blast dest: non_npD) + + from v vT have vT': "P,h \ v :\ vT'" .. + + from field D' have has_field: "P \ D' has F,NonStatic:vT' in D" + by (blast intro: has_field_mono has_visible_field) + + let ?h' = "h(a\(D', fs((F, D)\v)))" and ?f' = "(stk',loc,C,M,pc+1,ics)" + from h have hext: "h \ ?h'" by (rule hext_upd_obj) + + have "sh\'": "P,?h' \\<^sub>s sh \" by(rule shconf_hupd_obj[OF "sh\" h]) + + from a h i mC s' stk' has_field field + have "\' = (None, ?h', ?f'#frs, sh)" by(simp split: if_split_asm) + moreover + from "h\" h have "P,h \ (D',fs)\" by (rule hconfD) + with has_field vT' have "P,h \ (D',fs((F, D)\v))\" .. + with "h\" h have "P \ ?h'\" by (rule hconf_upd_obj) + moreover + from ST'' ST' have "P,h \ stk' [:\] ST'" .. + from this hext have "P,?h' \ stk' [:\] ST'" by (rule confs_hext) + moreover + from loc LT' have "P,h \ loc [:\\<^sub>\] LT'" .. + from this hext have "P,?h' \ loc [:\\<^sub>\] LT'" by (rule confTs_hext) + moreover + from fs hext + have "conf_fs P ?h' sh \ C M (size Ts) T frs" by (rule conf_fs_hext) + moreover + have "conf_clinit P sh (?f' # frs)" by(rule conf_clinit_diff[OF confc]) + moreover + note mC \' pc' "sh\'" + ultimately + show "P,\ \ \' \" by fastforce +qed +(*>*) + +lemma Putstatic_nInit_correct: + fixes \' :: jvm_state + assumes wf: "wf_prog wt P" + assumes mC: "P \ C sees M,b:Ts\T=(mxs,mxl\<^sub>0,ins,xt) in C" + assumes i: "ins!pc = Putstatic C' F D" + assumes wt: "P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M" + assumes s': "Some \' = exec (P, None, h, (stk,loc,C,M,pc,ics)#frs, sh)" + assumes cf: "P,\ \ (None, h, (stk,loc,C,M,pc,ics)#frs, sh)\" + assumes xc: "fst (exec_step P h stk loc C M pc ics frs sh) = None" + assumes cs: "ics = Called [] \ (ics = No_ics \ (\sfs. sh (fst(field P D F)) = Some(sfs, Done)))" + + shows "P,\ \ \'\" +(*<*) +proof - + from mC cf obtain ST LT where + "h\": "P \ h \" and + "sh\": "P,h \\<^sub>s sh \" and + \: "\ C M ! pc = Some (ST,LT)" and + stk: "P,h \ stk [:\] ST" and loc: "P,h \ loc [:\\<^sub>\] LT" and + pc: "pc < size ins" and + fs: "conf_fs P h sh \ C M (size Ts) T frs" and + confc: "conf_clinit P sh ((stk,loc,C,M,pc,ics)#frs)" and + vics: "P,h,sh \\<^sub>i (C,M,pc,ics)" + by (fastforce dest: sees_method_fun) + + from i \ wt cs obtain vT vT' ST'' ST' LT' where + ST: "ST = vT # ST''" and + F: "P \ C' sees F,Static:vT' in D" and + vT: "P \ vT \ vT'" and + pc': "pc+1 < size ins" and + \': "\ C M ! (pc+1) = Some (ST', LT')" and + ST': "P \ ST'' [\] ST'" and LT': "P \ LT [\\<^sub>\] LT'" + by fastforce + + from stk ST obtain v stk' where + stk': "stk = v#stk'" and + v: "P,h \ v :\ vT" and + ST'': "P,h \ stk' [:\] ST''" + by auto + + from v vT have vT': "P,h \ v :\ vT'" .. + + with mC i vics obtain sobj where + cc': "ics = Called [] \ Called_context P D (ins!pc) \ sh D = Some sobj" + by(fastforce dest: has_visible_field) + + from field_def2[OF sees_field_idemp[OF F]] have D[simp]: "fst(field P D F) = D" by simp + from cs cc' obtain sfs i where shD: "sh D = Some(sfs,i)" by(cases sobj, auto) + + let ?sh' = "sh(D\(sfs(F\v),i))" and ?f' = "(stk',loc,C,M,pc+1,No_ics)" + + have m_D: "P \ D has F,Static:vT' in D" by (rule has_field_idemp[OF has_visible_field[OF F]]) + from "sh\" shD have sfs: "P,h,D \\<^sub>s sfs \" by (rule shconfD) + + have "sh'\": "P,h \\<^sub>s ?sh' \" by (rule shconf_upd_obj[OF "sh\" soconf_fupd[OF m_D vT' sfs]]) + + from i mC s' v xc F cs cc' shD stk' + have "\' = (None, h, (stk',loc,C,M,pc+1,No_ics)#frs, ?sh')" + by(fastforce simp: split_beta split: if_split_asm init_call_status.splits) + moreover + from ST'' ST' have "P,h \ stk' [:\] ST'" .. + moreover + from loc LT' have "P,h \ loc [:\\<^sub>\] LT'" .. + moreover + have "conf_fs P h ?sh' \ C M (size Ts) T frs" by (rule conf_fs_shupd'[OF fs shD]) + moreover + have "conf_clinit P ?sh' ((stk',loc,C,M,pc+1,No_ics)#frs)" + by(rule conf_clinit_diff'[OF conf_clinit_shupd'[OF confc shD]]) + moreover + note "h\" "sh'\" mC \' pc' v vT' + ultimately + show "P,\ \ \' \" by fastforce +qed +(*>*) + +lemma Putstatic_Init_correct: + fixes \' :: jvm_state + assumes wf: "wf_prog wt P" + assumes mC: "P \ C sees M,b:Ts\T=(mxs,mxl\<^sub>0,ins,xt) in C" + assumes i: "ins!pc = Putstatic C' F D" + assumes wt: "P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M" + assumes s': "Some \' = exec (P, None, h, (stk,loc,C,M,pc,No_ics)#frs, sh)" + assumes cf: "P,\ \ (None, h, (stk,loc,C,M,pc,No_ics)#frs, sh)\" + assumes xc: "fst (exec_step P h stk loc C M pc No_ics frs sh) = None" + assumes nDone: "\sfs. sh (fst(field P D F)) \ Some(sfs, Done)" + + shows "P,\ \ \'\" +(*<*) +proof - + from mC cf obtain ST LT where + "h\": "P \ h \" and + "sh\": "P,h \\<^sub>s sh \" and + \: "\ C M ! pc = Some (ST,LT)" and + stk: "P,h \ stk [:\] ST" and loc: "P,h \ loc [:\\<^sub>\] LT" and + pc: "pc < size ins" and + fs: "conf_fs P h sh \ C M (size Ts) T frs" and + confc: "conf_clinit P sh ((stk,loc,C,M,pc,No_ics)#frs)" + by (fastforce dest: sees_method_fun) + + from i \ wt nDone obtain vT where + F: "P \ C' sees F,Static:vT in D" + by fastforce + then have has_field: "P \ C' has F,Static:vT in D" by(rule has_visible_field) + + from field_def2[OF sees_field_idemp[OF F]] has_field_is_class'[OF has_field] obtain + D[simp]: "fst(field P D F) = D" and + cls: "is_class P D" by simp + + from i mC s' xc F nDone + have "\' = (None, h, (stk,loc,C,M,pc,Calling D [])#frs, sh)" + by(auto simp: split_beta split: if_split_asm init_state.splits) + moreover + from confc have "conf_clinit P sh ((stk,loc,C,M,pc,Calling D [])#frs)" + by(auto simp: conf_clinit_def distinct_clinit_def split: if_split_asm) + moreover + note loc stk "h\" "sh\" mC \ pc fs i has_field cls + ultimately + show "P,\ \ \' \" by fastforce +qed +(*>*) + +(* FIXME: move *) +lemma oconf_blank2 [intro, simp]: + "\is_class P C; wf_prog wt P\ \ P,h \ blank P C \" +(*<*) + by (fastforce simp: oconf_blank dest: wf_Fields_Ex) +(*>*) + +lemma obj_ty_blank [iff]: "obj_ty (blank P C) = Class C" + by (simp add: blank_def) + +lemma New_nInit_correct: + fixes \' :: jvm_state + assumes wf: "wf_prog wt P" + assumes meth: "P \ C sees M,b:Ts\T=(mxs,mxl\<^sub>0,ins,xt) in C" + assumes ins: "ins!pc = New X" + assumes wt: "P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M" + assumes exec: "Some \' = exec (P, None, h, (stk,loc,C,M,pc,ics)#frs, sh)" + assumes conf: "P,\ \ (None, h, (stk,loc,C,M,pc,ics)#frs, sh)\" + assumes no_x: "fst (exec_step P h stk loc C M pc ics frs sh) = None" + assumes cs: "ics = Called [] \ (ics = No_ics \ (\sfs. sh X = Some(sfs, Done)))" + shows "P,\ \ \'\" +(*<*) +proof - + from ins conf meth + obtain ST LT where + heap_ok: "P\ h\" and + sheap_ok: "P,h \\<^sub>s sh \" and + \_pc: "\ C M!pc = Some (ST,LT)" and + frame: "conf_f P h sh (ST,LT) ins (stk,loc,C,M,pc,ics)" and + frames: "conf_fs P h sh \ C M (size Ts) T frs" and + confc: "conf_clinit P sh ((stk,loc,C,M,pc,ics) # frs)" + by (auto dest: sees_method_fun) + + from \_pc ins wt + obtain ST' LT' where + is_class_X: "is_class P X" and + mxs: "size ST < mxs" and + suc_pc: "pc+1 < size ins" and + \_suc: "\ C M!(pc+1) = Some (ST', LT')" and + less: "P \ (Class X # ST, LT) \\<^sub>i (ST', LT')" + by auto + + from ins no_x cs meth obtain oref where new_Addr: "new_Addr h = Some oref" by auto + hence h: "h oref = None" by (rule new_Addr_SomeD) + + with exec ins meth new_Addr cs have \': + "\' = (None, h(oref \ blank P X), (Addr oref#stk,loc,C,M,pc+1,No_ics)#frs, sh)" + (is "\' = (None, ?h', ?f # frs, sh)") + by auto + moreover + from wf h heap_ok is_class_X have h': "P \ ?h' \" + by (auto intro: hconf_new) + moreover + from h frame less suc_pc wf + have "conf_f P ?h' sh (ST', LT') ins ?f" + apply (clarsimp simp: fun_upd_apply conf_def blank_def split_beta) + apply (auto intro: confs_hext confTs_hext) + done + moreover + from h have "h \ ?h'" by simp + with frames have "conf_fs P ?h' sh \ C M (size Ts) T frs" by (rule conf_fs_hext) + moreover + have "P,?h' \\<^sub>s sh \" by(rule shconf_hnew[OF sheap_ok h]) + moreover + have "conf_clinit P sh (?f # frs)" by(rule conf_clinit_diff'[OF confc]) + ultimately + show ?thesis using meth \_suc by fastforce +qed +(*>*) + +lemma New_Init_correct: + fixes \' :: jvm_state + assumes wf: "wf_prog wt P" + assumes meth: "P \ C sees M,b:Ts\T=(mxs,mxl\<^sub>0,ins,xt) in C" + assumes ins: "ins!pc = New X" + assumes wt: "P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M" + assumes exec: "Some \' = exec (P, None, h, (stk,loc,C,M,pc,No_ics)#frs, sh)" + assumes conf: "P,\ \ (None, h, (stk,loc,C,M,pc,No_ics)#frs, sh)\" + assumes no_x: "fst (exec_step P h stk loc C M pc No_ics frs sh) = None" + assumes nDone: "\sfs. sh X \ Some(sfs, Done)" + shows "P,\ \ \'\" +(*<*) +proof - + from ins conf meth + obtain ST LT where + heap_ok: "P\ h\" and + sheap_ok: "P,h \\<^sub>s sh \" and + \_pc: "\ C M!pc = Some (ST,LT)" and + frame: "conf_f P h sh (ST,LT) ins (stk,loc,C,M,pc,No_ics)" and + frames: "conf_fs P h sh \ C M (size Ts) T frs" and + confc: "conf_clinit P sh ((stk,loc,C,M,pc,No_ics) # frs)" + by (auto dest: sees_method_fun) + + from \_pc ins wt + obtain ST' LT' where + is_class_X: "is_class P X" and + mxs: "size ST < mxs" and + suc_pc: "pc+1 < size ins" and + \_suc: "\ C M!(pc+1) = Some (ST', LT')" and + less: "P \ (Class X # ST, LT) \\<^sub>i (ST', LT')" + by auto + + with exec ins meth nDone have \': + "\' = (None, h, (stk,loc,C,M,pc,Calling X [])#frs, sh)" + (is "\' = (None, h, ?f # frs, sh)") + by(auto split: init_state.splits) + moreover + from meth frame is_class_X ins + have "conf_f P h sh (ST, LT) ins ?f" by auto + moreover note heap_ok sheap_ok frames + moreover + from confc have "conf_clinit P sh (?f # frs)" + by(auto simp: conf_clinit_def distinct_clinit_def split: if_split_asm) + ultimately + show ?thesis using meth \_pc by fastforce +qed +(*>*) + + +lemma Goto_correct: +"\ wf_prog wt P; + P \ C sees M,b:Ts\T=(mxs,mxl\<^sub>0,ins,xt) in C; + ins ! pc = Goto branch; + P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M; + Some \' = exec (P, None, h, (stk,loc,C,M,pc,ics)#frs, sh) ; + P,\ \ (None, h, (stk,loc,C,M,pc,ics)#frs, sh)\ \ +\ P,\ \ \'\" +(*<*) +apply(subgoal_tac "ics = No_ics") + prefer 2 apply(cases ics, (auto)[4]) +apply clarsimp +apply (drule (1) sees_method_fun) +apply (fastforce elim!: conf_clinit_diff) +done +(*>*) + + +lemma IfFalse_correct: +"\ wf_prog wt P; + P \ C sees M,b:Ts\T=(mxs,mxl\<^sub>0,ins,xt) in C; + ins ! pc = IfFalse branch; + P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M; + Some \' = exec (P, None, h, (stk,loc,C,M,pc,ics)#frs, sh) ; + P,\ \ (None, h, (stk,loc,C,M,pc,ics)#frs, sh)\ \ +\ P,\ \ \'\" +(*<*) +apply(subgoal_tac "ics = No_ics") + prefer 2 apply(cases ics, (auto)[4]) +apply clarsimp +apply (drule (1) sees_method_fun) +apply (fastforce elim!: conf_clinit_diff) +done +(*>*) + +lemma CmpEq_correct: +"\ wf_prog wt P; + P \ C sees M,b:Ts\T=(mxs,mxl\<^sub>0,ins,xt) in C; + ins ! pc = CmpEq; + P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M; + Some \' = exec (P, None, h, (stk,loc,C,M,pc,ics)#frs, sh) ; + P,\ \ (None, h, (stk,loc,C,M,pc,ics)#frs, sh)\ \ +\ P,\ \ \'\" +(*<*) +apply(subgoal_tac "ics = No_ics") + prefer 2 apply(cases ics, (auto)[4]) +apply clarsimp +apply (drule (1) sees_method_fun) +apply (fastforce elim!: conf_clinit_diff) +done +(*>*) + +lemma Pop_correct: +"\ wf_prog wt P; + P \ C sees M,b:Ts\T=(mxs,mxl\<^sub>0,ins,xt) in C; + ins ! pc = Pop; + P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M; + Some \' = exec (P, None, h, (stk,loc,C,M,pc,ics)#frs, sh) ; + P,\ \ (None, h, (stk,loc,C,M,pc,ics)#frs, sh)\ \ +\ P,\ \ \'\" +(*<*) +apply(subgoal_tac "ics = No_ics") + prefer 2 apply(cases ics, (auto)[4]) +apply clarsimp +apply (drule (1) sees_method_fun) +apply (fastforce elim!: conf_clinit_diff) +done +(*>*) + + +lemma IAdd_correct: +"\ wf_prog wt P; + P \ C sees M,b:Ts\T=(mxs,mxl\<^sub>0,ins,xt) in C; + ins ! pc = IAdd; + P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M; + Some \' = exec (P, None, h, (stk,loc,C,M,pc,ics)#frs, sh) ; + P,\ \ (None, h, (stk,loc,C,M,pc,ics)#frs, sh)\ \ +\ P,\ \ \'\" +(*<*) +apply(subgoal_tac "ics = No_ics") + prefer 2 apply(cases ics, (auto)[4]) +apply (clarsimp simp: conf_def) +apply (drule (1) sees_method_fun) +apply (fastforce elim!: conf_clinit_diff) +done +(*>*) + + +lemma Throw_correct: +"\ wf_prog wt P; + P \ C sees M,b:Ts\T=(mxs,mxl\<^sub>0,ins,xt) in C; + ins ! pc = Throw; + Some \' = exec (P, None, h, (stk,loc,C,M,pc,ics)#frs, sh) ; + P,\ \ (None, h, (stk,loc,C,M,pc,ics)#frs, sh)\; + fst (exec_step P h stk loc C M pc ics frs sh) = None \ +\ P,\ \ \'\" +apply(subgoal_tac "ics = No_ics") + prefer 2 apply(cases ics, (auto)[4]) +apply simp +done + +text \ + The next theorem collects the results of the sections above, + i.e.~exception handling, initialization procedure steps, and + the execution step for each instruction. It states type safety + for single step execution: in welltyped programs, a conforming + state is transformed into another conforming state when one + step of execution is performed. +\ +lemma step_correct: +fixes \' :: jvm_state +assumes wtp: "wf_jvm_prog\<^bsub>\\<^esub> P" + and meth: "P \ C sees M,b:Ts\T=(mxs,mxl\<^sub>0,ins,xt) in C" + and exec: "Some \' = exec (P, None, h, (stk,loc,C,M,pc,ics)#frs, sh)" + and conf: "P,\ \ (None, h, (stk,loc,C,M,pc,ics)#frs, sh)\" +shows "P,\ \ \'\" +(*<*) +proof - + from assms have pc: "pc < length ins" by(auto dest: sees_method_fun) + with wt_jvm_prog_impl_wt_instr[OF wtp meth] have wt: "P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M" + by simp + + from conf obtain ST LT where \: "\ C M ! pc = Some(ST,LT)" by clarsimp + + show ?thesis + proof(cases "fst (exec_step P h stk loc C M pc ics frs sh)") + case Some show ?thesis by(rule xcpt_correct[OF wtp meth wt Some exec conf]) + next + case None + from wt_jvm_progD[OF wtp] obtain wf_md where wf: "wf_prog wf_md P" by clarify + + { assume [simp]: "ics = No_ics" + + from exec conf None obtain + exec': "Some \' = exec (P, None, h, (stk,loc,C,M,pc,No_ics)#frs, sh)" + and conf': "P,\ \ (None, h, (stk,loc,C,M,pc,No_ics)#frs, sh)\" + and None': "fst (exec_step P h stk loc C M pc No_ics frs sh) = None" by simp + + have ?thesis + proof(cases "ins!pc") + case Load from Load_correct[OF wf meth this wt exec conf] show ?thesis by simp + next + case Store from Store_correct[OF wf meth this wt exec conf] show ?thesis by simp + next + case Push from Push_correct[OF wf meth this wt exec conf] show ?thesis by simp + next + case (New C) show ?thesis + proof(cases "\sfs. sh C = Some(sfs, Done)") + case True + with New_nInit_correct[OF wf meth New wt exec conf None] show ?thesis by simp + next + case False + with New_Init_correct[OF wf meth New wt exec' conf' None'] show ?thesis by simp + qed + next + case Getfield from Getfield_correct[OF wf meth this wt exec conf None] + show ?thesis by simp + next + case (Getstatic C F D) show ?thesis + proof(cases "\sfs. sh (fst (field P D F)) = Some(sfs, Done)") + case True + with Getstatic_nInit_correct[OF wf meth Getstatic wt exec conf None] show ?thesis by simp + next + case False + with Getstatic_Init_correct[OF wf meth Getstatic wt exec' conf' None'] + show ?thesis by simp + qed + next + case Putfield from Putfield_correct[OF wf meth this wt exec conf None] + show ?thesis by simp + next + case (Putstatic C F D) show ?thesis + proof(cases "\sfs. sh (fst (field P D F)) = Some(sfs, Done)") + case True + with Putstatic_nInit_correct[OF wf meth Putstatic wt exec conf None] show ?thesis by simp + next + case False + with Putstatic_Init_correct[OF wf meth Putstatic wt exec' conf' None'] + show ?thesis by simp + qed + next + case Checkcast from Checkcast_correct[OF wtp meth this wt exec conf None] + show ?thesis by simp + next + case Invoke with Invoke_correct[OF wtp meth this wt exec conf None] show ?thesis by simp + next + case (Invokestatic C M n) + from wf_jvm_prog_nclinit[OF wtp meth wt pc \ this] have ncl: "M \ clinit" by simp + show ?thesis + proof(cases "\sfs. sh (fst (method P C M)) = Some(sfs, Done)") + case True + with Invokestatic_nInit_correct[OF wtp meth Invokestatic ncl wt exec conf None] + show ?thesis by simp + next + case False + with Invokestatic_Init_correct[OF wtp meth Invokestatic ncl wt exec' conf' None'] + show ?thesis by simp + qed + next + case Return with Return_correct[OF wtp meth this wt exec conf] show ?thesis by simp + next + case Pop with Pop_correct[OF wf meth this wt exec conf] show ?thesis by simp + next + case IAdd with IAdd_correct[OF wf meth this wt exec conf] show ?thesis by simp + next + case Goto with Goto_correct[OF wf meth this wt exec conf] show ?thesis by simp + next + case CmpEq with CmpEq_correct[OF wf meth this wt exec conf] show ?thesis by simp + next + case IfFalse with IfFalse_correct[OF wf meth this wt exec conf] show ?thesis by simp + next + case Throw with Throw_correct[OF wf meth this exec conf None] show ?thesis by simp + qed + } + moreover + { fix Cs assume [simp]: "ics = Called Cs" + have ?thesis + proof(cases Cs) + case [simp]: Nil + from conf meth obtain C1 where "Called_context P C1 (ins ! pc)" + by(clarsimp simp: conf_f_def2 intro!: Called_context_Called_set) + then have "ins!pc \ Called_set" by(rule Called_context_Called_set) + then show ?thesis + proof(cases "ins!pc") + case (New C) + from New_nInit_correct[OF wf meth this wt exec conf None] show ?thesis by simp + next + case (Getstatic C F D) + from Getstatic_nInit_correct[OF wf meth this wt exec conf None] show ?thesis by simp + next + case (Putstatic C F D) + from Putstatic_nInit_correct[OF wf meth this wt exec conf None] show ?thesis by simp + next + case (Invokestatic C M n) + from wf_jvm_prog_nclinit[OF wtp meth wt pc \ this] have ncl: "M \ clinit" by simp + with Invokestatic_nInit_correct[OF wtp meth Invokestatic ncl wt exec conf None] + show ?thesis by simp + qed(simp_all) + next + case (Cons C' Cs') with Called_correct[OF wtp meth exec conf None] show ?thesis by simp + qed + } + moreover + { fix C' Cs assume [simp]: "ics = Calling C' Cs" + with Calling_correct[OF wtp meth exec conf None] have ?thesis by simp + } + moreover + { fix Cs a assume [simp]: "ics = Throwing Cs a" + have ?thesis + proof(cases Cs) + case Nil with exec None show ?thesis by simp + next + case (Cons C' Cs') + with Throwing_correct[OF wtp meth exec conf None] show ?thesis by simp + qed + } + ultimately show ?thesis by(cases ics) auto + qed +qed +(*>*) + +subsection \ Main \ + +lemma correct_state_impl_Some_method: + "P,\ \ (None, h, (stk,loc,C,M,pc,ics)#frs, sh)\ + \ \b m Ts T. P \ C sees M,b:Ts\T = m in C" + by fastforce + +lemma BV_correct_1 [rule_format]: +"\\. \ wf_jvm_prog\<^bsub>\\<^esub> P; P,\ \ \\\ \ P \ \ -jvm\\<^sub>1 \' \ P,\ \ \'\" +(*<*) +apply (simp only: split_tupled_all exec_1_iff) +apply (rename_tac xp h frs sh) +apply (case_tac xp) + apply (case_tac frs) + apply simp + apply (simp only: split_tupled_all) + apply hypsubst + apply (frule correct_state_impl_Some_method) + apply clarify + apply (rule step_correct) + apply assumption+ + apply (rule sym) + apply assumption+ +apply (case_tac frs) + apply simp_all +done +(*>*) + + +theorem progress: + "\ xp=None; frs\[] \ \ \\'. P \ (xp,h,frs,sh) -jvm\\<^sub>1 \'" + by (clarsimp simp: exec_1_iff neq_Nil_conv split_beta + simp del: split_paired_Ex) + +lemma progress_conform: + "\wf_jvm_prog\<^bsub>\\<^esub> P; P,\ \ (xp,h,frs,sh)\; xp=None; frs\[]\ + \ \\'. P \ (xp,h,frs,sh) -jvm\\<^sub>1 \' \ P,\ \ \'\" +(*<*) +apply (drule progress) + apply assumption +apply (fast intro: BV_correct_1) +done +(*>*) + +theorem BV_correct [rule_format]: +"\ wf_jvm_prog\<^bsub>\\<^esub> P; P \ \ -jvm\ \' \ \ P,\ \ \\ \ P,\ \ \'\" +(*<*) +apply (simp only: exec_all_def1) +apply (erule rtrancl_induct) + apply simp +apply clarify +apply (erule (2) BV_correct_1) +done +(*>*) + +lemma hconf_start: + assumes wf: "wf_prog wf_mb P" + shows "P \ (start_heap P) \" +(*<*) + apply (unfold hconf_def) + apply (simp add: preallocated_start) + apply (clarify) + apply (drule sym) + apply (unfold start_heap_def) + apply (insert wf) + apply (auto simp: fun_upd_apply is_class_xcpt split: if_split_asm) + done +(*>*) + +lemma shconf_start: + "\ is_class P Start \ P,start_heap P \\<^sub>s start_sheap \" +(*<*) + apply (unfold shconf_def) + apply (clarsimp simp: preallocated_start fun_upd_apply soconf_def has_field_is_class) + done +(*>*) + +lemma BV_correct_initial: + shows "\ wf_jvm_prog\<^bsub>\\<^esub> P; \is_class P Start; + P \ C sees M,Static:[]\Void = m in C; M \ clinit; + \' Start start_m = start_\\<^sub>m \ + \ start_prog P C M,\' \ start_state P \" +(*<*) + apply(subgoal_tac "is_class P Object") + prefer 2 apply(simp add: wf_jvm_prog_phi_def) + apply(subgoal_tac "\Mm. P \ Object sees_methods Mm") + prefer 2 apply(fastforce simp: is_class_def dest: sees_methods_Object) + apply (cases m) + apply (unfold start_state_def) + apply (unfold correct_state_def) + apply (simp del: defs1) + apply (rule conjI) + apply (simp add: wf_jvm_prog_phi_def class_add_hconf_wf[OF _ hconf_start] start_heap_nStart) + apply (rule conjI) + using start_prog_start_shconf apply(simp add: wf_jvm_prog_phi_def) + apply (rule conjI) + apply(simp add: conf_clinit_def distinct_clinit_def) + apply (drule wt_jvm_prog_impl_wt_start, assumption+) + apply (unfold conf_f_def wt_start_def) + apply (fastforce dest: start_prog_Start_sees_start_method) + done + +declare [[simproc add: list_to_set_comprehension]] +(*>*) + +theorem typesafe: + assumes welltyped: "wf_jvm_prog\<^bsub>\\<^esub> P" + assumes nstart: "\ is_class P Start" + assumes main_method: "P \ C sees M,Static:[]\Void = m in C" + assumes nclinit: "M \ clinit" + assumes \: "\C. C \ Start \ \' C = \ C" + assumes \': "\' Start start_m = start_\\<^sub>m" "\' Start clinit = start_\\<^sub>m" + assumes Obj_start_m: + "(\b' Ts' T' m' D'. P \ Object sees start_m, b' : Ts'\T' = m' in D' + \ b' = Static \ Ts' = [] \ T' = Void)" + shows "start_prog P C M \ start_state P -jvm\ \ \ start_prog P C M,\' \ \ \" +(*<*) +proof - + from welltyped nstart main_method nclinit \'(1) + have "start_prog P C M,\' \ start_state P \" by (rule BV_correct_initial) + moreover + assume "start_prog P C M \ start_state P -jvm\ \" + moreover + from start_prog_wf_jvm_prog_phi[OF welltyped nstart main_method nclinit \ \' Obj_start_m] + have "wf_jvm_prog\<^bsub>\'\<^esub>(start_prog P C M)" by simp + ultimately + show "start_prog P C M,\' \ \ \" using welltyped by - (rule BV_correct) +qed +(*>*) + +end diff --git a/thys/JinjaDCI/BV/ClassAdd.thy b/thys/JinjaDCI/BV/ClassAdd.thy new file mode 100644 --- /dev/null +++ b/thys/JinjaDCI/BV/ClassAdd.thy @@ -0,0 +1,685 @@ +(* Title: JinjaDCI/BV/ClassAdd.thy + Author: Susannah Mansky + 2019-20, UIUC +*) + +section \ Property preservation under @{text "class_add"} \ + +theory ClassAdd +imports BVConform +begin + + +lemma err_mono: "A \ B \ err A \ err B" + by(unfold err_def) auto + +lemma opt_mono: "A \ B \ opt A \ opt B" + by(unfold opt_def) auto + +lemma list_mono: +assumes "A \ B" shows "list n A \ list n B" +proof(rule) + fix xs assume "xs \ list n A" + then obtain size: "size xs = n" and inA: "set xs \ A" by simp + with assms have "set xs \ B" by simp + with size show "xs \ list n B" by(clarsimp intro!: listI) +qed + +(****************************************************************) + +\ \ adding a class in the simplest way \ +abbreviation class_add :: "jvm_prog \ jvm_method cdecl \ jvm_prog" where +"class_add P cd \ cd#P" + + +subsection "Fields" + +lemma class_add_has_fields: +assumes fs: "P \ D has_fields FDTs" and nc: "\is_class P C" +shows "class_add P (C, cdec) \ D has_fields FDTs" +using assms +proof(induct rule: Fields.induct) + case (has_fields_Object D fs ms FDTs) + from has_fields_is_class_Object[OF fs] nc have "C \ Object" by fast + with has_fields_Object show ?case + by(auto simp: class_def fun_upd_apply intro!: TypeRel.has_fields_Object) +next + case rec: (has_fields_rec C1 D fs ms FDTs FDTs') + with has_fields_is_class have [simp]: "D \ C" by auto + with rec have "C1 \ C" by(clarsimp simp: is_class_def) + with rec show ?case + by(auto simp: class_def fun_upd_apply intro: TypeRel.has_fields_rec) +qed + +lemma class_add_has_fields_rev: + "\ class_add P (C, cdec) \ D has_fields FDTs; \P \ D \\<^sup>* C \ + \ P \ D has_fields FDTs" +proof(induct rule: Fields.induct) + case (has_fields_Object D fs ms FDTs) + then show ?case by(auto simp: class_def fun_upd_apply intro!: TypeRel.has_fields_Object) +next + case rec: (has_fields_rec C1 D fs ms FDTs FDTs') + then have sub1: "P \ C1 \\<^sup>1 D" + by(auto simp: class_def fun_upd_apply intro!: subcls1I split: if_split_asm) + with rec.prems have cls: "\ P \ D \\<^sup>* C" by (meson converse_rtrancl_into_rtrancl) + with cls rec show ?case + by(auto simp: class_def fun_upd_apply + intro: TypeRel.has_fields_rec split: if_split_asm) +qed + +lemma class_add_has_field: +assumes "P \ C\<^sub>0 has F,b:T in D" and "\ is_class P C" +shows "class_add P (C, cdec) \ C\<^sub>0 has F,b:T in D" +using assms by(auto simp: has_field_def dest!: class_add_has_fields[of P C\<^sub>0]) + +lemma class_add_has_field_rev: +assumes has: "class_add P (C, cdec) \ C\<^sub>0 has F,b:T in D" + and ncp: "\D'. P \ C\<^sub>0 \\<^sup>* D' \ D' \ C" +shows "P \ C\<^sub>0 has F,b:T in D" +using assms by(auto simp: has_field_def dest!: class_add_has_fields_rev) + +lemma class_add_sees_field: +assumes "P \ C\<^sub>0 sees F,b:T in D" and "\ is_class P C" +shows "class_add P (C, cdec) \ C\<^sub>0 sees F,b:T in D" +using assms by(auto simp: sees_field_def dest!: class_add_has_fields[of P C\<^sub>0]) + +lemma class_add_sees_field_rev: +assumes has: "class_add P (C, cdec) \ C\<^sub>0 sees F,b:T in D" + and ncp: "\D'. P \ C\<^sub>0 \\<^sup>* D' \ D' \ C" +shows "P \ C\<^sub>0 sees F,b:T in D" +using assms by(auto simp: sees_field_def dest!: class_add_has_fields_rev) + +lemma class_add_field: +assumes fd: "P \ C\<^sub>0 sees F,b:T in D" and "\ is_class P C" +shows "field P C\<^sub>0 F = field (class_add P (C, cdec)) C\<^sub>0 F" +using class_add_sees_field[OF assms, of cdec] fd by simp + +subsection "Methods" + +lemma class_add_sees_methods: +assumes ms: "P \ D sees_methods Mm" and nc: "\is_class P C" +shows "class_add P (C, cdec) \ D sees_methods Mm" +using assms +proof(induct rule: Methods.induct) + case (sees_methods_Object D fs ms Mm) + from sees_methods_is_class_Object[OF ms] nc have "C \ Object" by fast + with sees_methods_Object show ?case + by(auto simp: class_def fun_upd_apply intro!: TypeRel.sees_methods_Object) +next + case rec: (sees_methods_rec C1 D fs ms Mm Mm') + with sees_methods_is_class have [simp]: "D \ C" by auto + with rec have "C1 \ C" by(clarsimp simp: is_class_def) + with rec show ?case + by(auto simp: class_def fun_upd_apply intro: TypeRel.sees_methods_rec) +qed + +lemma class_add_sees_methods_rev: + "\ class_add P (C, cdec) \ D sees_methods Mm; + \D'. P \ D \\<^sup>* D' \ D' \ C \ + \ P \ D sees_methods Mm" +proof(induct rule: Methods.induct) + case (sees_methods_Object D fs ms Mm) + then show ?case + by(auto simp: class_def fun_upd_apply intro!: TypeRel.sees_methods_Object) +next + case rec: (sees_methods_rec C1 D fs ms Mm Mm') + then have sub1: "P \ C1 \\<^sup>1 D" + by(auto simp: class_def fun_upd_apply intro!: subcls1I) + have cls: "\D'. P \ D \\<^sup>* D' \ D' \ C" + proof - + fix D' assume "P \ D \\<^sup>* D'" + with sub1 have "P \ C1 \\<^sup>* D'" by simp + with rec.prems show "D' \ C" by simp + qed + with cls rec show ?case + by(auto simp: class_def fun_upd_apply intro: TypeRel.sees_methods_rec) +qed + +lemma class_add_sees_methods_Obj: +assumes "P \ Object sees_methods Mm" and nObj: "C \ Object" +shows "class_add P (C, cdec) \ Object sees_methods Mm" +proof - + from assms obtain C' fs ms where cls: "class P Object = Some(C',fs,ms)" + by(auto elim!: Methods.cases) + with nObj have cls': "class (class_add P (C, cdec)) Object = Some(C',fs,ms)" + by(simp add: class_def fun_upd_apply) + from assms cls have "Mm = map_option (\m. (m, Object)) \ map_of ms" by(auto elim!: Methods.cases) + with assms cls' show ?thesis + by(auto simp: is_class_def fun_upd_apply intro!: sees_methods_Object) +qed + +lemma class_add_sees_methods_rev_Obj: +assumes "class_add P (C, cdec) \ Object sees_methods Mm" and nObj: "C \ Object" +shows "P \ Object sees_methods Mm" +proof - + from assms obtain C' fs ms where cls: "class (class_add P (C, cdec)) Object = Some(C',fs,ms)" + by(auto elim!: Methods.cases) + with nObj have cls': "class P Object = Some(C',fs,ms)" + by(simp add: class_def fun_upd_apply) + from assms cls have "Mm = map_option (\m. (m, Object)) \ map_of ms" by(auto elim!: Methods.cases) + with assms cls' show ?thesis + by(auto simp: is_class_def fun_upd_apply intro!: sees_methods_Object) +qed + +lemma class_add_sees_method: +assumes "P \ C\<^sub>0 sees M\<^sub>0, b : Ts\T = m in D" and "\ is_class P C" +shows "class_add P (C, cdec) \ C\<^sub>0 sees M\<^sub>0, b : Ts\T = m in D" +using assms by(auto simp: Method_def dest!: class_add_sees_methods[of P C\<^sub>0]) + +lemma class_add_method: +assumes md: "P \ C\<^sub>0 sees M\<^sub>0, b : Ts\T = m in D" and "\ is_class P C" +shows "method P C\<^sub>0 M\<^sub>0 = method (class_add P (C, cdec)) C\<^sub>0 M\<^sub>0" +using class_add_sees_method[OF assms, of cdec] md by simp + +lemma class_add_sees_method_rev: + "\ class_add P (C, cdec) \ C\<^sub>0 sees M\<^sub>0, b : Ts\T = m in D; + \ P \ C\<^sub>0 \\<^sup>* C \ + \ P \ C\<^sub>0 sees M\<^sub>0, b : Ts\T = m in D" + by(auto simp: Method_def dest!: class_add_sees_methods_rev) + +lemma class_add_sees_method_Obj: + "\ P \ Object sees M\<^sub>0, b : Ts\T = m in D; C \ Object \ + \ class_add P (C, cdec) \ Object sees M\<^sub>0, b : Ts\T = m in D" + by(auto simp: Method_def dest!: class_add_sees_methods_Obj[where P=P]) + +lemma class_add_sees_method_rev_Obj: + "\ class_add P (C, cdec) \ Object sees M\<^sub>0, b : Ts\T = m in D; C \ Object \ + \ P \ Object sees M\<^sub>0, b : Ts\T = m in D" + by(auto simp: Method_def dest!: class_add_sees_methods_rev_Obj[where P=P]) + +subsection "Types and states" + +lemma class_add_is_type: + "is_type P T \ is_type (class_add P (C, cdec)) T" + by(cases cdec, simp add: is_type_def is_class_def class_def fun_upd_apply split: ty.splits) + +lemma class_add_types: + "types P \ types (class_add P (C, cdec))" +using class_add_is_type by(cases cdec, clarsimp) + +lemma class_add_states: + "states P mxs mxl \ states (class_add P (C, cdec)) mxs mxl" +proof - + let ?A = "types P" and ?B = "types (class_add P (C, cdec))" + have ab: "?A \ ?B" by(rule class_add_types) + moreover have "\n. list n ?A \ list n ?B" using ab by(rule list_mono) + moreover have "list mxl (err ?A) \ list mxl (err ?B)" using err_mono[OF ab] by(rule list_mono) + ultimately show ?thesis by(auto simp: JVM_states_unfold intro!: err_mono opt_mono) +qed + +lemma class_add_check_types: + "check_types P mxs mxl \s \ check_types (class_add P (C, cdec)) mxs mxl \s" +using class_add_states by(fastforce simp: check_types_def) + +subsection "Subclasses and subtypes" + +lemma class_add_subcls: + "\ P \ D \\<^sup>* D'; \ is_class P C \ + \ class_add P (C, cdec) \ D \\<^sup>* D'" +proof(induct rule: rtrancl.induct) + case (rtrancl_into_rtrancl a b c) + then have "b \ C" by(clarsimp simp: is_class_def dest!: subcls1D) + with rtrancl_into_rtrancl show ?case + by(fastforce dest!: subcls1D simp: class_def fun_upd_apply + intro!: rtrancl_trans[of a b] subcls1I) +qed(simp) + +lemma class_add_subcls_rev: + "\ class_add P (C, cdec) \ D \\<^sup>* D'; \P \ D \\<^sup>* C \ + \ P \ D \\<^sup>* D'" +proof(induct rule: rtrancl.induct) + case (rtrancl_into_rtrancl a b c) + then have "b \ C" by(clarsimp simp: is_class_def dest!: subcls1D) + with rtrancl_into_rtrancl show ?case + by(fastforce dest!: subcls1D simp: class_def fun_upd_apply + intro!: rtrancl_trans[of a b] subcls1I) +qed(simp) + +lemma class_add_subtype: + "\ subtype P x y; \ is_class P C \ + \ subtype (class_add P (C, cdec)) x y" +proof(induct rule: widen.induct) + case (widen_subcls C D) + then show ?case using class_add_subcls by simp +qed(simp+) + +lemma class_add_widens: + "\ P \ Ts [\] Ts'; \ is_class P C \ + \ (class_add P (C, cdec)) \ Ts [\] Ts'" +using class_add_subtype by (metis (no_types) list_all2_mono) + +lemma class_add_sup_ty_opt: + "\ P \ l1 \\<^sub>\ l2; \ is_class P C \ + \ class_add P (C, cdec) \ l1 \\<^sub>\ l2" +using class_add_subtype by(auto simp: sup_ty_opt_def Err.le_def lesub_def split: err.splits) + +lemma class_add_sup_loc: +"\ P \ LT [\\<^sub>\] LT'; \ is_class P C \ + \ class_add P (C, cdec) \ LT [\\<^sub>\] LT'" +using class_add_sup_ty_opt[where P=P and C=C] by (simp add: list.rel_mono_strong) + +lemma class_add_sup_state: + "\ P \ \ \\<^sub>i \'; \ is_class P C \ + \ class_add P (C, cdec) \ \ \\<^sub>i \'" +using class_add_subtype class_add_sup_ty_opt + by(auto simp: sup_state_def Listn.le_def Product.le_def lesub_def class_add_widens + class_add_sup_ty_opt list_all2_mono) + +lemma class_add_sup_state_opt: + "\ P \ \ \' \'; \ is_class P C \ + \ class_add P (C, cdec) \ \ \' \'" + by(auto simp: sup_state_opt_def Opt.le_def lesub_def class_add_widens + class_add_sup_ty_opt list_all2_mono) + +subsection "Effect" + +lemma class_add_is_relevant_class: + "\ is_relevant_class i P C\<^sub>0; \ is_class P C \ + \ is_relevant_class i (class_add P (C, cdec)) C\<^sub>0" + by(cases i, auto simp: class_add_subcls) + +lemma class_add_is_relevant_class_rev: +assumes irc: "is_relevant_class i (class_add P (C, cdec)) C\<^sub>0" + and ncp: "\cd D'. cd \ set P \ \P \ fst cd \\<^sup>* C" + and wfxp: "wf_syscls P" +shows "is_relevant_class i P C\<^sub>0" +using assms +proof(cases i) + case (Getfield F D) with assms + show ?thesis by(fastforce simp: wf_syscls_def sys_xcpts_def dest!: class_add_subcls_rev) +next + case (Putfield F D) with assms + show ?thesis by(fastforce simp: wf_syscls_def sys_xcpts_def dest!: class_add_subcls_rev) +next + case (Checkcast D) with assms + show ?thesis by(fastforce simp: wf_syscls_def sys_xcpts_def dest!: class_add_subcls_rev) +qed(simp_all) + +lemma class_add_is_relevant_entry: + "\ is_relevant_entry P i pc e; \ is_class P C \ + \ is_relevant_entry (class_add P (C, cdec)) i pc e" + by(clarsimp simp: is_relevant_entry_def class_add_is_relevant_class) + +lemma class_add_is_relevant_entry_rev: + "\ is_relevant_entry (class_add P (C, cdec)) i pc e; + \cd D'. cd \ set P \ \P \ fst cd \\<^sup>* C; + wf_syscls P \ + \ is_relevant_entry P i pc e" + by(auto simp: is_relevant_entry_def dest!: class_add_is_relevant_class_rev) + +lemma class_add_relevant_entries: + "\ is_class P C + \ set (relevant_entries P i pc xt) \ set (relevant_entries (class_add P (C, cdec)) i pc xt)" + by(clarsimp simp: relevant_entries_def class_add_is_relevant_entry) + +lemma class_add_relevant_entries_eq: +assumes wf: "wf_prog wf_md P" and nclass: "\ is_class P C" +shows "relevant_entries P i pc xt = relevant_entries (class_add P (C, cdec)) i pc xt" +proof - + have ncp: "\cd D'. cd \ set P \ \P \ fst cd \\<^sup>* C" + by(rule wf_subcls_nCls'[OF assms]) + moreover from wf have wfsys: "wf_syscls P" by(simp add: wf_prog_def) + moreover + note class_add_is_relevant_entry[OF _ nclass, of i pc _ cdec] + class_add_is_relevant_entry_rev[OF _ ncp wfsys, of cdec i pc] + ultimately show ?thesis by (metis filter_cong relevant_entries_def) +qed + +lemma class_add_norm_eff_pc: +assumes ne: "\(pc',\') \ set (norm_eff i P pc \). pc' < mpc" +shows "\(pc',\') \ set (norm_eff i (class_add P (C, cdec)) pc \). pc' < mpc" +using assms by(cases i, auto simp: norm_eff_def) + +lemma class_add_norm_eff_sup_state_opt: +assumes ne: "\(pc',\') \ set (norm_eff i P pc \). P \ \' \' \s!pc'" + and nclass: "\ is_class P C" and app: "app\<^sub>i (i, P, pc, mxs, T, \)" +shows "\(pc',\') \ set (norm_eff i (class_add P (C, cdec)) pc \). (class_add P (C, cdec)) \ \' \' \s!pc'" +proof - + obtain ST LT where "\ = (ST,LT)" by(cases \) + with assms show ?thesis proof(cases i) + qed(fastforce simp: norm_eff_def + dest!: class_add_field[where cdec=cdec] class_add_method[where cdec=cdec] + class_add_sup_loc[OF _ nclass] class_add_subtype[OF _ nclass] + class_add_widens[OF _ nclass] class_add_sup_state_opt[OF _ nclass])+ +qed + +lemma class_add_xcpt_eff_eq: +assumes wf: "wf_prog wf_md P" and nclass: "\ is_class P C" +shows "xcpt_eff i P pc \ xt = xcpt_eff i (class_add P (C, cdec)) pc \ xt" +using class_add_relevant_entries_eq[OF assms, of i pc xt cdec] by(cases \, simp add: xcpt_eff_def) + +lemma class_add_eff_pc: +assumes eff: "\(pc',\') \ set (eff i P pc xt (Some \)). pc' < mpc" + and wf: "wf_prog wf_md P" and nclass: "\ is_class P C" +shows "\(pc',\') \ set (eff i (class_add P (C, cdec)) pc xt (Some \)). pc' < mpc" +using eff class_add_norm_eff_pc class_add_xcpt_eff_eq[OF wf nclass] + by(auto simp: norm_eff_def eff_def) + +lemma class_add_eff_sup_state_opt: +assumes eff: "\(pc',\') \ set (eff i P pc xt (Some \)). P \ \' \' \s!pc'" + and wf: "wf_prog wf_md P"and nclass: "\ is_class P C" + and app: "app\<^sub>i (i, P, pc, mxs, T, \)" +shows "\(pc',\') \ set (eff i (class_add P (C, cdec)) pc xt (Some \)). + (class_add P (C, cdec)) \ \' \' \s!pc'" +proof - + from eff have ne: "\(pc', \')\set (norm_eff i P pc \). P \ \' \' \s ! pc'" + by(simp add: norm_eff_def eff_def) + from eff have "\(pc', \')\set (xcpt_eff i P pc \ xt). P \ \' \' \s ! pc'" + by(simp add: xcpt_eff_def eff_def) + with class_add_norm_eff_sup_state_opt[OF ne nclass app] + class_add_xcpt_eff_eq[OF wf nclass]class_add_sup_state_opt[OF _ nclass] + show ?thesis by(cases cdec, auto simp: eff_def norm_eff_def xcpt_app_def) +qed + + +lemma class_add_app\<^sub>i: +assumes "app\<^sub>i (i, P, pc, mxs, T\<^sub>r, ST, LT)" and "\ is_class P C" +shows "app\<^sub>i (i, class_add P (C, cdec), pc, mxs, T\<^sub>r, ST, LT)" +using assms +proof(cases i) + case New then show ?thesis using assms by(fastforce simp: is_class_def class_def fun_upd_apply) +next + case Getfield then show ?thesis using assms + by(auto simp: class_add_subtype dest!: class_add_sees_field[where P=P]) +next + case Getstatic then show ?thesis using assms by(auto dest!: class_add_sees_field[where P=P]) +next + case Putfield then show ?thesis using assms + by(auto dest!: class_add_subtype[where P=P] class_add_sees_field[where P=P]) +next + case Putstatic then show ?thesis using assms + by(auto dest!: class_add_subtype[where P=P] class_add_sees_field[where P=P]) +next + case Checkcast then show ?thesis using assms + by(clarsimp simp: is_class_def class_def fun_upd_apply) +next + case Invoke then show ?thesis using assms + by(fastforce dest!: class_add_widens[where P=P] class_add_sees_method[where P=P]) +next + case Invokestatic then show ?thesis using assms + by(fastforce dest!: class_add_widens[where P=P] class_add_sees_method[where P=P]) +next + case Return then show ?thesis using assms by(clarsimp simp: class_add_subtype) +qed(simp+) + +lemma class_add_xcpt_app: +assumes xa: "xcpt_app i P pc mxs xt \" + and wf: "wf_prog wf_md P" and nclass: "\ is_class P C" +shows "xcpt_app i (class_add P (C, cdec)) pc mxs xt \" +using xa class_add_relevant_entries_eq[OF wf nclass] nclass + by(auto simp: xcpt_app_def is_class_def class_def fun_upd_apply) auto + +lemma class_add_app: +assumes app: "app i P mxs T pc mpc xt t" + and wf: "wf_prog wf_md P" and nclass: "\ is_class P C" +shows "app i (class_add P (C, cdec)) mxs T pc mpc xt t" +proof(cases t) + case (Some \) + let ?P = "class_add P (C, cdec)" + from assms Some have eff: "\(pc', \')\set (eff i P pc xt \\\). pc' < mpc" by(simp add: app_def) + from assms Some have app\<^sub>i: "app\<^sub>i (i,P,pc,mxs,T,\)" by(simp add: app_def) + with class_add_app\<^sub>i[OF _ nclass] Some have "app\<^sub>i (i,?P,pc,mxs,T,\)" by(cases \,simp) + moreover + from app class_add_xcpt_app[OF _ wf nclass] Some + have "xcpt_app i ?P pc mxs xt \" by(simp add: app_def del: xcpt_app_def) + moreover + from app class_add_eff_pc[OF eff wf nclass] Some + have "\(pc',\') \ set (eff i ?P pc xt t). pc' < mpc" by auto + moreover note app Some + ultimately show ?thesis by(simp add: app_def) +qed(simp) + +subsection "Well-formedness and well-typedness" + +lemma class_add_wf_mdecl: + "\ wf_mdecl wf_md P C\<^sub>0 md; + \C\<^sub>0 md. wf_md P C\<^sub>0 md \ wf_md (class_add P (C, cdec)) C\<^sub>0 md \ + \ wf_mdecl wf_md (class_add P (C, cdec)) C\<^sub>0 md" + by(clarsimp simp: wf_mdecl_def class_add_is_type) + +lemma class_add_wf_mdecl': +assumes wfd: "wf_mdecl wf_md P C\<^sub>0 md" + and ms: "(C\<^sub>0,S,fs,ms) \ set P" and md: "md \ set ms" + and wf_md': "\C\<^sub>0 S fs ms m.\(C\<^sub>0,S,fs,ms) \ set P; m \ set ms\ \ wf_md' (class_add P (C, cdec)) C\<^sub>0 m" +shows "wf_mdecl wf_md' (class_add P (C, cdec)) C\<^sub>0 md" +using assms by(clarsimp simp: wf_mdecl_def class_add_is_type) + +lemma class_add_wf_cdecl: +assumes wfcd: "wf_cdecl wf_md P cd" and cdP: "cd \ set P" + and ncp: "\ P \ fst cd \\<^sup>* C" and dist: "distinct_fst P" + and wfmd: "\C\<^sub>0 md. wf_md P C\<^sub>0 md \ wf_md (class_add P (C, cdec)) C\<^sub>0 md" + and nclass: "\ is_class P C" +shows "wf_cdecl wf_md (class_add P (C, cdec)) cd" +proof - + let ?P = "class_add P (C, cdec)" + obtain C1 D fs ms where [simp]: "cd = (C1,(D,fs,ms))" by(cases cd) + from wfcd + have "\f\set fs. wf_fdecl ?P f" by(auto simp: wf_cdecl_def wf_fdecl_def class_add_is_type) + moreover + from wfcd wfmd class_add_wf_mdecl + have "\m\set ms. wf_mdecl wf_md ?P C1 m" by(auto simp: wf_cdecl_def) + moreover + have "C1 \ Object \ is_class ?P D \ \ ?P \ D \\<^sup>* C1 + \ (\(M,b,Ts,T,m)\set ms. + \D' b' Ts' T' m'. ?P \ D sees M,b':Ts' \ T' = m' in D' \ + b = b' \ ?P \ Ts' [\] Ts \ ?P \ T \ T')" + proof - + assume nObj[simp]: "C1 \ Object" + with cdP dist have sub1: "P \ C1 \\<^sup>1 D" by(auto simp: class_def intro!: subcls1I map_of_SomeI) + with ncp have ncp': "\ P \ D \\<^sup>* C" by(auto simp: converse_rtrancl_into_rtrancl) + with wfcd + have clsD: "is_class ?P D" + by(auto simp: wf_cdecl_def is_class_def class_def fun_upd_apply) + moreover + from wfcd sub1 + have "\ ?P \ D \\<^sup>* C1" by(auto simp: wf_cdecl_def dest!: class_add_subcls_rev[OF _ ncp']) + moreover + have "\M b Ts T m D' b' Ts' T' m'. (M,b,Ts,T,m) \ set ms + \ ?P \ D sees M,b':Ts' \ T' = m' in D' + \ b = b' \ ?P \ Ts' [\] Ts \ ?P \ T \ T'" + proof - + fix M b Ts T m D' b' Ts' T' m' + assume ms: "(M,b,Ts,T,m) \ set ms" and meth': "?P \ D sees M,b':Ts' \ T' = m' in D'" + with sub1 + have "P \ D sees M,b':Ts' \ T' = m' in D'" + by(fastforce dest!: class_add_sees_method_rev[OF _ ncp']) + moreover + with wfcd ms meth' + have "b = b' \ P \ Ts' [\] Ts \ P \ T \ T'" + by(cases m', fastforce simp: wf_cdecl_def elim!: ballE[where x="(M,b,Ts,T,m)"]) + ultimately show "b = b' \ ?P \ Ts' [\] Ts \ ?P \ T \ T'" + by(auto dest!: class_add_subtype[OF _ nclass] class_add_widens[OF _ nclass]) + qed + ultimately show ?thesis by clarsimp + qed + moreover note wfcd + ultimately show ?thesis by(simp add: wf_cdecl_def) +qed + +lemma class_add_wf_cdecl': +assumes wfcd: "wf_cdecl wf_md P cd" and cdP: "cd \ set P" + and ncp: "\P \ fst cd \\<^sup>* C" and dist: "distinct_fst P" + and wfmd: "\C\<^sub>0 S fs ms m.\(C\<^sub>0,S,fs,ms) \ set P; m \ set ms\ \ wf_md' (class_add P (C, cdec)) C\<^sub>0 m" + and nclass: "\ is_class P C" +shows "wf_cdecl wf_md' (class_add P (C, cdec)) cd" +proof - + let ?P = "class_add P (C, cdec)" + obtain C1 D fs ms where [simp]: "cd = (C1,(D,fs,ms))" by(cases cd) + from wfcd + have "\f\set fs. wf_fdecl ?P f" by(auto simp: wf_cdecl_def wf_fdecl_def class_add_is_type) + moreover + from cdP wfcd wfmd + have "\m\set ms. wf_mdecl wf_md' ?P C1 m" + by(auto simp: wf_cdecl_def wf_mdecl_def class_add_is_type) + moreover + have "C1 \ Object \ is_class ?P D \ \ ?P \ D \\<^sup>* C1 + \ (\(M,b,Ts,T,m)\set ms. + \D' b' Ts' T' m'. ?P \ D sees M,b':Ts' \ T' = m' in D' \ + b = b' \ ?P \ Ts' [\] Ts \ ?P \ T \ T')" + proof - + assume nObj[simp]: "C1 \ Object" + with cdP dist have sub1: "P \ C1 \\<^sup>1 D" by(auto simp: class_def intro!: subcls1I map_of_SomeI) + with ncp have ncp': "\ P \ D \\<^sup>* C" by(auto simp: converse_rtrancl_into_rtrancl) + with wfcd + have clsD: "is_class ?P D" + by(auto simp: wf_cdecl_def is_class_def class_def fun_upd_apply) + moreover + from wfcd sub1 + have "\ ?P \ D \\<^sup>* C1" by(auto simp: wf_cdecl_def dest!: class_add_subcls_rev[OF _ ncp']) + moreover + have "\M b Ts T m D' b' Ts' T' m'. (M,b,Ts,T,m) \ set ms + \ ?P \ D sees M,b':Ts' \ T' = m' in D' + \ b = b' \ ?P \ Ts' [\] Ts \ ?P \ T \ T'" + proof - + fix M b Ts T m D' b' Ts' T' m' + assume ms: "(M,b,Ts,T,m) \ set ms" and meth': "?P \ D sees M,b':Ts' \ T' = m' in D'" + with sub1 + have "P \ D sees M,b':Ts' \ T' = m' in D'" + by(fastforce dest!: class_add_sees_method_rev[OF _ ncp']) + moreover + with wfcd ms meth' + have "b = b' \ P \ Ts' [\] Ts \ P \ T \ T'" + by(cases m', fastforce simp: wf_cdecl_def elim!: ballE[where x="(M,b,Ts,T,m)"]) + ultimately show "b = b' \ ?P \ Ts' [\] Ts \ ?P \ T \ T'" + by(auto dest!: class_add_subtype[OF _ nclass] class_add_widens[OF _ nclass]) + qed + ultimately show ?thesis by clarsimp + qed + moreover note wfcd + ultimately show ?thesis by(simp add: wf_cdecl_def) +qed + +lemma class_add_wt_start: + "\ wt_start P C\<^sub>0 b Ts mxl \s; \ is_class P C \ + \ wt_start (class_add P (C, cdec)) C\<^sub>0 b Ts mxl \s" +using class_add_sup_state_opt by(clarsimp simp: wt_start_def split: staticb.splits) + +lemma class_add_wt_instr: +assumes wti: "P,T,mxs,mpc,xt \ i,pc :: \s" + and wf: "wf_prog wf_md P" and nclass: "\ is_class P C" +shows "class_add P (C, cdec),T,mxs,mpc,xt \ i,pc :: \s" +proof - + let ?P = "class_add P (C, cdec)" + from wti have eff: "\(pc', \')\set (eff i P pc xt (\s ! pc)). P \ \' \' \s ! pc'" + by(simp add: wt_instr_def) + from wti have app\<^sub>i: "\s!pc \ None \ app\<^sub>i (i,P,pc,mxs,T,the (\s!pc))" + by(simp add: wt_instr_def app_def) + from wti class_add_app[OF _ wf nclass] + have "app i ?P mxs T pc mpc xt (\s!pc)" by(simp add: wt_instr_def) + moreover + have "\(pc',\') \ set (eff i ?P pc xt (\s!pc)). ?P \ \' \' \s!pc'" + proof(cases "\s!pc") + case Some with eff class_add_eff_sup_state_opt[OF _ wf nclass app\<^sub>i] show ?thesis by auto + qed(simp add: eff_def) + moreover note wti + ultimately show ?thesis by(clarsimp simp: wt_instr_def) +qed + +lemma class_add_wt_method: +assumes wtm: "wt_method P C\<^sub>0 b Ts T\<^sub>r mxs mxl\<^sub>0 is xt (\ C\<^sub>0 M\<^sub>0)" + and wf: "wf_prog wf_md P" and nclass: "\ is_class P C" +shows "wt_method (class_add P (C, cdec)) C\<^sub>0 b Ts T\<^sub>r mxs mxl\<^sub>0 is xt (\ C\<^sub>0 M\<^sub>0)" +proof - + let ?P = "class_add P (C, cdec)" + let ?\s = "\ C\<^sub>0 M\<^sub>0" + from wtm class_add_check_types + have "check_types ?P mxs ((case b of Static \ 0 | NonStatic \ 1)+size Ts+mxl\<^sub>0) (map OK ?\s)" + by(simp add: wt_method_def) + moreover + from wtm class_add_wt_start nclass + have "wt_start ?P C\<^sub>0 b Ts mxl\<^sub>0 ?\s" by(simp add: wt_method_def) + moreover + from wtm class_add_wt_instr[OF _ wf nclass] + have "\pc < size is. ?P,T\<^sub>r,mxs,size is,xt \ is!pc,pc :: ?\s" by(clarsimp simp: wt_method_def) + moreover note wtm + ultimately + show ?thesis by(clarsimp simp: wt_method_def) +qed + +lemma class_add_wt_method': + "\ (\P C (M,b,Ts,T\<^sub>r,(mxs,mxl\<^sub>0,is,xt)). wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt (\ C M)) P C\<^sub>0 md; + wf_prog wf_md P; \ is_class P C \ + \ (\P C (M,b,Ts,T\<^sub>r,(mxs,mxl\<^sub>0,is,xt)). wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt (\ C M)) + (class_add P (C, cdec)) C\<^sub>0 md" + by(clarsimp simp: class_add_wt_method) + +subsection \ @{text "distinct_fst"} \ + +lemma class_add_distinct_fst: +"\ distinct_fst P; \ is_class P C \ + \ distinct_fst (class_add P (C, cdec))" + by(clarsimp simp: distinct_fst_def is_class_def class_def) + +subsection "Conformance" + +lemma class_add_conf: + "\ P,h \ v :\ T; \ is_class P C \ + \ class_add P (C, cdec),h \ v :\ T" + by(clarsimp simp: conf_def class_add_subtype) + +lemma class_add_oconf: +fixes obj::obj +assumes oc: "P,h \ obj \" and ns: "\ is_class P C" + and ncp: "\D'. P \ fst(obj) \\<^sup>* D' \ D' \ C" +shows "(class_add P (C, cdec)),h \ obj \" +proof - + obtain C\<^sub>0 fs where [simp]: "obj=(C\<^sub>0,fs)" by(cases obj) + from oc have + oc': "\F D T. P \ C\<^sub>0 has F,NonStatic:T in D \ (\v. fs (F, D) = \v\ \ P,h \ v :\ T)" + by(simp add: oconf_def) + have "\F D T. class_add P (C, cdec) \ C\<^sub>0 has F,NonStatic:T in D + \ \v. fs(F,D) = Some v \ class_add P (C, cdec),h \ v :\ T" + proof - + fix F D T assume "class_add P (C, cdec) \ C\<^sub>0 has F,NonStatic:T in D" + with class_add_has_field_rev[OF _ ncp] have meth: "P \ C\<^sub>0 has F,NonStatic:T in D" by simp + then show "\v. fs(F,D) = Some v \ class_add P (C, cdec),h \ v :\ T" + using oc'[OF meth] class_add_conf[OF _ ns] by(fastforce simp: oconf_def) + qed + then show ?thesis by(simp add: oconf_def) +qed + +lemma class_add_soconf: +assumes soc: "P,h,C\<^sub>0 \\<^sub>s sfs \" and ns: "\ is_class P C" + and ncp: "\D'. P \ C\<^sub>0 \\<^sup>* D' \ D' \ C" +shows "(class_add P (C, cdec)),h,C\<^sub>0 \\<^sub>s sfs \" +proof - + from soc have + oc': "\F T. P \ C\<^sub>0 has F,Static:T in C\<^sub>0 \ (\v. sfs F = \v\ \ P,h \ v :\ T)" + by(simp add: soconf_def) + have "\F T. class_add P (C, cdec) \ C\<^sub>0 has F,Static:T in C\<^sub>0 + \ \v. sfs F = Some v \ class_add P (C, cdec),h \ v :\ T" + proof - + fix F T assume "class_add P (C, cdec) \ C\<^sub>0 has F,Static:T in C\<^sub>0" + with class_add_has_field_rev[OF _ ncp] have meth: "P \ C\<^sub>0 has F,Static:T in C\<^sub>0" by simp + then show "\v. sfs F = Some v \ class_add P (C, cdec),h \ v :\ T" + using oc'[OF meth] class_add_conf[OF _ ns] by(fastforce simp: soconf_def) + qed + then show ?thesis by(simp add: soconf_def) +qed + +lemma class_add_hconf: +assumes "P \ h \" and "\ is_class P C" + and "\a obj D'. h a = Some obj \ P \ fst(obj) \\<^sup>* D' \ D' \ C" +shows "class_add P (C, cdec) \ h \" +using assms by(auto simp: hconf_def intro!: class_add_oconf) + +lemma class_add_hconf_wf: +assumes wf: "wf_prog wf_md P" and "P \ h \" and "\ is_class P C" + and "\a obj. h a = Some obj \ fst(obj) \ C" +shows "class_add P (C, cdec) \ h \" +using wf_subcls_nCls[OF wf] assms by(fastforce simp: hconf_def intro!: class_add_oconf) + +lemma class_add_shconf: +assumes "P,h \\<^sub>s sh \" and ns: "\ is_class P C" + and "\C sobj D'. sh C = Some sobj \ P \ C \\<^sup>* D' \ D' \ C" +shows "class_add P (C, cdec),h \\<^sub>s sh \" +using assms by(fastforce simp: shconf_def) + +lemma class_add_shconf_wf: +assumes wf: "wf_prog wf_md P" and "P,h \\<^sub>s sh \" and "\ is_class P C" + and "\C sobj. sh C = Some sobj \ C \ C" +shows "class_add P (C, cdec),h \\<^sub>s sh \" +using wf_subcls_nCls[OF wf] assms by(fastforce simp: shconf_def) + + +end \ No newline at end of file diff --git a/thys/JinjaDCI/BV/Effect.thy b/thys/JinjaDCI/BV/Effect.thy new file mode 100644 --- /dev/null +++ b/thys/JinjaDCI/BV/Effect.thy @@ -0,0 +1,441 @@ +(* Title: JinjaDCI/BV/Effect.thy + Author: Gerwin Klein, Susannah Mansky + Copyright 2000 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory BV/Effect.thy by Gerwin Klein +*) + +section \Effect of Instructions on the State Type\ + +theory Effect +imports JVM_SemiType "../JVM/JVMExceptions" +begin + +\ \FIXME\ +locale prog = + fixes P :: "'a prog" + +locale jvm_method = prog + + fixes mxs :: nat + fixes mxl\<^sub>0 :: nat + fixes Ts :: "ty list" + fixes T\<^sub>r :: ty + fixes "is" :: "instr list" + fixes xt :: ex_table + + fixes mxl :: nat + defines mxl_def: "mxl \ 1+size Ts+mxl\<^sub>0" + +text \ Program counter of successor instructions: \ +primrec succs :: "instr \ ty\<^sub>i \ pc \ pc list" where + "succs (Load idx) \ pc = [pc+1]" +| "succs (Store idx) \ pc = [pc+1]" +| "succs (Push v) \ pc = [pc+1]" +| "succs (Getfield F C) \ pc = [pc+1]" +| "succs (Getstatic C F D) \ pc = [pc+1]" +| "succs (Putfield F C) \ pc = [pc+1]" +| "succs (Putstatic C F D) \ pc = [pc+1]" +| "succs (New C) \ pc = [pc+1]" +| "succs (Checkcast C) \ pc = [pc+1]" +| "succs Pop \ pc = [pc+1]" +| "succs IAdd \ pc = [pc+1]" +| "succs CmpEq \ pc = [pc+1]" +| succs_IfFalse: + "succs (IfFalse b) \ pc = [pc+1, nat (int pc + b)]" +| succs_Goto: + "succs (Goto b) \ pc = [nat (int pc + b)]" +| succs_Return: + "succs Return \ pc = []" +| succs_Invoke: + "succs (Invoke M n) \ pc = (if (fst \)!n = NT then [] else [pc+1])" +| succs_Invokestatic: + "succs (Invokestatic C M n) \ pc = [pc+1]" +| succs_Throw: + "succs Throw \ pc = []" + +text "Effect of instruction on the state type:" + +fun the_class:: "ty \ cname" where + "the_class (Class C) = C" + +fun eff\<^sub>i :: "instr \ 'm prog \ ty\<^sub>i \ ty\<^sub>i" where + eff\<^sub>i_Load: + "eff\<^sub>i (Load n, P, (ST, LT)) = (ok_val (LT ! n) # ST, LT)" +| eff\<^sub>i_Store: + "eff\<^sub>i (Store n, P, (T#ST, LT)) = (ST, LT[n:= OK T])" +| eff\<^sub>i_Push: + "eff\<^sub>i (Push v, P, (ST, LT)) = (the (typeof v) # ST, LT)" +| eff\<^sub>i_Getfield: + "eff\<^sub>i (Getfield F C, P, (T#ST, LT)) = (snd (snd (field P C F)) # ST, LT)" +| eff\<^sub>i_Getstatic: + "eff\<^sub>i (Getstatic C F D, P, (ST, LT)) = (snd (snd (field P C F)) # ST, LT)" +| eff\<^sub>i_Putfield: + "eff\<^sub>i (Putfield F C, P, (T\<^sub>1#T\<^sub>2#ST, LT)) = (ST,LT)" +| eff\<^sub>i_Putstatic: + "eff\<^sub>i (Putstatic C F D, P, (T#ST, LT)) = (ST,LT)" +| eff\<^sub>i_New: + "eff\<^sub>i (New C, P, (ST,LT)) = (Class C # ST, LT)" +| eff\<^sub>i_Checkcast: + "eff\<^sub>i (Checkcast C, P, (T#ST,LT)) = (Class C # ST,LT)" +| eff\<^sub>i_Pop: + "eff\<^sub>i (Pop, P, (T#ST,LT)) = (ST,LT)" +| eff\<^sub>i_IAdd: + "eff\<^sub>i (IAdd, P,(T\<^sub>1#T\<^sub>2#ST,LT)) = (Integer#ST,LT)" +| eff\<^sub>i_CmpEq: + "eff\<^sub>i (CmpEq, P, (T\<^sub>1#T\<^sub>2#ST,LT)) = (Boolean#ST,LT)" +| eff\<^sub>i_IfFalse: + "eff\<^sub>i (IfFalse b, P, (T\<^sub>1#ST,LT)) = (ST,LT)" +| eff\<^sub>i_Invoke: + "eff\<^sub>i (Invoke M n, P, (ST,LT)) = + (let C = the_class (ST!n); (D,b,Ts,T\<^sub>r,m) = method P C M + in (T\<^sub>r # drop (n+1) ST, LT))" +| eff\<^sub>i_Invokestatic: + "eff\<^sub>i (Invokestatic C M n, P, (ST,LT)) = + (let (D,b,Ts,T\<^sub>r,m) = method P C M + in (T\<^sub>r # drop n ST, LT))" +| eff\<^sub>i_Goto: + "eff\<^sub>i (Goto n, P, s) = s" + +fun is_relevant_class :: "instr \ 'm prog \ cname \ bool" where + rel_Getfield: + "is_relevant_class (Getfield F D) + = (\P C. P \ NullPointer \\<^sup>* C \ P \ NoSuchFieldError \\<^sup>* C + \ P \ IncompatibleClassChangeError \\<^sup>* C)" +| rel_Getstatic: + "is_relevant_class (Getstatic C F D) + = (\P C. True)" +| rel_Putfield: + "is_relevant_class (Putfield F D) + = (\P C. P \ NullPointer \\<^sup>* C \ P \ NoSuchFieldError \\<^sup>* C + \ P \ IncompatibleClassChangeError \\<^sup>* C)" +| rel_Putstatic: + "is_relevant_class (Putstatic C F D) + = (\P C. True)" +| rel_Checkcast: + "is_relevant_class (Checkcast D) = (\P C. P \ ClassCast \\<^sup>* C)" +| rel_New: + "is_relevant_class (New D) = (\P C. True)" +| rel_Throw: + "is_relevant_class Throw = (\P C. True)" +| rel_Invoke: + "is_relevant_class (Invoke M n) = (\P C. True)" +| rel_Invokestatic: + "is_relevant_class (Invokestatic C M n) = (\P C. True)" +| rel_default: + "is_relevant_class i = (\P C. False)" + +definition is_relevant_entry :: "'m prog \ instr \ pc \ ex_entry \ bool" where + "is_relevant_entry P i pc e \ (let (f,t,C,h,d) = e in is_relevant_class i P C \ pc \ {f.. instr \ pc \ ex_table \ ex_table" where + "relevant_entries P i pc = filter (is_relevant_entry P i pc)" + +definition xcpt_eff :: "instr \ 'm prog \ pc \ ty\<^sub>i + \ ex_table \ (pc \ ty\<^sub>i') list" where + "xcpt_eff i P pc \ et = (let (ST,LT) = \ in + map (\(f,t,C,h,d). (h, Some (Class C#drop (size ST - d) ST, LT))) (relevant_entries P i pc et))" + +definition norm_eff :: "instr \ 'm prog \ nat \ ty\<^sub>i \ (pc \ ty\<^sub>i') list" where + "norm_eff i P pc \ = map (\pc'. (pc',Some (eff\<^sub>i (i,P,\)))) (succs i \ pc)" + +definition eff :: "instr \ 'm prog \ pc \ ex_table \ ty\<^sub>i' \ (pc \ ty\<^sub>i') list" where + "eff i P pc et t = (case t of + None \ [] + | Some \ \ (norm_eff i P pc \) @ (xcpt_eff i P pc \ et))" + + +lemma eff_None: + "eff i P pc xt None = []" +by (simp add: eff_def) + +lemma eff_Some: + "eff i P pc xt (Some \) = norm_eff i P pc \ @ xcpt_eff i P pc \ xt" +by (simp add: eff_def) + +(* FIXME: getfield, \T D. P \ C sees F:T in D \ .. *) + +text "Conditions under which eff is applicable:" + +fun app\<^sub>i :: "instr \ 'm prog \ pc \ nat \ ty \ ty\<^sub>i \ bool" where + app\<^sub>i_Load: + "app\<^sub>i (Load n, P, pc, mxs, T\<^sub>r, (ST,LT)) = + (n < length LT \ LT ! n \ Err \ length ST < mxs)" +| app\<^sub>i_Store: + "app\<^sub>i (Store n, P, pc, mxs, T\<^sub>r, (T#ST, LT)) = + (n < length LT)" +| app\<^sub>i_Push: + "app\<^sub>i (Push v, P, pc, mxs, T\<^sub>r, (ST,LT)) = + (length ST < mxs \ typeof v \ None)" +| app\<^sub>i_Getfield: + "app\<^sub>i (Getfield F C, P, pc, mxs, T\<^sub>r, (T#ST, LT)) = + (\T\<^sub>f. P \ C sees F,NonStatic:T\<^sub>f in C \ P \ T \ Class C)" +| app\<^sub>i_Getstatic: + "app\<^sub>i (Getstatic C F D, P, pc, mxs, T\<^sub>r, (ST, LT)) = + (length ST < mxs \ (\T\<^sub>f. P \ C sees F,Static:T\<^sub>f in D))" +| app\<^sub>i_Putfield: + "app\<^sub>i (Putfield F C, P, pc, mxs, T\<^sub>r, (T\<^sub>1#T\<^sub>2#ST, LT)) = + (\T\<^sub>f. P \ C sees F,NonStatic:T\<^sub>f in C \ P \ T\<^sub>2 \ (Class C) \ P \ T\<^sub>1 \ T\<^sub>f)" +| app\<^sub>i_Putstatic: + "app\<^sub>i (Putstatic C F D, P, pc, mxs, T\<^sub>r, (T#ST, LT)) = + (\T\<^sub>f. P \ C sees F,Static:T\<^sub>f in D \ P \ T \ T\<^sub>f)" +| app\<^sub>i_New: + "app\<^sub>i (New C, P, pc, mxs, T\<^sub>r, (ST,LT)) = + (is_class P C \ length ST < mxs)" +| app\<^sub>i_Checkcast: + "app\<^sub>i (Checkcast C, P, pc, mxs, T\<^sub>r, (T#ST,LT)) = + (is_class P C \ is_refT T)" +| app\<^sub>i_Pop: + "app\<^sub>i (Pop, P, pc, mxs, T\<^sub>r, (T#ST,LT)) = + True" +| app\<^sub>i_IAdd: + "app\<^sub>i (IAdd, P, pc, mxs, T\<^sub>r, (T\<^sub>1#T\<^sub>2#ST,LT)) = (T\<^sub>1 = T\<^sub>2 \ T\<^sub>1 = Integer)" +| app\<^sub>i_CmpEq: + "app\<^sub>i (CmpEq, P, pc, mxs, T\<^sub>r, (T\<^sub>1#T\<^sub>2#ST,LT)) = + (T\<^sub>1 = T\<^sub>2 \ is_refT T\<^sub>1 \ is_refT T\<^sub>2)" +| app\<^sub>i_IfFalse: + "app\<^sub>i (IfFalse b, P, pc, mxs, T\<^sub>r, (Boolean#ST,LT)) = + (0 \ int pc + b)" +| app\<^sub>i_Goto: + "app\<^sub>i (Goto b, P, pc, mxs, T\<^sub>r, s) = + (0 \ int pc + b)" +| app\<^sub>i_Return: + "app\<^sub>i (Return, P, pc, mxs, T\<^sub>r, (T#ST,LT)) = + (P \ T \ T\<^sub>r)" +| app\<^sub>i_Throw: + "app\<^sub>i (Throw, P, pc, mxs, T\<^sub>r, (T#ST,LT)) = + is_refT T" +| app\<^sub>i_Invoke: + "app\<^sub>i (Invoke M n, P, pc, mxs, T\<^sub>r, (ST,LT)) = + (n < length ST \ + (ST!n \ NT \ + (\C D Ts T m. ST!n = Class C \ P \ C sees M,NonStatic:Ts \ T = m in D \ + P \ rev (take n ST) [\] Ts)))" +| app\<^sub>i_Invokestatic: + "app\<^sub>i (Invokestatic C M n, P, pc, mxs, T\<^sub>r, (ST,LT)) = + (length ST - n < mxs \ n \ length ST \ M \ clinit \ + (\D Ts T m. P \ C sees M,Static:Ts \ T = m in D \ + P \ rev (take n ST) [\] Ts))" + +| app\<^sub>i_default: + "app\<^sub>i (i,P, pc,mxs,T\<^sub>r,s) = False" + + +definition xcpt_app :: "instr \ 'm prog \ pc \ nat \ ex_table \ ty\<^sub>i \ bool" where + "xcpt_app i P pc mxs xt \ \ (\(f,t,C,h,d) \ set (relevant_entries P i pc xt). is_class P C \ d \ size (fst \) \ d < mxs)" + +definition app :: "instr \ 'm prog \ nat \ ty \ nat \ nat \ ex_table \ ty\<^sub>i' \ bool" where + "app i P mxs T\<^sub>r pc mpc xt t = (case t of None \ True | Some \ \ + app\<^sub>i (i,P,pc,mxs,T\<^sub>r,\) \ xcpt_app i P pc mxs xt \ \ + (\(pc',\') \ set (eff i P pc xt t). pc' < mpc))" + + +lemma app_Some: + "app i P mxs T\<^sub>r pc mpc xt (Some \) = + (app\<^sub>i (i,P,pc,mxs,T\<^sub>r,\) \ xcpt_app i P pc mxs xt \ \ + (\(pc',s') \ set (eff i P pc xt (Some \)). pc' < mpc))" +by (simp add: app_def) + +locale eff = jvm_method + + fixes eff\<^sub>i and app\<^sub>i and eff and app + fixes norm_eff and xcpt_app and xcpt_eff + + fixes mpc + defines "mpc \ size is" + + defines "eff\<^sub>i i \ \ Effect.eff\<^sub>i (i,P,\)" + notes eff\<^sub>i_simps [simp] = Effect.eff\<^sub>i.simps [where P = P, folded eff\<^sub>i_def] + + defines "app\<^sub>i i pc \ \ Effect.app\<^sub>i (i, P, pc, mxs, T\<^sub>r, \)" + notes app\<^sub>i_simps [simp] = Effect.app\<^sub>i.simps [where P=P and mxs=mxs and T\<^sub>r=T\<^sub>r, folded app\<^sub>i_def] + + defines "xcpt_eff i pc \ \ Effect.xcpt_eff i P pc \ xt" + notes xcpt_eff = Effect.xcpt_eff_def [of _ P _ _ xt, folded xcpt_eff_def] + + defines "norm_eff i pc \ \ Effect.norm_eff i P pc \" + notes norm_eff = Effect.norm_eff_def [of _ P, folded norm_eff_def eff\<^sub>i_def] + + defines "eff i pc \ Effect.eff i P pc xt" + notes eff = Effect.eff_def [of _ P _ xt, folded eff_def norm_eff_def xcpt_eff_def] + + defines "xcpt_app i pc \ \ Effect.xcpt_app i P pc mxs xt \" + notes xcpt_app = Effect.xcpt_app_def [of _ P _ mxs xt, folded xcpt_app_def] + + defines "app i pc \ Effect.app i P mxs T\<^sub>r pc mpc xt" + notes app = Effect.app_def [of _ P mxs T\<^sub>r _ mpc xt, folded app_def xcpt_app_def app\<^sub>i_def eff_def] + + +lemma length_cases2: + assumes "\LT. P ([],LT)" + assumes "\l ST LT. P (l#ST,LT)" + shows "P s" + by (cases s, cases "fst s") (auto intro!: assms) + + +lemma length_cases3: + assumes "\LT. P ([],LT)" + assumes "\l LT. P ([l],LT)" + assumes "\l ST LT. P (l#ST,LT)" + shows "P s" +(*<*) +proof - + obtain xs LT where s: "s = (xs,LT)" by (cases s) + show ?thesis + proof (cases xs) + case Nil with assms s show ?thesis by simp + next + fix l xs' assume "xs = l#xs'" + with assms s show ?thesis by simp + qed +qed +(*>*) + +lemma length_cases4: + assumes "\LT. P ([],LT)" + assumes "\l LT. P ([l],LT)" + assumes "\l l' LT. P ([l,l'],LT)" + assumes "\l l' ST LT. P (l#l'#ST,LT)" + shows "P s" +(*<*) +proof - + obtain xs LT where s: "s = (xs,LT)" by (cases s) + show ?thesis + proof (cases xs) + case Nil with assms s show ?thesis by simp + next + fix l xs' assume xs: "xs = l#xs'" + thus ?thesis + proof (cases xs') + case Nil with assms s xs show ?thesis by simp + next + fix l' ST assume "xs' = l'#ST" + with assms s xs show ?thesis by simp + qed + qed +qed +(*>*) + +text \ +\medskip +simp rules for @{term app} +\ +lemma appNone[simp]: "app i P mxs T\<^sub>r pc mpc et None = True" + by (simp add: app_def) + + +lemma appLoad[simp]: +"app\<^sub>i (Load idx, P, T\<^sub>r, mxs, pc, s) = (\ST LT. s = (ST,LT) \ idx < length LT \ LT!idx \ Err \ length ST < mxs)" + by (cases s, simp) + +lemma appStore[simp]: +"app\<^sub>i (Store idx,P,pc,mxs,T\<^sub>r,s) = (\ts ST LT. s = (ts#ST,LT) \ idx < length LT)" + by (rule length_cases2, auto) + +lemma appPush[simp]: +"app\<^sub>i (Push v,P,pc,mxs,T\<^sub>r,s) = + (\ST LT. s = (ST,LT) \ length ST < mxs \ typeof v \ None)" + by (cases s, simp) + +lemma appGetField[simp]: +"app\<^sub>i (Getfield F C,P,pc,mxs,T\<^sub>r,s) = + (\ oT vT ST LT. s = (oT#ST, LT) \ + P \ C sees F,NonStatic:vT in C \ P \ oT \ (Class C))" + by (rule length_cases2 [of _ s]) auto + +lemma appGetStatic[simp]: +"app\<^sub>i (Getstatic C F D,P,pc,mxs,T\<^sub>r,s) = + (\ vT ST LT. s = (ST, LT) \ length ST < mxs \ P \ C sees F,Static:vT in D)" + by (rule length_cases2 [of _ s]) auto + +lemma appPutField[simp]: +"app\<^sub>i (Putfield F C,P,pc,mxs,T\<^sub>r,s) = + (\ vT vT' oT ST LT. s = (vT#oT#ST, LT) \ + P \ C sees F,NonStatic:vT' in C \ P \ oT \ (Class C) \ P \ vT \ vT')" + by (rule length_cases4 [of _ s], auto) + +lemma appPutstatic[simp]: +"app\<^sub>i (Putstatic C F D,P,pc,mxs,T\<^sub>r,s) = + (\ vT vT' ST LT. s = (vT#ST, LT) \ + P \ C sees F,Static:vT' in D \ P \ vT \ vT')" + by (rule length_cases4 [of _ s], auto) + +lemma appNew[simp]: + "app\<^sub>i (New C,P,pc,mxs,T\<^sub>r,s) = + (\ST LT. s=(ST,LT) \ is_class P C \ length ST < mxs)" + by (cases s, simp) + +lemma appCheckcast[simp]: + "app\<^sub>i (Checkcast C,P,pc,mxs,T\<^sub>r,s) = + (\T ST LT. s = (T#ST,LT) \ is_class P C \ is_refT T)" + by (cases s, cases "fst s", simp add: app_def) (cases "hd (fst s)", auto) + +lemma app\<^sub>iPop[simp]: +"app\<^sub>i (Pop,P,pc,mxs,T\<^sub>r,s) = (\ts ST LT. s = (ts#ST,LT))" + by (rule length_cases2, auto) + +lemma appIAdd[simp]: +"app\<^sub>i (IAdd,P,pc,mxs,T\<^sub>r,s) = (\ST LT. s = (Integer#Integer#ST,LT))" +(*<*) +proof - + obtain ST LT where [simp]: "s = (ST,LT)" by (cases s) + have "ST = [] \ (\T. ST = [T]) \ (\T\<^sub>1 T\<^sub>2 ST'. ST = T\<^sub>1#T\<^sub>2#ST')" + by (cases ST, auto, case_tac list, auto) + moreover + { assume "ST = []" hence ?thesis by simp } + moreover + { fix T assume "ST = [T]" hence ?thesis by (cases T, auto) } + moreover + { fix T\<^sub>1 T\<^sub>2 ST' assume "ST = T\<^sub>1#T\<^sub>2#ST'" + hence ?thesis by (cases T\<^sub>1, auto) + } + ultimately show ?thesis by blast +qed +(*>*) + + +lemma appIfFalse [simp]: +"app\<^sub>i (IfFalse b,P,pc,mxs,T\<^sub>r,s) = + (\ST LT. s = (Boolean#ST,LT) \ 0 \ int pc + b)" +(*<*) + apply (rule length_cases2) + apply simp + apply (case_tac l) + apply auto + done +(*>*) + +lemma appCmpEq[simp]: +"app\<^sub>i (CmpEq,P,pc,mxs,T\<^sub>r,s) = + (\T\<^sub>1 T\<^sub>2 ST LT. s = (T\<^sub>1#T\<^sub>2#ST,LT) \ (\is_refT T\<^sub>1 \ T\<^sub>2 = T\<^sub>1 \ is_refT T\<^sub>1 \ is_refT T\<^sub>2))" + by (rule length_cases4, auto) + +lemma appReturn[simp]: +"app\<^sub>i (Return,P,pc,mxs,T\<^sub>r,s) = (\T ST LT. s = (T#ST,LT) \ P \ T \ T\<^sub>r)" + by (rule length_cases2, auto) + +lemma appThrow[simp]: + "app\<^sub>i (Throw,P,pc,mxs,T\<^sub>r,s) = (\T ST LT. s=(T#ST,LT) \ is_refT T)" + by (rule length_cases2, auto) + +lemma effNone: + "(pc', s') \ set (eff i P pc et None) \ s' = None" + by (auto simp add: eff_def xcpt_eff_def norm_eff_def) + + +text \ some helpers to make the specification directly executable: \ +lemma relevant_entries_append [simp]: + "relevant_entries P i pc (xt @ xt') = relevant_entries P i pc xt @ relevant_entries P i pc xt'" + by (unfold relevant_entries_def) simp + +lemma xcpt_app_append [iff]: + "xcpt_app i P pc mxs (xt@xt') \ = (xcpt_app i P pc mxs xt \ \ xcpt_app i P pc mxs xt' \)" + by (unfold xcpt_app_def) fastforce + +lemma xcpt_eff_append [simp]: + "xcpt_eff i P pc \ (xt@xt') = xcpt_eff i P pc \ xt @ xcpt_eff i P pc \ xt'" + by (unfold xcpt_eff_def, cases \) simp + +lemma app_append [simp]: + "app i P pc T mxs mpc (xt@xt') \ = (app i P pc T mxs mpc xt \ \ app i P pc T mxs mpc xt' \)" + by (unfold app_def eff_def) auto + +end diff --git a/thys/JinjaDCI/BV/EffectMono.thy b/thys/JinjaDCI/BV/EffectMono.thy new file mode 100644 --- /dev/null +++ b/thys/JinjaDCI/BV/EffectMono.thy @@ -0,0 +1,235 @@ +(* Title: JinjaDCI/BV/EffMono.thy + + Author: Gerwin Klein, Susannah Mansky + Copyright 2000 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory BV/EffectMono.thy by Gerwin Klein +*) + +section \ Monotonicity of eff and app \ + +theory EffectMono imports Effect begin + +declare not_Err_eq [iff] + +lemma app\<^sub>i_mono: + assumes wf: "wf_prog p P" + assumes less: "P \ \ \\<^sub>i \'" + shows "app\<^sub>i (i,P,mxs,mpc,rT,\') \ app\<^sub>i (i,P,mxs,mpc,rT,\)" +(*<*) +proof - + assume app: "app\<^sub>i (i,P,mxs,mpc,rT,\')" + + obtain ST LT ST' LT' where + [simp]: "\ = (ST,LT)" and + [simp]: "\' = (ST',LT')" + by (cases \, cases \') + + from less have [simp]: "size ST = size ST'" and [simp]: "size LT = size LT'" + by (auto dest: list_all2_lengthD) + + note [iff] = list_all2_Cons2 widen_Class + note [simp] = fun_of_def + + from app less show "app\<^sub>i (i,P,mxs,mpc,rT,\)" + proof (cases i) + case Load + with app less show ?thesis by (auto dest!: list_all2_nthD) + next + case (Invoke M n) + with app have n: "n < size ST'" by simp + + { assume "ST!n = NT" hence ?thesis using n app Invoke by simp } + moreover { + assume "ST'!n = NT" + moreover with n less have "ST!n = NT" + by (auto dest: list_all2_nthD) + ultimately have ?thesis using n app Invoke by simp + } + moreover { + assume ST: "ST!n \ NT" and ST': "ST'!n \ NT" + + from ST' app Invoke obtain D Ts T m C' where + D: "ST' ! n = Class D" and + Ts: "P \ rev (take n ST') [\] Ts" and + D_M: "P \ D sees M,NonStatic: Ts\T = m in C'" + by auto + + from n D less have "P \ ST!n \ ST'!n" + by (fastforce dest: list_all2_nthD2) + with D ST obtain D' where + D': "ST!n = Class D'" and DsubC: "P \ D' \\<^sup>* D" by auto + + from wf D_M DsubC obtain Ts' T' m' C'' where + D'_M: "P \ D' sees M,NonStatic: Ts'\T' = m' in C''" and + Ts': "P \ Ts [\] Ts'" + by (blast dest: sees_method_mono) + + from less have "P \ rev (take n ST) [\] rev (take n ST')" by simp + also note Ts also note Ts' + finally have "P \ rev (take n ST) [\] Ts'" . + with D'_M D' app less Invoke have ?thesis by fastforce + } + ultimately show ?thesis by blast + next + case (Invokestatic D M n) + moreover { + from app Invokestatic obtain Ts T m C' where + Ts: "P \ rev (take n ST') [\] Ts" and + D_M: "P \ D sees M,Static: Ts\T = m in C'" + by auto + from wf D_M obtain Ts' T' m' C'' where + D'_M: "P \ D sees M,Static: Ts'\T' = m' in C''" and + Ts': "P \ Ts [\] Ts'" + by (blast dest: sees_method_mono) + from less have "P \ rev (take n ST) [\] rev (take n ST')" by simp + also note Ts also note Ts' + finally have "P \ rev (take n ST) [\] Ts'" . + with D'_M app less Invokestatic have ?thesis by fastforce + } + ultimately show ?thesis by blast + next + case Getfield + with app less show ?thesis by (fastforce intro: rtrancl_trans) + next + case (Putfield F C) + with app less show ?thesis by (fastforce intro: widen_trans rtrancl_trans) + next + case (Putstatic C F D) + with app less show ?thesis by (fastforce intro: widen_trans rtrancl_trans) + next + case Return + with app less show ?thesis by (fastforce intro: widen_trans) + qed (auto elim!: refTE not_refTE) +qed +(*>*) + +lemma succs_mono: + assumes wf: "wf_prog p P" and app\<^sub>i: "app\<^sub>i (i,P,mxs,mpc,rT,\')" + shows "P \ \ \\<^sub>i \' \ set (succs i \ pc) \ set (succs i \' pc)" +(*<*) +proof (cases i) + case (Invoke M n) + obtain ST LT ST' LT' where + [simp]: "\ = (ST,LT)" and [simp]: "\' = (ST',LT')" by (cases \, cases \') + assume "P \ \ \\<^sub>i \'" + moreover + with app\<^sub>i Invoke have "n < size ST" by (auto dest: list_all2_lengthD) + ultimately + have "P \ ST!n \ ST'!n" by (auto simp add: fun_of_def dest: list_all2_nthD) + with Invoke show ?thesis by auto +qed auto +(*>*) + + +lemma app_mono: + assumes wf: "wf_prog p P" + assumes less': "P \ \ \' \'" + shows "app i P m rT pc mpc xt \' \ app i P m rT pc mpc xt \" +(*<*) +proof (cases \) + case None thus ?thesis by simp +next + case (Some \\<^sub>1) + moreover + with less' obtain \\<^sub>2 where \\<^sub>2: "\' = Some \\<^sub>2" by (cases \') auto + ultimately have less: "P \ \\<^sub>1 \\<^sub>i \\<^sub>2" using less' by simp + + assume "app i P m rT pc mpc xt \'" + with Some \\<^sub>2 obtain + app\<^sub>i: "app\<^sub>i (i, P, pc, m, rT, \\<^sub>2)" and + xcpt: "xcpt_app i P pc m xt \\<^sub>2" and + succs: "\(pc',s')\set (eff i P pc xt (Some \\<^sub>2)). pc' < mpc" + by (auto simp add: app_def) + + from wf less app\<^sub>i have "app\<^sub>i (i, P, pc, m, rT, \\<^sub>1)" by (rule app\<^sub>i_mono) + moreover + from less have "size (fst \\<^sub>1) = size (fst \\<^sub>2)" + by (cases \\<^sub>1, cases \\<^sub>2) (auto dest: list_all2_lengthD) + with xcpt have "xcpt_app i P pc m xt \\<^sub>1" by (simp add: xcpt_app_def) + moreover + from wf app\<^sub>i less have "\pc. set (succs i \\<^sub>1 pc) \ set (succs i \\<^sub>2 pc)" + by (blast dest: succs_mono) + with succs + have "\(pc',s')\set (eff i P pc xt (Some \\<^sub>1)). pc' < mpc" + by (cases \\<^sub>1, cases \\<^sub>2) + (auto simp add: eff_def norm_eff_def xcpt_eff_def dest: bspec) + ultimately + show ?thesis using Some by (simp add: app_def) +qed +(*>*) + + +lemma eff\<^sub>i_mono: + assumes wf: "wf_prog p P" + assumes less: "P \ \ \\<^sub>i \'" + assumes app\<^sub>i: "app i P m rT pc mpc xt (Some \')" + assumes succs: "succs i \ pc \ []" "succs i \' pc \ []" + shows "P \ eff\<^sub>i (i,P,\) \\<^sub>i eff\<^sub>i (i,P,\')" +(*<*) +proof - + obtain ST LT ST' LT' where + [simp]: "\ = (ST,LT)" and + [simp]: "\' = (ST',LT')" + by (cases \, cases \') + + note [simp] = eff_def app_def fun_of_def + + from less have "P \ (Some \) \' (Some \')" by simp + from wf this app\<^sub>i + have app: "app i P m rT pc mpc xt (Some \)" by (rule app_mono) + + from less app app\<^sub>i show ?thesis + proof (cases i) + case Throw with succs have False by simp + thus ?thesis .. + next + case Return with succs have False by simp + thus ?thesis .. + next + case (Load i) + from Load app obtain y where + y: "i < size LT" "LT!i = OK y" by clarsimp + from Load app\<^sub>i obtain y' where + y': "i < size LT'" "LT'!i = OK y'" by clarsimp + + from less have "P \ LT [\\<^sub>\] LT'" by simp + with y y' have "P \ y \ y'" by (auto dest: list_all2_nthD) + with Load less y y' app app\<^sub>i + show ?thesis by auto + next + case Store with less app app\<^sub>i + show ?thesis by (auto simp add: list_all2_update_cong) + next + case (Invoke M n) + with app\<^sub>i have n: "n < size ST'" by simp + from less have [simp]: "size ST = size ST'" + by (auto dest: list_all2_lengthD) + + from Invoke succs have ST: "ST!n \ NT" and ST': "ST'!n \ NT" + by (auto split: if_split_asm) + + from ST' app\<^sub>i Invoke obtain D Ts T m C' where + D: "ST' ! n = Class D" and + D_M: "P \ D sees M,NonStatic: Ts\T = m in C'" + by auto + + from n D less have "P \ ST!n \ ST'!n" + by (fastforce dest: list_all2_nthD2) + with D ST obtain D' where + D': "ST ! n = Class D'" and DsubC: "P \ D' \\<^sup>* D" + by (auto simp: widen_Class) + + from wf D_M DsubC obtain Ts' T' m' C'' where + D'_M: "P \ D' sees M,NonStatic: Ts'\T' = m' in C''" and + Ts': "P \ T' \ T" + by (blast dest: sees_method_mono) + + with Invoke n D D' D_M less + show ?thesis by (auto intro: list_all2_dropI) + qed auto +qed +(*>*) + +end + diff --git a/thys/JinjaDCI/BV/JVM_SemiType.thy b/thys/JinjaDCI/BV/JVM_SemiType.thy new file mode 100644 --- /dev/null +++ b/thys/JinjaDCI/BV/JVM_SemiType.thy @@ -0,0 +1,256 @@ +(* Title: HOL/MicroJava/BV/JVM.thy + + Author: Gerwin Klein + Copyright 2000 TUM + +*) + +section \ The JVM Type System as Semilattice \ + +theory JVM_SemiType imports SemiType begin + +type_synonym ty\<^sub>l = "ty err list" +type_synonym ty\<^sub>s = "ty list" +type_synonym ty\<^sub>i = "ty\<^sub>s \ ty\<^sub>l" +type_synonym ty\<^sub>i' = "ty\<^sub>i option" +type_synonym ty\<^sub>m = "ty\<^sub>i' list" +type_synonym ty\<^sub>P = "mname \ cname \ ty\<^sub>m" + + +definition stk_esl :: "'c prog \ nat \ ty\<^sub>s esl" +where + "stk_esl P mxs \ upto_esl mxs (SemiType.esl P)" + +definition loc_sl :: "'c prog \ nat \ ty\<^sub>l sl" +where + "loc_sl P mxl \ Listn.sl mxl (Err.sl (SemiType.esl P))" + +definition sl :: "'c prog \ nat \ nat \ ty\<^sub>i' err sl" +where + "sl P mxs mxl \ + Err.sl(Opt.esl(Product.esl (stk_esl P mxs) (Err.esl(loc_sl P mxl))))" + + +definition states :: "'c prog \ nat \ nat \ ty\<^sub>i' err set" +where "states P mxs mxl \ fst(sl P mxs mxl)" + +definition le :: "'c prog \ nat \ nat \ ty\<^sub>i' err ord" +where + "le P mxs mxl \ fst(snd(sl P mxs mxl))" + +definition sup :: "'c prog \ nat \ nat \ ty\<^sub>i' err binop" +where + "sup P mxs mxl \ snd(snd(sl P mxs mxl))" + + +definition sup_ty_opt :: "['c prog,ty err,ty err] \ bool" + ("_ \ _ \\<^sub>\ _" [71,71,71] 70) +where + "sup_ty_opt P \ Err.le (subtype P)" + +definition sup_state :: "['c prog,ty\<^sub>i,ty\<^sub>i] \ bool" + ("_ \ _ \\<^sub>i _" [71,71,71] 70) +where + "sup_state P \ Product.le (Listn.le (subtype P)) (Listn.le (sup_ty_opt P))" + +definition sup_state_opt :: "['c prog,ty\<^sub>i',ty\<^sub>i'] \ bool" + ("_ \ _ \'' _" [71,71,71] 70) +where + "sup_state_opt P \ Opt.le (sup_state P)" + +abbreviation + sup_loc :: "['c prog,ty\<^sub>l,ty\<^sub>l] \ bool" ("_ \ _ [\\<^sub>\] _" [71,71,71] 70) + where "P \ LT [\\<^sub>\] LT' \ list_all2 (sup_ty_opt P) LT LT'" + +notation (ASCII) + sup_ty_opt ("_ |- _ <=T _" [71,71,71] 70) and + sup_state ("_ |- _ <=i _" [71,71,71] 70) and + sup_state_opt ("_ |- _ <=' _" [71,71,71] 70) and + sup_loc ("_ |- _ [<=T] _" [71,71,71] 70) + + +subsection "Unfolding" + +lemma JVM_states_unfold: + "states P mxs mxl \ err(opt((Union {list n (types P) |n. n <= mxs}) \ + list mxl (err(types P))))" +(*<*) + apply (unfold states_def sl_def Opt.esl_def Err.sl_def + stk_esl_def loc_sl_def Product.esl_def + Listn.sl_def upto_esl_def SemiType.esl_def Err.esl_def) + apply simp + done +(*>*) + +lemma JVM_le_unfold: + "le P m n \ + Err.le(Opt.le(Product.le(Listn.le(subtype P))(Listn.le(Err.le(subtype P)))))" +(*<*) + apply (unfold le_def sl_def Opt.esl_def Err.sl_def + stk_esl_def loc_sl_def Product.esl_def + Listn.sl_def upto_esl_def SemiType.esl_def Err.esl_def) + apply simp + done +(*>*) + +lemma sl_def2: + "JVM_SemiType.sl P mxs mxl \ + (states P mxs mxl, JVM_SemiType.le P mxs mxl, JVM_SemiType.sup P mxs mxl)" +(*<*) by (unfold JVM_SemiType.sup_def states_def JVM_SemiType.le_def) simp (*>*) + + +lemma JVM_le_conv: + "le P m n (OK t1) (OK t2) = P \ t1 \' t2" +(*<*) by (simp add: JVM_le_unfold Err.le_def lesub_def sup_state_opt_def + sup_state_def sup_ty_opt_def) (*>*) + +lemma JVM_le_Err_conv: + "le P m n = Err.le (sup_state_opt P)" +(*<*) by (unfold sup_state_opt_def sup_state_def + sup_ty_opt_def JVM_le_unfold) simp (*>*) + +lemma err_le_unfold [iff]: + "Err.le r (OK a) (OK b) = r a b" +(*<*) by (simp add: Err.le_def lesub_def) (*>*) + + +subsection \ Semilattice \ + +lemma order_sup_state_opt [intro, simp]: + "wf_prog wf_mb P \ order (sup_state_opt P)" +(*<*) by (unfold sup_state_opt_def sup_state_def sup_ty_opt_def) blast (*>*) + +lemma semilat_JVM [intro?]: + "wf_prog wf_mb P \ semilat (JVM_SemiType.sl P mxs mxl)" +(*<*) + apply (unfold JVM_SemiType.sl_def stk_esl_def loc_sl_def) + apply (blast intro: err_semilat_Product_esl err_semilat_upto_esl + Listn_sl err_semilat_JType_esl) + done +(*>*) + +lemma acc_JVM [intro]: + "wf_prog wf_mb P \ acc (JVM_SemiType.le P mxs mxl)" +(*<*) by (unfold JVM_le_unfold) blast (*>*) + + +subsection \ Widening with @{text "\"} \ + +lemma subtype_refl[iff]: "subtype P t t" (*<*) by (simp add: fun_of_def) (*>*) + +lemma sup_ty_opt_refl [iff]: "P \ T \\<^sub>\ T" +(*<*) + apply (unfold sup_ty_opt_def) + apply (fold lesub_def) + apply (rule le_err_refl) + apply (simp add: lesub_def) + done +(*>*) + +lemma Err_any_conv [iff]: "P \ Err \\<^sub>\ T = (T = Err)" +(*<*) by (unfold sup_ty_opt_def) (rule Err_le_conv [simplified lesub_def]) (*>*) + +lemma any_Err [iff]: "P \ T \\<^sub>\ Err" +(*<*) by (unfold sup_ty_opt_def) (rule le_Err [simplified lesub_def]) (*>*) + +lemma OK_OK_conv [iff]: + "P \ OK T \\<^sub>\ OK T' = P \ T \ T'" +(*<*) by (simp add: sup_ty_opt_def fun_of_def) (*>*) + +lemma any_OK_conv [iff]: + "P \ X \\<^sub>\ OK T' = (\T. X = OK T \ P \ T \ T')" +(*<*) + apply (unfold sup_ty_opt_def) + apply (rule le_OK_conv [simplified lesub_def]) + done +(*>*) + +lemma OK_any_conv: + "P \ OK T \\<^sub>\ X = (X = Err \ (\T'. X = OK T' \ P \ T \ T'))" +(*<*) + apply (unfold sup_ty_opt_def) + apply (rule OK_le_conv [simplified lesub_def]) + done +(*>*) + +lemma sup_ty_opt_trans [intro?, trans]: + "\P \ a \\<^sub>\ b; P \ b \\<^sub>\ c\ \ P \ a \\<^sub>\ c" +(*<*) by (auto intro: widen_trans + simp add: sup_ty_opt_def Err.le_def lesub_def fun_of_def + split: err.splits) (*>*) + + +subsection "Stack and Registers" + +lemma stk_convert: + "P \ ST [\] ST' = Listn.le (subtype P) ST ST'" +(*<*) by (simp add: Listn.le_def lesub_def) (*>*) + +lemma sup_loc_refl [iff]: "P \ LT [\\<^sub>\] LT" +(*<*) by (rule list_all2_refl) simp (*>*) + +lemmas sup_loc_Cons1 [iff] = list_all2_Cons1 [of "sup_ty_opt P"] for P + +lemma sup_loc_def: + "P \ LT [\\<^sub>\] LT' \ Listn.le (sup_ty_opt P) LT LT'" +(*<*) by (simp add: Listn.le_def lesub_def) (*>*) + +lemma sup_loc_widens_conv [iff]: + "P \ map OK Ts [\\<^sub>\] map OK Ts' = P \ Ts [\] Ts'" +(*<*) + by (simp add: list_all2_map1 list_all2_map2) +(*>*) + + +lemma sup_loc_trans [intro?, trans]: + "\P \ a [\\<^sub>\] b; P \ b [\\<^sub>\] c\ \ P \ a [\\<^sub>\] c" +(*<*) by (rule list_all2_trans, rule sup_ty_opt_trans) (*>*) + + +subsection "State Type" + +lemma sup_state_conv [iff]: + "P \ (ST,LT) \\<^sub>i (ST',LT') = (P \ ST [\] ST' \ P \ LT [\\<^sub>\] LT')" +(*<*) by (auto simp add: sup_state_def stk_convert lesub_def Product.le_def sup_loc_def) (*>*) + +lemma sup_state_conv2: + "P \ s1 \\<^sub>i s2 = (P \ fst s1 [\] fst s2 \ P \ snd s1 [\\<^sub>\] snd s2)" +(*<*) by (cases s1, cases s2) simp (*>*) + +lemma sup_state_refl [iff]: "P \ s \\<^sub>i s" +(*<*) by (auto simp add: sup_state_conv2) (*>*) + +lemma sup_state_trans [intro?, trans]: + "\P \ a \\<^sub>i b; P \ b \\<^sub>i c\ \ P \ a \\<^sub>i c" +(*<*) by (auto intro: sup_loc_trans widens_trans simp add: sup_state_conv2) (*>*) + + +lemma sup_state_opt_None_any [iff]: + "P \ None \' s" +(*<*) by (simp add: sup_state_opt_def Opt.le_def) (*>*) + +lemma sup_state_opt_any_None [iff]: + "P \ s \' None = (s = None)" +(*<*) by (simp add: sup_state_opt_def Opt.le_def) (*>*) + +lemma sup_state_opt_Some_Some [iff]: + "P \ Some a \' Some b = P \ a \\<^sub>i b" +(*<*) by (simp add: sup_state_opt_def Opt.le_def lesub_def) (*>*) + +lemma sup_state_opt_any_Some: + "P \ (Some s) \' X = (\s'. X = Some s' \ P \ s \\<^sub>i s')" +(*<*) by (simp add: sup_state_opt_def Opt.le_def lesub_def) (*>*) + +lemma sup_state_opt_refl [iff]: "P \ s \' s" +(*<*) by (simp add: sup_state_opt_def Opt.le_def lesub_def) (*>*) + +lemma sup_state_opt_trans [intro?, trans]: + "\P \ a \' b; P \ b \' c\ \ P \ a \' c" +(*<*) + apply (unfold sup_state_opt_def Opt.le_def lesub_def) + apply (simp del: split_paired_All) + apply (rule sup_state_trans, assumption+) + done +(*>*) + +end diff --git a/thys/JinjaDCI/BV/LBVJVM.thy b/thys/JinjaDCI/BV/LBVJVM.thy new file mode 100644 --- /dev/null +++ b/thys/JinjaDCI/BV/LBVJVM.thy @@ -0,0 +1,226 @@ +(* Title: JinjaDCI/BV/LBVJVM.thy + + Author: Tobias Nipkow, Gerwin Klein, Susannah Mansky + Copyright 2000 TUM, 2020 UIUC + + Based on the Jinja theory BV/LBVJVM.thy by Tobias Nipkow and Gerwin Klein +*) + +section \ LBV for the JVM \label{sec:JVM} \ + +theory LBVJVM +imports Jinja.Abstract_BV TF_JVM +begin + +type_synonym prog_cert = "cname \ mname \ ty\<^sub>i' err list" + +definition check_cert :: "jvm_prog \ nat \ nat \ nat \ ty\<^sub>i' err list \ bool" +where + "check_cert P mxs mxl n cert \ check_types P mxs mxl cert \ size cert = n+1 \ + (\i Err) \ cert!n = OK None" + +definition lbvjvm :: "jvm_prog \ nat \ nat \ ty \ ex_table \ + ty\<^sub>i' err list \ instr list \ ty\<^sub>i' err \ ty\<^sub>i' err" +where + "lbvjvm P mxs maxr T\<^sub>r et cert bs \ + wtl_inst_list bs cert (JVM_SemiType.sup P mxs maxr) (JVM_SemiType.le P mxs maxr) Err (OK None) (exec P mxs T\<^sub>r et bs) 0" + +definition wt_lbv :: "jvm_prog \ cname \ staticb \ ty list \ ty \ nat \ nat \ + ex_table \ ty\<^sub>i' err list \ instr list \ bool" +where + "wt_lbv P C b Ts T\<^sub>r mxs mxl\<^sub>0 et cert ins \ + check_cert P mxs ((case b of Static \ 0 | NonStatic \ 1)+size Ts+mxl\<^sub>0) (size ins) cert \ + 0 < size ins \ + (let start = Some ([],(case b of Static \ [] | NonStatic \ [OK (Class C)]) + @((map OK Ts))@(replicate mxl\<^sub>0 Err)); + result = lbvjvm P mxs ((case b of Static \ 0 | NonStatic \ 1)+size Ts+mxl\<^sub>0) T\<^sub>r et cert ins (OK start) + in result \ Err)" + +definition wt_jvm_prog_lbv :: "jvm_prog \ prog_cert \ bool" +where + "wt_jvm_prog_lbv P cert \ + wf_prog (\P C (mn,b,Ts,T\<^sub>r,(mxs,mxl\<^sub>0,ins,et)). wt_lbv P C b Ts T\<^sub>r mxs mxl\<^sub>0 et (cert C mn) ins) P" + +definition mk_cert :: "jvm_prog \ nat \ ty \ ex_table \ instr list + \ ty\<^sub>m \ ty\<^sub>i' err list" +where + "mk_cert P mxs T\<^sub>r et bs phi \ make_cert (exec P mxs T\<^sub>r et bs) (map OK phi) (OK None)" + +definition prg_cert :: "jvm_prog \ ty\<^sub>P \ prog_cert" +where + "prg_cert P phi C mn \ let (C,b,Ts,T\<^sub>r,(mxs,mxl\<^sub>0,ins,et)) = method P C mn + in mk_cert P mxs T\<^sub>r et ins (phi C mn)" + +lemma check_certD [intro?]: + "check_cert P mxs mxl n cert \ cert_ok cert n Err (OK None) (states P mxs mxl)" + by (unfold cert_ok_def check_cert_def check_types_def) auto + + +lemma (in start_context) wt_lbv_wt_step: + assumes lbv: "wt_lbv P C b Ts T\<^sub>r mxs mxl\<^sub>0 xt cert is" + shows "\\s \ list (size is) A. wt_step r Err step \s \ OK first \\<^sub>r \s!0" +(*<*) +proof - + from wf have "semilat (JVM_SemiType.sl P mxs mxl)" .. + hence "semilat (A, r, f)" by (simp add: sl_def2) + moreover have "top r Err" by (simp add: JVM_le_Err_conv) + moreover have "Err \ A" by (simp add: JVM_states_unfold) + moreover have "bottom r (OK None)" + by (simp add: JVM_le_Err_conv bottom_def lesub_def Err.le_def split: err.split) + moreover have "OK None \ A" by (simp add: JVM_states_unfold) + moreover note bounded_step + moreover from lbv have "cert_ok cert (size is) Err (OK None) A" + by (unfold wt_lbv_def) (auto dest: check_certD) + moreover note exec_pres_type + moreover + from lbv + have "wtl_inst_list is cert f r Err (OK None) step 0 (OK first) \ Err" + by (cases b; simp add: wt_lbv_def lbvjvm_def step_def_exec [symmetric]) + moreover note first_in_A + moreover from lbv have "0 < size is" by (simp add: wt_lbv_def) + ultimately show ?thesis by (rule lbvs.wtl_sound_strong [OF lbvs.intro, OF lbv.intro lbvs_axioms.intro, OF Semilat.intro lbv_axioms.intro]) +qed +(*>*) + + +lemma (in start_context) wt_lbv_wt_method: + assumes lbv: "wt_lbv P C b Ts T\<^sub>r mxs mxl\<^sub>0 xt cert is" + shows "\\s. wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt \s" +(*<*) +proof - + from lbv have l: "is \ []" by (simp add: wt_lbv_def) + moreover + from wf lbv C Ts obtain \s where + list: "\s \ list (size is) A" and + step: "wt_step r Err step \s" and + start: "OK first \\<^sub>r \s!0" + by (blast dest: wt_lbv_wt_step) + from list have [simp]: "size \s = size is" by simp + have "size (map ok_val \s) = size is" by simp + moreover from l have 0: "0 < size \s" by simp + with step obtain \s0 where "\s!0 = OK \s0" + by (unfold wt_step_def) blast + with start 0 have "wt_start P C b Ts mxl\<^sub>0 (map ok_val \s)" + by (cases b; simp add: wt_start_def JVM_le_Err_conv lesub_def Err.le_def) + moreover { + from list have "check_types P mxs mxl \s" by (simp add: check_types_def) + also from step have "\x \ set \s. x \ Err" + by (auto simp add: all_set_conv_all_nth wt_step_def) + hence [symmetric]: "map OK (map ok_val \s) = \s" + by (auto intro!: map_idI) + finally have "check_types P mxs mxl (map OK (map ok_val \s))" . + } + moreover { + note bounded_step + moreover from list have "set \s \ A" by simp + moreover from step have "wt_err_step (sup_state_opt P) step \s" + by (simp add: wt_err_step_def JVM_le_Err_conv) + ultimately have "wt_app_eff (sup_state_opt P) app eff (map ok_val \s)" + by (auto intro: wt_err_imp_wt_app_eff simp add: exec_def states_def) + } + ultimately have "wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt (map ok_val \s)" + by (simp add: wt_method_def2 check_types_def del: map_map) + thus ?thesis .. +qed +(*>*) + + +lemma (in start_context) wt_method_wt_lbv: + assumes wt: "wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt \s" + defines [simp]: "cert \ mk_cert P mxs T\<^sub>r xt is \s" + + shows "wt_lbv P C b Ts T\<^sub>r mxs mxl\<^sub>0 xt cert is" +(*<*) +proof - + let ?\s = "map OK \s" + let ?cert = "make_cert step ?\s (OK None)" + + from wt obtain + 0: "0 < size is" and + size: "size is = size ?\s" and + ck_types: "check_types P mxs mxl ?\s" and + wt_start: "wt_start P C b Ts mxl\<^sub>0 \s" and + app_eff: "wt_app_eff (sup_state_opt P) app eff \s" + by (force simp add: wt_method_def2 check_types_def) + + from wf have "semilat (JVM_SemiType.sl P mxs mxl)" .. + hence "semilat (A, r, f)" by (simp add: sl_def2) + moreover have "top r Err" by (simp add: JVM_le_Err_conv) + moreover have "Err \ A" by (simp add: JVM_states_unfold) + moreover have "bottom r (OK None)" + by (simp add: JVM_le_Err_conv bottom_def lesub_def Err.le_def split: err.split) + moreover have "OK None \ A" by (simp add: JVM_states_unfold) + moreover from wf have "mono r step (size is) A" by (rule step_mono) + hence "mono r step (size ?\s) A" by (simp add: size) + moreover from exec_pres_type + have "pres_type step (size ?\s) A" by (simp add: size) + moreover + from ck_types have \s_in_A: "set ?\s \ A" by (simp add: check_types_def) + hence "\pc. pc < size ?\s \ ?\s!pc \ A \ ?\s!pc \ Err" by auto + moreover from bounded_step + have "bounded step (size ?\s)" by (simp add: size) + moreover have "OK None \ Err" by simp + moreover from bounded_step size \s_in_A app_eff + have "wt_err_step (sup_state_opt P) step ?\s" + by (auto intro: wt_app_eff_imp_wt_err simp add: exec_def states_def) + hence "wt_step r Err step ?\s" + by (simp add: wt_err_step_def JVM_le_Err_conv) + moreover + from 0 size have "0 < size \s" by auto + hence "?\s!0 = OK (\s!0)" by simp + with wt_start have "OK first \\<^sub>r ?\s!0" + by (cases b; clarsimp simp add: wt_start_def lesub_def Err.le_def JVM_le_Err_conv) + moreover note first_in_A + moreover have "OK first \ Err" by simp + moreover note size + ultimately + have "wtl_inst_list is ?cert f r Err (OK None) step 0 (OK first) \ Err" + by (rule lbvc.wtl_complete [OF lbvc.intro, OF lbv.intro lbvc_axioms.intro, OF Semilat.intro lbv_axioms.intro]) + moreover from 0 size have "\s \ []" by auto + moreover from ck_types have "check_types P mxs mxl ?cert" + apply (auto simp add: make_cert_def check_types_def JVM_states_unfold) + apply (subst Ok_in_err [symmetric]) + apply (drule nth_mem) + apply auto + done + moreover note 0 size + ultimately show ?thesis + by (simp add: wt_lbv_def lbvjvm_def mk_cert_def step_def_exec [symmetric] + check_cert_def make_cert_def nth_append) +qed +(*>*) + + +theorem jvm_lbv_correct: + "wt_jvm_prog_lbv P Cert \ wf_jvm_prog P" +(*<*) +proof - + let ?\ = "\C mn. let (C,b,Ts,T\<^sub>r,(mxs,mxl\<^sub>0,is,xt)) = method P C mn in + SOME \s. wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt \s" + + assume wt: "wt_jvm_prog_lbv P Cert" + hence "wf_jvm_prog\<^bsub>?\\<^esub> P" + apply (unfold wf_jvm_prog_phi_def wt_jvm_prog_lbv_def) + apply (erule wf_prog_lift) + apply (auto dest!: start_context.wt_lbv_wt_method [OF start_context.intro] + intro: someI) + apply (erule sees_method_is_class) + done + thus ?thesis by (unfold wf_jvm_prog_def) blast +qed +(*>*) + +theorem jvm_lbv_complete: + assumes wt: "wf_jvm_prog\<^bsub>\\<^esub> P" + shows "wt_jvm_prog_lbv P (prg_cert P \)" +(*<*) + using wt + apply (unfold wf_jvm_prog_phi_def wt_jvm_prog_lbv_def) + apply (erule wf_prog_lift) + apply (auto simp add: prg_cert_def + intro!: start_context.wt_method_wt_lbv start_context.intro) + apply (erule sees_method_is_class) + done +(*>*) + +end diff --git a/thys/JinjaDCI/BV/SemiType.thy b/thys/JinjaDCI/BV/SemiType.thy new file mode 100644 --- /dev/null +++ b/thys/JinjaDCI/BV/SemiType.thy @@ -0,0 +1,280 @@ +(* Title: Jinja/BV/SemiType.thy + + Author: Tobias Nipkow, Gerwin Klein + Copyright 2000 TUM +*) + +section \ The Jinja Type System as a Semilattice \ + +theory SemiType +imports "../Common/WellForm" Jinja.Semilattices +begin + +definition super :: "'a prog \ cname \ cname" +where "super P C \ fst (the (class P C))" + +lemma superI: + "(C,D) \ subcls1 P \ super P C = D" + by (unfold super_def) (auto dest: subcls1D) + + +primrec the_Class :: "ty \ cname" +where + "the_Class (Class C) = C" + +definition sup :: "'c prog \ ty \ ty \ ty err" +where + "sup P T\<^sub>1 T\<^sub>2 \ + if is_refT T\<^sub>1 \ is_refT T\<^sub>2 then + OK (if T\<^sub>1 = NT then T\<^sub>2 else + if T\<^sub>2 = NT then T\<^sub>1 else + (Class (exec_lub (subcls1 P) (super P) (the_Class T\<^sub>1) (the_Class T\<^sub>2)))) + else + (if T\<^sub>1 = T\<^sub>2 then OK T\<^sub>1 else Err)" + +lemma sup_def': + "sup P = (\T\<^sub>1 T\<^sub>2. + if is_refT T\<^sub>1 \ is_refT T\<^sub>2 then + OK (if T\<^sub>1 = NT then T\<^sub>2 else + if T\<^sub>2 = NT then T\<^sub>1 else + (Class (exec_lub (subcls1 P) (super P) (the_Class T\<^sub>1) (the_Class T\<^sub>2)))) + else + (if T\<^sub>1 = T\<^sub>2 then OK T\<^sub>1 else Err))" + by (simp add: sup_def fun_eq_iff) + +abbreviation + subtype :: "'c prog \ ty \ ty \ bool" + where "subtype P \ widen P" + +definition esl :: "'c prog \ ty esl" +where + "esl P \ (types P, subtype P, sup P)" + + +(* FIXME: move to wellform *) +lemma is_class_is_subcls: + "wf_prog m P \ is_class P C = P \ C \\<^sup>* Object" +(*<*)by (fastforce simp:is_class_def + elim: subcls_C_Object converse_rtranclE subcls1I + dest: subcls1D) +(*>*) + + +(* FIXME: move to wellform *) +lemma subcls_antisym: + "\wf_prog m P; P \ C \\<^sup>* D; P \ D \\<^sup>* C\ \ C = D" + (*<*) by (auto dest: acyclic_subcls1 acyclic_impl_antisym_rtrancl antisymD) (*>*) + +(* FIXME: move to wellform *) +lemma widen_antisym: + "\ wf_prog m P; P \ T \ U; P \ U \ T \ \ T = U" +(*<*) +apply (cases T) + apply (cases U) + apply auto +apply (cases U) + apply (auto elim!: subcls_antisym) +done +(*>*) + +lemma order_widen [intro,simp]: + "wf_prog m P \ order (subtype P)" +(*<*) + apply (unfold Semilat.order_def lesub_def) + apply (auto intro: widen_trans widen_antisym) + done +(*>*) + +(* FIXME: move to TypeRel *) +lemma NT_widen: + "P \ NT \ T = (T = NT \ (\C. T = Class C))" +(*<*) by (cases T) auto (*>*) + +(* FIXME: move to TypeRel *) +lemma Class_widen2: "P \ Class C \ T = (\D. T = Class D \ P \ C \\<^sup>* D)" +(*<*) by (cases T) auto (*>*) + +lemma wf_converse_subcls1_impl_acc_subtype: + "wf ((subcls1 P)^-1) \ acc (subtype P)" +(*<*) +apply (unfold Semilat.acc_def lesssub_def) +apply (drule_tac p = "(subcls1 P)^-1 - Id" in wf_subset) + apply blast +apply (drule wf_trancl) +apply (simp add: wf_eq_minimal) +apply clarify +apply (unfold lesub_def) +apply (rename_tac M T) +apply (case_tac "\C. Class C \ M") + prefer 2 + apply (case_tac T) + apply fastforce + apply fastforce + apply fastforce + apply simp + apply (rule_tac x = NT in bexI) + apply (rule allI) + apply (rule impI, erule conjE) + apply (clarsimp simp add: NT_widen) + apply simp + apply clarsimp +apply (erule_tac x = "{C. Class C : M}" in allE) +apply auto +apply (rename_tac D) +apply (rule_tac x = "Class D" in bexI) + prefer 2 + apply assumption +apply clarify +apply (clarsimp simp: Class_widen2) +apply (insert rtrancl_r_diff_Id [symmetric, of "subcls1 P"]) +apply simp +apply (erule rtranclE) + apply blast +apply (drule rtrancl_converseI) +apply (subgoal_tac "((subcls1 P)-Id)^-1 = ((subcls1 P)^-1 - Id)") + prefer 2 + apply blast +apply simp +apply (blast intro: rtrancl_into_trancl2) +done +(*>*) + +lemma wf_subtype_acc [intro, simp]: + "wf_prog wf_mb P \ acc (subtype P)" +(*<*) by (rule wf_converse_subcls1_impl_acc_subtype, rule wf_subcls1) (*>*) + +lemma exec_lub_refl [simp]: "exec_lub r f T T = T" +(*<*) by (simp add: exec_lub_def while_unfold) (*>*) + +lemma closed_err_types: + "wf_prog wf_mb P \ closed (err (types P)) (lift2 (sup P))" +(*<*) + apply (unfold closed_def plussub_def lift2_def sup_def') + apply (frule acyclic_subcls1) + apply (frule single_valued_subcls1) + apply (auto simp: is_type_def is_refT_def is_class_is_subcls split: err.split ty.splits) + apply (blast dest!: is_lub_exec_lub is_lubD is_ubD intro!: is_ubI superI) + done +(*>*) + + +lemma sup_subtype_greater: + "\ wf_prog wf_mb P; is_type P t1; is_type P t2; sup P t1 t2 = OK s \ + \ subtype P t1 s \ subtype P t2 s" +(*<*) +proof - + assume wf_prog: "wf_prog wf_mb P" + + { fix c1 c2 + assume is_class: "is_class P c1" "is_class P c2" + with wf_prog + obtain + "P \ c1 \\<^sup>* Object" + "P \ c2 \\<^sup>* Object" + by (blast intro: subcls_C_Object) + with single_valued_subcls1[OF wf_prog] + obtain u where + "is_lub ((subcls1 P)^* ) c1 c2 u" + by (blast dest: single_valued_has_lubs) + moreover + note acyclic_subcls1[OF wf_prog] + moreover + have "\x y. (x, y) \ subcls1 P \ super P x = y" + by (blast intro: superI) + ultimately + have "P \ c1 \\<^sup>* exec_lub (subcls1 P) (super P) c1 c2 \ + P \ c2 \\<^sup>* exec_lub (subcls1 P) (super P) c1 c2" + by (simp add: exec_lub_conv) (blast dest: is_lubD is_ubD) + } note this [simp] + + assume "is_type P t1" "is_type P t2" "sup P t1 t2 = OK s" + thus ?thesis + apply (unfold sup_def) + apply (cases s) + apply (auto simp add: is_refT_def split: if_split_asm) + done +qed +(*>*) + +lemma sup_subtype_smallest: + "\ wf_prog wf_mb P; is_type P a; is_type P b; is_type P c; + subtype P a c; subtype P b c; sup P a b = OK d \ + \ subtype P d c" +(*<*) +proof - + assume wf_prog: "wf_prog wf_mb P" + + { fix c1 c2 D + assume is_class: "is_class P c1" "is_class P c2" + assume le: "P \ c1 \\<^sup>* D" "P \ c2 \\<^sup>* D" + from wf_prog is_class + obtain + "P \ c1 \\<^sup>* Object" + "P \ c2 \\<^sup>* Object" + by (blast intro: subcls_C_Object) + with single_valued_subcls1[OF wf_prog] + obtain u where + lub: "is_lub ((subcls1 P)^* ) c1 c2 u" + by (blast dest: single_valued_has_lubs) + with acyclic_subcls1[OF wf_prog] + have "exec_lub (subcls1 P) (super P) c1 c2 = u" + by (blast intro: superI exec_lub_conv) + moreover + from lub le + have "P \ u \\<^sup>* D" + by (simp add: is_lub_def is_ub_def) + ultimately + have "P \ exec_lub (subcls1 P) (super P) c1 c2 \\<^sup>* D" + by blast + } note this [intro] + + have [dest!]: + "\C T. P \ Class C \ T \ \D. T=Class D \ P \ C \\<^sup>* D" + by (frule Class_widen, auto) + + assume "is_type P a" "is_type P b" "is_type P c" + "subtype P a c" "subtype P b c" "sup P a b = OK d" + thus ?thesis + by (auto simp add: sup_def is_refT_def + split: if_split_asm) +qed +(*>*) + +lemma sup_exists: + "\ subtype P a c; subtype P b c \ \ \T. sup P a b = OK T" +(*<*) +apply (unfold sup_def) +apply (cases b) +apply auto +apply (cases a) +apply auto +apply (cases a) +apply auto +done +(*>*) + +lemma err_semilat_JType_esl: + "wf_prog wf_mb P \ err_semilat (esl P)" +(*<*) +proof - + assume wf_prog: "wf_prog wf_mb P" + hence "order (subtype P)".. + moreover from wf_prog + have "closed (err (types P)) (lift2 (sup P))" + by (rule closed_err_types) + moreover + from wf_prog have + "(\x\err (types P). \y\err (types P). x \\<^bsub>Err.le (subtype P)\<^esub> x \\<^bsub>lift2 (sup P)\<^esub> y) \ + (\x\err (types P). \y\err (types P). y \\<^bsub>Err.le (subtype P)\<^esub> x \\<^bsub>lift2 (sup P)\<^esub> y)" + by (auto simp add: lesub_def plussub_def Err.le_def lift2_def sup_subtype_greater split: err.split) + moreover from wf_prog have + "\x\err (types P). \y\err (types P). \z\err (types P). + x \\<^bsub>Err.le (subtype P)\<^esub> z \ y \\<^bsub>Err.le (subtype P)\<^esub> z \ x \\<^bsub>lift2 (sup P)\<^esub> y \\<^bsub>Err.le (subtype P)\<^esub> z" + by (unfold lift2_def plussub_def lesub_def Err.le_def) + (auto intro: sup_subtype_smallest dest:sup_exists split: err.split) + ultimately show ?thesis by (simp add: esl_def semilat_def sl_def Err.sl_def) +qed +(*>*) + + +end diff --git a/thys/JinjaDCI/BV/StartProg.thy b/thys/JinjaDCI/BV/StartProg.thy new file mode 100644 --- /dev/null +++ b/thys/JinjaDCI/BV/StartProg.thy @@ -0,0 +1,228 @@ +(* Title: JinjaDCI/BV/StartProg.thy + Author: Susannah Mansky + 2019-20, UIUC +*) +section "Properties and types of the starting program" + +theory StartProg +imports ClassAdd +begin + +lemmas wt_defs = correct_state_def conf_f_def wt_instr_def eff_def norm_eff_def app_def xcpt_app_def + +declare wt_defs [simp] \ \ removed from @{text simp} at the end of file \ +declare start_class_def [simp] + +subsection "Types" + +abbreviation start_\\<^sub>m :: "ty\<^sub>m" where +"start_\\<^sub>m \ [Some([],[]),Some([Void],[])]" + +fun \_start :: "ty\<^sub>P \ ty\<^sub>P" where +"\_start \ C M = (if C=Start \ (M=start_m \ M=clinit) then start_\\<^sub>m else \ C M)" + +lemma \_start: "\C. C \ Start \ \_start \ C = \ C" + "\_start \ Start start_m = start_\\<^sub>m" "\_start \ Start clinit = start_\\<^sub>m" + by auto + +lemma check_types_\\<^sub>m: "check_types (start_prog P C M) 1 0 (map OK start_\\<^sub>m)" + by (auto simp: check_types_def JVM_states_unfold) + +(***************************************************************************************) + +subsection "Some simple properties" + +lemma preallocated_start_state: "start_state P = \ \ preallocated (fst(snd \))" +using preallocated_start[of P] by(auto simp: start_state_def split_beta) + +lemma start_prog_Start_super: "start_prog P C M \ Start \\<^sup>1 Object" + by(auto intro!: subcls1I simp: class_def fun_upd_apply) + +lemma start_prog_Start_fields: + "start_prog P C M \ Start has_fields FDTs \ map_of FDTs (F, Start) = None" + by(drule Fields.cases, auto simp: class_def fun_upd_apply Object_fields) + +lemma start_prog_Start_soconf: + "(start_prog P C M),h,Start \\<^sub>s Map.empty \" + by(simp add: soconf_def has_field_def start_prog_Start_fields) + +lemma start_prog_start_shconf: + "start_prog P C M,start_heap P \\<^sub>s start_sheap \" +(*<*) using start_prog_Start_soconf by (simp add: shconf_def fun_upd_apply) (*>*) + +(************************************) + +subsection "Well-typed and well-formed" + +lemma start_wt_method: +assumes "P \ C sees M, Static : []\Void = m in D" and "M \ clinit" and "\ is_class P Start" +shows "wt_method (start_prog P C M) Start Static [] Void 1 0 [Invokestatic C M 0, Return] [] start_\\<^sub>m" + (is "wt_method ?P ?C ?b ?Ts ?T\<^sub>r ?mxs ?mxl\<^sub>0 ?is ?xt ?\s") +proof - + let ?cdec = "(Object, [], [start_method C M, start_clinit])" + obtain mxs mxl ins xt where m: "m = (mxs,mxl,ins,xt)" by(cases m) + have ca_sees: "class_add P (Start, ?cdec) \ C sees M, Static : []\Void = m in D" + by(rule class_add_sees_method[OF assms(1,3)]) + have "\pc. pc < size ?is \ ?P,?T\<^sub>r,?mxs,size ?is,?xt \ ?is!pc,pc :: ?\s" + proof - + fix pc assume pc: "pc < size ?is" + then show "?P,?T\<^sub>r,?mxs,size ?is,?xt \ ?is!pc,pc :: ?\s" + proof(cases "pc = 0") + case True with assms m ca_sees show ?thesis + by(fastforce simp: wt_method_def wt_start_def relevant_entries_def + is_relevant_entry_def xcpt_eff_def) + next + case False with pc show ?thesis + by(simp add: wt_method_def wt_start_def relevant_entries_def + is_relevant_entry_def xcpt_eff_def) + qed + qed + with assms check_types_\\<^sub>m show ?thesis by(simp add: wt_method_def wt_start_def) +qed + +lemma start_clinit_wt_method: +assumes "P \ C sees M, Static : []\Void = m in D" and "M \ clinit" and "\ is_class P Start" +shows "wt_method (start_prog P C M) Start Static [] Void 1 0 [Push Unit,Return] [] start_\\<^sub>m" + (is "wt_method ?P ?C ?b ?Ts ?T\<^sub>r ?mxs ?mxl\<^sub>0 ?is ?xt ?\s") +proof - + let ?cdec = "(Object, [], [start_method C M, start_clinit])" + obtain mxs mxl ins xt where m: "m = (mxs,mxl,ins,xt)" by(cases m) + have ca_sees: "class_add P (Start, ?cdec) \ C sees M, Static : []\Void = m in D" + by(rule class_add_sees_method[OF assms(1,3)]) + have "\pc. pc < size ?is \ ?P,?T\<^sub>r,?mxs,size ?is,?xt \ ?is!pc,pc :: ?\s" + proof - + fix pc assume pc: "pc < size ?is" + then show "?P,?T\<^sub>r,?mxs,size ?is,?xt \ ?is!pc,pc :: ?\s" + proof(cases "pc = 0") + case True with assms m ca_sees show ?thesis + by(fastforce simp: wt_method_def wt_start_def relevant_entries_def + is_relevant_entry_def xcpt_eff_def) + next + case False with pc show ?thesis + by(simp add: wt_method_def wt_start_def relevant_entries_def + is_relevant_entry_def xcpt_eff_def) + qed + qed + with assms check_types_\\<^sub>m show ?thesis by(simp add: wt_method_def wt_start_def) +qed + +lemma start_class_wf: +assumes "P \ C sees M, Static : []\Void = m in D" + and "M \ clinit" and "\ is_class P Start" + and "\ Start start_m = start_\\<^sub>m" and "\ Start clinit = start_\\<^sub>m" + and "is_class P Object" + and "\b' Ts' T' m' D'. P \ Object sees start_m, b' : Ts'\T' = m' in D' + \ b' = Static \ Ts' = [] \ T' = Void" + and "\b' Ts' T' m' D'. P \ Object sees clinit, b' : Ts'\T' = m' in D' + \ b' = Static \ Ts' = [] \ T' = Void" +shows "wf_cdecl (\P C (M,b,Ts,T\<^sub>r,(mxs,mxl\<^sub>0,is,xt)). wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt (\ C M)) + (start_prog P C M) (start_class C M)" +proof - + from assms start_wt_method start_clinit_wt_method class_add_sees_method_rev_Obj[where P=P and C=Start] + show ?thesis + by(auto simp: start_method_def wf_cdecl_def wf_fdecl_def wf_mdecl_def + is_class_def class_def fun_upd_apply wf_clinit_def) fast+ +qed + +lemma start_prog_wf_jvm_prog_phi: +assumes wtp: "wf_jvm_prog\<^bsub>\\<^esub> P" + and nstart: "\ is_class P Start" + and meth: "P \ C sees M, Static : []\Void = m in D" and nclinit: "M \ clinit" + and \: "\C. C \ Start \ \' C = \ C" + and \': "\' Start start_m = start_\\<^sub>m" "\' Start clinit = start_\\<^sub>m" + and Obj_start_m: "\b' Ts' T' m' D'. P \ Object sees start_m, b' : Ts'\T' = m' in D' + \ b' = Static \ Ts' = [] \ T' = Void" +shows "wf_jvm_prog\<^bsub>\'\<^esub> (start_prog P C M)" +proof - + let ?wf_md = "(\P C (M,b,Ts,T\<^sub>r,(mxs,mxl\<^sub>0,is,xt)). wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt (\ C M))" + let ?wf_md' = "(\P C (M,b,Ts,T\<^sub>r,(mxs,mxl\<^sub>0,is,xt)). wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt (\' C M))" + from wtp have wf: "wf_prog ?wf_md P" by(simp add: wf_jvm_prog_phi_def) + from wf_subcls_nCls'[OF wf nstart] + have nsp: "\cd D'. cd \ set P \ \P \ fst cd \\<^sup>* Start" by simp + have wf_md': + "\C\<^sub>0 S fs ms m. (C\<^sub>0, S, fs, ms) \ set P \ m \ set ms \ ?wf_md' (start_prog P C M) C\<^sub>0 m" + proof - + fix C\<^sub>0 S fs ms m assume asms: "(C\<^sub>0, S, fs, ms) \ set P" "m \ set ms" + with nstart have ns: "C\<^sub>0 \ Start" by(auto simp: is_class_def class_def dest: weak_map_of_SomeI) + from wf asms have "?wf_md P C\<^sub>0 m" by(auto simp: wf_prog_def wf_cdecl_def wf_mdecl_def) + + with \[OF ns] class_add_wt_method[OF _ wf nstart] + show "?wf_md' (start_prog P C M) C\<^sub>0 m" by fastforce + qed + from wtp have a1: "is_class P Object" by (simp add: wf_jvm_prog_phi_def) + with wf_sees_clinit[where P=P and C=Object] wtp + have a2: "\b' Ts' T' m' D'. P \ Object sees clinit, b' : Ts'\T' = m' in D' + \ b' = Static \ Ts' = [] \ T' = Void" + by(fastforce simp: wf_jvm_prog_phi_def is_class_def dest: sees_method_fun) + from wf have dist: "distinct_fst P" by (simp add: wf_prog_def) + with class_add_distinct_fst[OF _ nstart] have "distinct_fst (start_prog P C M)" by simp + moreover from wf have "wf_syscls (start_prog P C M)" by(simp add: wf_prog_def wf_syscls_def) + moreover + from class_add_wf_cdecl'[where wf_md'="?wf_md'", OF _ _ nsp dist] wf_md' nstart wf + have "\c. c \ set P \ wf_cdecl ?wf_md' (start_prog P C M) c" by(fastforce simp: wf_prog_def) + moreover from start_class_wf[OF meth] nclinit nstart \' a1 Obj_start_m a2 + have "wf_cdecl ?wf_md' (start_prog P C M) (start_class C M)" by simp + ultimately show ?thesis by(simp add: wf_jvm_prog_phi_def wf_prog_def) +qed + +lemma start_prog_wf_jvm_prog: +assumes wf: "wf_jvm_prog P" + and nstart: "\ is_class P Start" + and meth: "P \ C sees M, Static : []\Void = m in D" and nclinit: "M \ clinit" + and Obj_start_m: "\b' Ts' T' m' D'. P \ Object sees start_m, b' : Ts'\T' = m' in D' + \ b' = Static \ Ts' = [] \ T' = Void" +shows "wf_jvm_prog (start_prog P C M)" +proof - + from wf obtain \ where wtp: "wf_jvm_prog\<^bsub>\\<^esub> P" by(clarsimp simp: wf_jvm_prog_def) + + let ?\' = "\C f. if C = Start \ (f = start_m \ f = clinit) then start_\\<^sub>m else \ C f" + + from start_prog_wf_jvm_prog_phi[OF wtp nstart meth nclinit _ _ _ Obj_start_m] have + "wf_jvm_prog\<^bsub>?\'\<^esub> (start_prog P C M)" by simp + then show ?thesis by(auto simp: wf_jvm_prog_def) +qed + +(*****************************************************************************) + +subsection "Methods and instructions" + +lemma start_prog_Start_sees_methods: + "P \ Object sees_methods Mm + \ start_prog P C M \ + Start sees_methods Mm ++ (map_option (\m. (m,Start)) \ map_of [start_method C M, start_clinit])" + by (auto simp: class_def fun_upd_apply + dest!: class_add_sees_methods_Obj[where P=P and C=Start] intro: sees_methods_rec) + +lemma start_prog_Start_sees_start_method: + "P \ Object sees_methods Mm + \ start_prog P C M \ + Start sees start_m, Static : []\Void = (1, 0, [Invokestatic C M 0,Return], []) in Start" + by(auto simp: start_method_def Method_def fun_upd_apply + dest!: start_prog_Start_sees_methods) + +lemma wf_start_prog_Start_sees_start_method: +assumes wf: "wf_prog wf_md P" +shows "start_prog P C M \ + Start sees start_m, Static : []\Void = (1, 0, [Invokestatic C M 0,Return], []) in Start" +proof - + from wf have "is_class P Object" by simp + with sees_methods_Object obtain Mm where "P \ Object sees_methods Mm" + by(fastforce simp: is_class_def dest: sees_methods_Object) + then show ?thesis by(rule start_prog_Start_sees_start_method) +qed + +lemma start_prog_start_m_instrs: +assumes wf: "wf_prog wf_md P" +shows "(instrs_of (start_prog P C M) Start start_m) = [Invokestatic C M 0, Return]" +proof - + from wf_start_prog_Start_sees_start_method[OF wf] + have "start_prog P C M \ Start sees start_m, Static : + []\Void = (1,0,[Invokestatic C M 0,Return],[]) in Start" by simp + then show ?thesis by simp +qed + +(******************************************************************) + +declare wt_defs [simp del] + +end \ No newline at end of file diff --git a/thys/JinjaDCI/BV/TF_JVM.thy b/thys/JinjaDCI/BV/TF_JVM.thy new file mode 100644 --- /dev/null +++ b/thys/JinjaDCI/BV/TF_JVM.thy @@ -0,0 +1,292 @@ +(* Title: JinjaDCI/BV/TF_JVM.thy + + Author: Tobias Nipkow, Gerwin Klein, Susannah Mansky + Copyright 2000 TUM, 2019-20 UIUC + + Based on the Jinja theory BV/TF_JVM.thy by Tobias Nipkow and Gerwin Klein +*) + +section \ The Typing Framework for the JVM \label{sec:JVM} \ + +theory TF_JVM +imports Jinja.Typing_Framework_err EffectMono BVSpec +begin + +definition exec :: "jvm_prog \ nat \ ty \ ex_table \ instr list \ ty\<^sub>i' err step_type" +where + "exec G maxs rT et bs \ + err_step (size bs) (\pc. app (bs!pc) G maxs rT pc (size bs) et) + (\pc. eff (bs!pc) G pc et)" + +locale JVM_sl = + fixes P :: jvm_prog and mxs and mxl\<^sub>0 + fixes b and Ts :: "ty list" and "is" and xt and T\<^sub>r + + fixes mxl and A and r and f and app and eff and step + defines [simp]: "mxl \ (case b of Static \ 0 | NonStatic \ 1)+size Ts+mxl\<^sub>0" + defines [simp]: "A \ states P mxs mxl" + defines [simp]: "r \ JVM_SemiType.le P mxs mxl" + defines [simp]: "f \ JVM_SemiType.sup P mxs mxl" + + defines [simp]: "app \ \pc. Effect.app (is!pc) P mxs T\<^sub>r pc (size is) xt" + defines [simp]: "eff \ \pc. Effect.eff (is!pc) P pc xt" + defines [simp]: "step \ err_step (size is) app eff" + + +locale start_context = JVM_sl + + fixes p and C + assumes wf: "wf_prog p P" + assumes C: "is_class P C" + assumes Ts: "set Ts \ types P" + + fixes first :: ty\<^sub>i' and start + defines [simp]: + "first \ Some ([],(case b of Static \ [] | NonStatic \ [OK (Class C)]) @ map OK Ts @ replicate mxl\<^sub>0 Err)" + defines [simp]: + "start \ (OK first) # replicate (size is - 1) (OK None)" + + + +subsection \ Connecting JVM and Framework \ + + +lemma (in JVM_sl) step_def_exec: "step \ exec P mxs T\<^sub>r xt is" + by (simp add: exec_def) + +lemma special_ex_swap_lemma [iff]: + "(? X. (? n. X = A n & P n) & Q X) = (? n. Q(A n) & P n)" + by blast + +lemma ex_in_list [iff]: + "(\n. ST \ list n A \ n \ mxs) = (set ST \ A \ size ST \ mxs)" + by (unfold list_def) auto + +lemma singleton_list: + "(\n. [Class C] \ list n (types P) \ n \ mxs) = (is_class P C \ 0 < mxs)" + by auto + +lemma set_drop_subset: + "set xs \ A \ set (drop n xs) \ A" + by (auto dest: in_set_dropD) + +lemma Suc_minus_minus_le: + "n < mxs \ Suc (n - (n - b)) \ mxs" + by arith + +lemma in_listE: + "\ xs \ list n A; \size xs = n; set xs \ A\ \ P \ \ P" + by (unfold list_def) blast + +declare is_relevant_entry_def [simp] +declare set_drop_subset [simp] + +theorem (in start_context) exec_pres_type: + "pres_type step (size is) A" +(*<*) + apply (insert wf) + apply simp + apply (unfold JVM_states_unfold) + apply (rule pres_type_lift) + apply clarify + apply (rename_tac s pc pc' s') + apply (case_tac s) + apply simp + apply (drule effNone) + apply simp + apply (simp add: Effect.app_def xcpt_app_def Effect.eff_def + xcpt_eff_def norm_eff_def relevant_entries_def) + apply (case_tac "is!pc") + + \ \Load\ + apply clarsimp + apply (frule listE_nth_in, assumption) + apply fastforce + + \ \Store\ + apply fastforce + + \ \Push\ + apply (fastforce simp add: typeof_lit_is_type) + + \ \New\ + apply fastforce + + \ \Getfield\ + apply (fastforce dest: sees_field_is_type) + + \ \Getstatic\ + apply (fastforce dest: sees_field_is_type) + + \ \Putfield\ + apply fastforce + + \ \Putstatic\ + apply fastforce + + \ \Checkcast\ + apply fastforce + + defer defer \ \Invoke and Invokestatic deferred\ + + \ \Return\ + apply fastforce + + \ \Pop\ + apply fastforce + + \ \IAdd\ + apply fastforce + + \ \Goto\ + apply fastforce + + \ \CmpEq\ + apply fastforce + + \ \IfFalse\ + apply fastforce + + \ \Throw\ + apply fastforce + + \ \Invoke\ + apply (clarsimp split!: if_splits) + apply fastforce + apply (erule disjE) + prefer 2 + apply fastforce + apply clarsimp + apply (rule conjI) + apply (drule (1) sees_wf_mdecl) + apply (clarsimp simp add: wf_mdecl_def) + apply arith + + \ \Invokestatic\ + apply (clarsimp split!: if_splits) + apply (erule disjE) + prefer 2 + apply fastforce + apply clarsimp + apply (drule (1) sees_wf_mdecl) + apply (clarsimp simp add: wf_mdecl_def) + done +(*>*) + +declare is_relevant_entry_def [simp del] +declare set_drop_subset [simp del] + +lemma lesubstep_type_simple: + "xs [\\<^bsub>Product.le (=) r\<^esub>] ys \ set xs {\\<^bsub>r\<^esub>} set ys" +(*<*) + apply (unfold lesubstep_type_def) + apply clarify + apply (simp add: set_conv_nth) + apply clarify + apply (drule le_listD, assumption) + apply (clarsimp simp add: lesub_def Product.le_def) + apply (rule exI) + apply (rule conjI) + apply (rule exI) + apply (rule conjI) + apply (rule sym) + apply assumption + apply assumption + apply assumption + done +(*>*) + +declare is_relevant_entry_def [simp del] + + +lemma conjI2: "\ A; A \ B \ \ A \ B" by blast + +lemma (in JVM_sl) eff_mono: + "\wf_prog p P; pc < length is; s \\<^bsub>sup_state_opt P\<^esub> t; app pc t\ + \ set (eff pc s) {\\<^bsub>sup_state_opt P\<^esub>} set (eff pc t)" +(*<*) + apply simp + apply (unfold Effect.eff_def) + apply (cases t) + apply (simp add: lesub_def) + apply (rename_tac a) + apply (cases s) + apply simp + apply (rename_tac b) + apply simp + apply (rule lesubstep_union) + prefer 2 + apply (rule lesubstep_type_simple) + apply (simp add: xcpt_eff_def) + apply (rule le_listI) + apply (simp add: split_beta) + apply (simp add: split_beta) + apply (simp add: lesub_def fun_of_def) + apply (case_tac a) + apply (case_tac b) + apply simp + apply (subgoal_tac "size ab = size aa") + prefer 2 + apply (clarsimp simp add: list_all2_lengthD) + apply simp + apply (clarsimp simp add: norm_eff_def lesubstep_type_def lesub_def iff del: sup_state_conv) + apply (rule exI) + apply (rule conjI2) + apply (rule imageI) + apply (clarsimp simp add: Effect.app_def iff del: sup_state_conv) + apply (drule (2) succs_mono) + apply blast + apply simp + apply (erule eff\<^sub>i_mono) + apply simp + apply assumption + apply clarsimp + apply clarsimp + done +(*>*) + +lemma (in JVM_sl) bounded_step: "bounded step (size is)" +(*<*) + apply simp + apply (unfold bounded_def err_step_def Effect.app_def Effect.eff_def) + apply (auto simp add: error_def map_snd_def split: err.splits option.splits) + done +(*>*) + +theorem (in JVM_sl) step_mono: + "wf_prog wf_mb P \ mono r step (size is) A" +(*<*) + apply (simp add: JVM_le_Err_conv) + apply (insert bounded_step) + apply (unfold JVM_states_unfold) + apply (rule mono_lift) + apply blast + apply (unfold app_mono_def lesub_def) + apply clarsimp + apply (erule (2) app_mono) + apply simp + apply clarify + apply (drule eff_mono) + apply (auto simp add: lesub_def) + done +(*>*) + + +lemma (in start_context) first_in_A [iff]: "OK first \ A" + using Ts C by (cases b; force intro!: list_appendI simp add: JVM_states_unfold) + + +lemma (in JVM_sl) wt_method_def2: + "wt_method P C' b Ts T\<^sub>r mxs mxl\<^sub>0 is xt \s = + (is \ [] \ + size \s = size is \ + OK ` set \s \ states P mxs mxl \ + wt_start P C' b Ts mxl\<^sub>0 \s \ + wt_app_eff (sup_state_opt P) app eff \s)" +(*<*) + apply (unfold wt_method_def wt_app_eff_def wt_instr_def lesub_def check_types_def) + apply auto + done +(*>*) + + +end diff --git a/thys/JinjaDCI/Common/Auxiliary.thy b/thys/JinjaDCI/Common/Auxiliary.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/Common/Auxiliary.thy @@ -0,0 +1,175 @@ +(* Title: JinjaDCI/Common/Auxiliary.thy + + Author: David von Oheimb, Tobias Nipkow, Susannah Mansky + Copyright 1999 TU Muenchen, 2019-20 UIUC + + Based on the Jinja theory Common/Auxiliary.thy by David von Oheimb and Tobias Nipkow +*) + +chapter \ Jinja Source Language \label{cha:j} \ + +section \ Auxiliary Definitions \ + +theory Auxiliary imports Main begin +(* FIXME move and possibly turn into a general simproc *) +lemma nat_add_max_le[simp]: + "((n::nat) + max i j \ m) = (n + i \ m \ n + j \ m)" + (*<*)by arith(*>*) + +lemma Suc_add_max_le[simp]: + "(Suc(n + max i j) \ m) = (Suc(n + i) \ m \ Suc(n + j) \ m)" +(*<*)by arith(*>*) + + +notation Some ("(\_\)") + +(*<*) +declare + option.splits[split] + Let_def[simp] + subset_insertI2 [simp] + Cons_eq_map_conv [iff] +(*>*) + + +subsection \@{text distinct_fst}\ + +definition distinct_fst :: "('a \ 'b) list \ bool" +where + "distinct_fst \ distinct \ map fst" + +lemma distinct_fst_Nil [simp]: + "distinct_fst []" + (*<*) +by (unfold distinct_fst_def) (simp (no_asm)) +(*>*) + +lemma distinct_fst_Cons [simp]: + "distinct_fst ((k,x)#kxs) = (distinct_fst kxs \ (\y. (k,y) \ set kxs))" +(*<*) +by (unfold distinct_fst_def) (auto simp:image_def) +(*>*) + +lemma distinct_fst_appendD: + "distinct_fst(kxs @ kxs') \ distinct_fst kxs \ distinct_fst kxs'" +(*<*)by(induct kxs, auto)(*>*) + +lemma map_of_SomeI: + "\ distinct_fst kxs; (k,x) \ set kxs \ \ map_of kxs k = Some x" +(*<*)by (induct kxs) (auto simp:fun_upd_apply)(*>*) + + +subsection \ Using @{term list_all2} for relations \ + +definition fun_of :: "('a \ 'b) set \ 'a \ 'b \ bool" +where + "fun_of S \ \x y. (x,y) \ S" + +text \ Convenience lemmas \ +(*<*) +declare fun_of_def [simp] +(*>*) +lemma rel_list_all2_Cons [iff]: + "list_all2 (fun_of S) (x#xs) (y#ys) = + ((x,y) \ S \ list_all2 (fun_of S) xs ys)" + (*<*)by simp(*>*) + +lemma rel_list_all2_Cons1: + "list_all2 (fun_of S) (x#xs) ys = + (\z zs. ys = z#zs \ (x,z) \ S \ list_all2 (fun_of S) xs zs)" + (*<*)by (cases ys) auto(*>*) + +lemma rel_list_all2_Cons2: + "list_all2 (fun_of S) xs (y#ys) = + (\z zs. xs = z#zs \ (z,y) \ S \ list_all2 (fun_of S) zs ys)" + (*<*)by (cases xs) auto(*>*) + +lemma rel_list_all2_refl: + "(\x. (x,x) \ S) \ list_all2 (fun_of S) xs xs" + (*<*)by (simp add: list_all2_refl)(*>*) + +lemma rel_list_all2_antisym: + "\ (\x y. \(x,y) \ S; (y,x) \ T\ \ x = y); + list_all2 (fun_of S) xs ys; list_all2 (fun_of T) ys xs \ \ xs = ys" + (*<*)by (rule list_all2_antisym) auto(*>*) + +lemma rel_list_all2_trans: + "\ \a b c. \(a,b) \ R; (b,c) \ S\ \ (a,c) \ T; + list_all2 (fun_of R) as bs; list_all2 (fun_of S) bs cs\ + \ list_all2 (fun_of T) as cs" + (*<*)by (rule list_all2_trans) auto(*>*) + +lemma rel_list_all2_update_cong: + "\ i S \ + \ list_all2 (fun_of S) (xs[i:=x]) (ys[i:=y])" + (*<*)by (simp add: list_all2_update_cong)(*>*) + +lemma rel_list_all2_nthD: + "\ list_all2 (fun_of S) xs ys; p < size xs \ \ (xs!p,ys!p) \ S" + (*<*)by (drule list_all2_nthD) auto(*>*) + +lemma rel_list_all2I: + "\ length a = length b; \n. n < length a \ (a!n,b!n) \ S \ \ list_all2 (fun_of S) a b" + (*<*)by (erule list_all2_all_nthI) simp(*>*) + +(*<*)declare fun_of_def [simp del](*>*) + +subsection \ Auxiliary properties of @{text "map_of"} function \ + +lemma map_of_set_pcs_notin: "C \ (\t. snd (fst t)) ` set FDTs \ map_of FDTs (F, C) = None" +(*<*)by (metis image_eqI image_image map_of_eq_None_iff snd_conv)(*>*) + +lemma map_of_insertmap_SomeD': + "map_of fs F = Some y \ map_of (map (\(F, y). (F, D, y)) fs) F = Some(D,y)" +(*<*)by (induct fs) (auto simp:fun_upd_apply split: if_split_asm)(*>*) + +lemma map_of_reinsert_neq_None: + "Ca \ D \ map_of (map (\(F, y). ((F, Ca), y)) fs) (F, D) = None" +(*<*)by (induct fs) (auto simp:fun_upd_apply split: if_split_asm)(*>*) + +lemma map_of_remap_insertmap: + "map_of (map ((\((F, D), b, T). (F, D, b, T)) \ (\(F, y). ((F, D), y))) fs) + = map_of (map (\(F, y). (F, D, y)) fs)" +(*<*)by (induct fs) (auto simp:fun_upd_apply split: if_split_asm)(*>*) + + +lemma map_of_reinsert_SomeD: + "map_of (map (\(F, y). ((F, D), y)) fs) (F, D) = Some T \ map_of fs F = Some T" +(*<*)by (induct fs) (auto simp:fun_upd_apply split: if_split_asm)(*>*) + +lemma map_of_filtered_SomeD: +"map_of fs (F,D) = Some (a, T) \ Q ((F,D),a,T) \ + map_of (map (\((F,D), b, T). ((F,D), P T)) (filter Q fs)) + (F,D) = Some (P T)" +(*<*)by (induct fs) (auto simp:fun_upd_apply split: if_split_asm)(*>*) + + +lemma map_of_remove_filtered_SomeD: +"map_of fs (F,C) = Some (a, T) \ Q ((F,C),a,T) \ + map_of (map (\((F,D), b, T). (F, P T)) [((F, D), b, T)\fs . Q ((F, D), b, T) \ D = C]) + F = Some (P T)" +(*<*)by (induct fs) (auto simp:fun_upd_apply split: if_split_asm)(*>*) + + +lemma map_of_Some_None_split: +assumes "t = map (\(F, y). ((F, C), y)) fs @ t'" "map_of t' (F, C) = None" "map_of t (F, C) = Some y" +shows "map_of (map (\((F, D), b, T). (F, D, b, T)) t) F = Some (C, y)" +(*<*) +proof - + have "map_of (map (\(F, y). ((F, C), y)) fs) (F, C) = Some y" using assms by auto + then have "\p. map_of fs F = Some p \ Some y \ Some p" + by (metis map_of_reinsert_SomeD) + then have "\f b p pa. ((f ++ map_of (map (\(a, p). (a, b::'b, p)) fs)) F = Some p \ Some (b, pa) \ Some p) + \ Some y \ Some pa" + by (metis (no_types) map_add_find_right map_of_insertmap_SomeD') + then have "(map_of (map (\((a, b), c, d). (a, b, c, d)) t') + ++ map_of (map (\(a, p). (a, C, p)) fs)) F = Some (C, y)" + by blast + then have "(map_of (map (\((a, b), c, d). (a, b, c, d)) t') + ++ map_of (map ((\((a, b), c, d). (a, b, c, d)) \ (\(a, y). ((a, C), y))) fs)) F = Some (C, y)" + by (simp add: map_of_remap_insertmap) + then show ?thesis using assms by auto +qed +(*>*) + +end diff --git a/thys/JinjaDCI/Common/Conform.thy b/thys/JinjaDCI/Common/Conform.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/Common/Conform.thy @@ -0,0 +1,218 @@ +(* Title: JinjaDCI/Common/Conform.thy + + Author: David von Oheimb, Tobias Nipkow, Susannah Mansky + Copyright 1999 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory Common/Conform.thy by David von Oheimb and Tobias Nipkow +*) + +section \ Conformance Relations for Type Soundness Proofs \ + +theory Conform +imports Exceptions +begin + +definition conf :: "'m prog \ heap \ val \ ty \ bool" ("_,_ \ _ :\ _" [51,51,51,51] 50) +where + "P,h \ v :\ T \ + \T'. typeof\<^bsub>h\<^esub> v = Some T' \ P \ T' \ T" + +definition oconf :: "'m prog \ heap \ obj \ bool" ("_,_ \ _ \" [51,51,51] 50) +where + "P,h \ obj \ \ + let (C,fs) = obj in \F D T. P \ C has F,NonStatic:T in D \ + (\v. fs(F,D) = Some v \ P,h \ v :\ T)" + +definition soconf :: "'m prog \ heap \ cname \ sfields \ bool" ("_,_,_ \\<^sub>s _ \" [51,51,51,51] 50) +where + "P,h,C \\<^sub>s sfs \ \ + \F T. P \ C has F,Static:T in C \ + (\v. sfs F = Some v \ P,h \ v :\ T)" + +definition hconf :: "'m prog \ heap \ bool" ("_ \ _ \" [51,51] 50) +where + "P \ h \ \ + (\a obj. h a = Some obj \ P,h \ obj \) \ preallocated h" + +definition shconf :: "'m prog \ heap \ sheap \ bool" ("_,_ \\<^sub>s _ \" [51,51,51] 50) +where + "P,h \\<^sub>s sh \ \ + (\C sfs i. sh C = Some(sfs,i) \ P,h,C \\<^sub>s sfs \)" + +definition lconf :: "'m prog \ heap \ (vname \ val) \ (vname \ ty) \ bool" ("_,_ \ _ '(:\') _" [51,51,51,51] 50) +where + "P,h \ l (:\) E \ + \V v. l V = Some v \ (\T. E V = Some T \ P,h \ v :\ T)" + +abbreviation + confs :: "'m prog \ heap \ val list \ ty list \ bool" + ("_,_ \ _ [:\] _" [51,51,51,51] 50) where + "P,h \ vs [:\] Ts \ list_all2 (conf P h) vs Ts" + + +subsection\ Value conformance @{text":\"} \ + +lemma conf_Null [simp]: "P,h \ Null :\ T = P \ NT \ T" +(*<*)by (simp (no_asm) add: conf_def)(*>*) + +lemma typeof_conf[simp]: "typeof\<^bsub>h\<^esub> v = Some T \ P,h \ v :\ T" +(*<*)by (induct v) (auto simp: conf_def)(*>*) + +lemma typeof_lit_conf[simp]: "typeof v = Some T \ P,h \ v :\ T" +(*<*)by (rule typeof_conf[OF typeof_lit_typeof])(*>*) + +lemma defval_conf[simp]: "P,h \ default_val T :\ T" +(*<*)by (cases T) (auto simp: conf_def)(*>*) + +lemma conf_upd_obj: "h a = Some(C,fs) \ (P,h(a\(C,fs')) \ x :\ T) = (P,h \ x :\ T)" +(*<*)by (rule val.induct) (auto simp:conf_def fun_upd_apply)(*>*) + +lemma conf_widen: "P,h \ v :\ T \ P \ T \ T' \ P,h \ v :\ T'" +(*<*)by (induct v) (auto intro: widen_trans simp: conf_def)(*>*) + +lemma conf_hext: "h \ h' \ P,h \ v :\ T \ P,h' \ v :\ T" +(*<*)by (induct v) (auto dest: hext_objD simp: conf_def)(*>*) + +lemma conf_ClassD: "P,h \ v :\ Class C \ + v = Null \ (\a obj T. v = Addr a \ h a = Some obj \ obj_ty obj = T \ P \ T \ Class C)" +(*<*)by(induct v) (auto simp: conf_def)(*>*) + +lemma conf_NT [iff]: "P,h \ v :\ NT = (v = Null)" +(*<*)by (auto simp add: conf_def)(*>*) + +lemma non_npD: "\ v \ Null; P,h \ v :\ Class C \ + \ \a C' fs. v = Addr a \ h a = Some(C',fs) \ P \ C' \\<^sup>* C" +(*<*)by (auto dest: conf_ClassD)(*>*) + + +subsection\ Value list conformance @{text"[:\]"} \ + +lemma confs_widens [trans]: "\P,h \ vs [:\] Ts; P \ Ts [\] Ts'\ \ P,h \ vs [:\] Ts'" +(*<*)by(auto intro: list_all2_trans conf_widen)(*>*) + +lemma confs_rev: "P,h \ rev s [:\] t = (P,h \ s [:\] rev t)" +(*<*)by (simp add: list_all2_rev1)(*>*) + +lemma confs_conv_map: + "\Ts'. P,h \ vs [:\] Ts' = (\Ts. map typeof\<^bsub>h\<^esub> vs = map Some Ts \ P \ Ts [\] Ts')" +(*<*) +proof(induct vs) + case (Cons a vs) + then show ?case by(case_tac Ts') (auto simp add:conf_def) +qed simp +(*>*) + +lemma confs_hext: "P,h \ vs [:\] Ts \ h \ h' \ P,h' \ vs [:\] Ts" +(*<*)by (erule list_all2_mono, erule conf_hext, assumption)(*>*) + +lemma confs_Cons2: "P,h \ xs [:\] y#ys = (\z zs. xs = z#zs \ P,h \ z :\ y \ P,h \ zs [:\] ys)" +(*<*)by (rule list_all2_Cons2)(*>*) + + +subsection "Object conformance" + +lemma oconf_hext: "P,h \ obj \ \ h \ h' \ P,h' \ obj \" +(*<*)by (fastforce elim:conf_hext simp: oconf_def)(*>*) + +lemma oconf_blank: + "P \ C has_fields FDTs \ P,h \ blank P C \" +(*<*) +by(fastforce dest: has_fields_fun + simp: has_field_def oconf_def blank_def init_fields_def + map_of_filtered_SomeD) +(*>*) + +lemma oconf_fupd [intro?]: + "\ P \ C has F,NonStatic:T in D; P,h \ v :\ T; P,h \ (C,fs) \ \ + \ P,h \ (C, fs((F,D)\v)) \" +(*<*)by (auto dest: has_fields_fun simp add: oconf_def has_field_def fun_upd_apply)(*>*) + +(*<*) +lemmas oconf_new = oconf_hext [OF _ hext_new] +lemmas oconf_upd_obj = oconf_hext [OF _ hext_upd_obj] +(*>*) + +subsection "Static object conformance" + +lemma soconf_hext: "P,h,C \\<^sub>s obj \ \ h \ h' \ P,h',C \\<^sub>s obj \" +(*<*)by (fastforce elim:conf_hext simp:soconf_def)(*>*) + +lemma soconf_sblank: + "P \ C has_fields FDTs \ P,h,C \\<^sub>s sblank P C \" +(*<*) +proof - + let ?sfs = "sblank P C" + assume FDTs: "P \ C has_fields FDTs" + then have "\F T. P \ C has F,Static:T in C + \ \v. ?sfs F = Some v \ P,h \ v :\ T" + proof - + fix F T assume has: "P \ C has F,Static:T in C" + with has_fields_fun[OF FDTs] have map: "map_of FDTs (F, C) = \(Static, T)\" + by(clarsimp simp: has_field_def) + then have "map_of (map (\((F, D), b, T). (F, default_val T)) + (filter (\((F, D), b, T). (case ((F, D), b, T) of (x, xa) + \ (case x of (F, D) \ \(b, T). b = Static) xa) \ D = C) FDTs)) F + = \default_val T\" + by(rule map_of_remove_filtered_SomeD[where P = "default_val" + and Q = "\((F, D), b, T). b = Static"]) simp + with FDTs show "\v. ?sfs F = Some v \ P,h \ v :\ T" + by(clarsimp simp: sblank_def init_sfields_def) + qed + then show ?thesis by(simp add: soconf_def) +qed +(*>*) + +lemma soconf_fupd [intro?]: + "\ P \ C has F,Static:T in C; P,h \ v :\ T; P,h,C \\<^sub>s sfs \ \ + \ P,h,C \\<^sub>s sfs(F\v) \" +(*<*)by (auto dest: has_fields_fun simp add: fun_upd_apply soconf_def has_field_def)(*>*) + +(*<*) +lemmas soconf_new = soconf_hext [OF _ hext_new] +lemmas soconf_upd_obj = soconf_hext [OF _ hext_upd_obj] +(*>*) + +subsection "Heap conformance" + +lemma hconfD: "\ P \ h \; h a = Some obj \ \ P,h \ obj \" +(*<*)by (unfold hconf_def) fast(*>*) + +lemma hconf_new: "\ P \ h \; h a = None; P,h \ obj \ \ \ P \ h(a\obj) \" +(*<*)by (unfold hconf_def) (auto intro: oconf_new preallocated_new)(*>*) + +lemma hconf_upd_obj: "\ P \ h\; h a = Some(C,fs); P,h \ (C,fs')\ \ \ P \ h(a\(C,fs'))\" +(*<*)by (unfold hconf_def) (auto intro: oconf_upd_obj preallocated_upd_obj)(*>*) + + +subsection "Class statics conformance" + +lemma shconfD: "\ P,h \\<^sub>s sh \; sh C = Some(sfs,i) \ \ P,h,C \\<^sub>s sfs \" +(*<*)by (unfold shconf_def) fast(*>*) + +lemma shconf_upd_obj: "\ P,h \\<^sub>s sh \; P,h,C \\<^sub>s sfs' \ \ + \ P,h \\<^sub>s sh(C\(sfs',i'))\" +(*<*)by (unfold shconf_def) (auto intro: soconf_upd_obj preallocated_upd_obj)(*>*) + +lemma shconf_hnew: "\ P,h \\<^sub>s sh \; h a = None \ \ P,h(a\obj) \\<^sub>s sh \" +(*<*)by (unfold shconf_def) (auto intro: soconf_new preallocated_new)(*>*) + +lemma shconf_hupd_obj: "\ P,h \\<^sub>s sh \; h a = Some(C,fs) \ \ P,h(a\(C,fs')) \\<^sub>s sh \" +(*<*)by (unfold shconf_def) (auto intro: soconf_upd_obj preallocated_upd_obj)(*>*) + +subsection "Local variable conformance" + +lemma lconf_hext: "\ P,h \ l (:\) E; h \ h' \ \ P,h' \ l (:\) E" +(*<*)by (unfold lconf_def) (fast elim: conf_hext)(*>*) + +lemma lconf_upd: + "\ P,h \ l (:\) E; P,h \ v :\ T; E V = Some T \ \ P,h \ l(V\v) (:\) E" +(*<*)by (unfold lconf_def) auto(*>*) + +lemma lconf_empty[iff]: "P,h \ Map.empty (:\) E" +(*<*)by(simp add:lconf_def)(*>*) + +lemma lconf_upd2: "\P,h \ l (:\) E; P,h \ v :\ T\ \ P,h \ l(V\v) (:\) E(V\T)" +(*<*)by(simp add:lconf_def)(*>*) + + +end diff --git a/thys/JinjaDCI/Common/Decl.thy b/thys/JinjaDCI/Common/Decl.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/Common/Decl.thy @@ -0,0 +1,85 @@ +(* Title: JinjaDCI/Common/Decl.thy + + Author: David von Oheimb, Susannah Mansky + Copyright 1999 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory Common/Decl.thy by David von Oheimb +*) + +section \ Class Declarations and Programs \ + +theory Decl imports Type begin + +type_synonym + fdecl = "vname \ staticb \ ty" \ \field declaration\ +type_synonym + 'm mdecl = "mname \ staticb \ ty list \ ty \ 'm" \ \method = name, static flag, arg.\ types, return type, body\ +type_synonym + 'm "class" = "cname \ fdecl list \ 'm mdecl list" \ \class = superclass, fields, methods\ +type_synonym + 'm cdecl = "cname \ 'm class" \ \class declaration\ +type_synonym + 'm prog = "'m cdecl list" \ \program\ + +(* replaced all fname, mname, cname in below with `char list' so that + pretty printing works -SM *) +(*<*) +translations + (type) "fdecl" <= (type) "char list \ staticb \ ty" + (type) "'c mdecl" <= (type) "char list \ staticb \ ty list \ ty \ 'c" + (type) "'c class" <= (type) "char list \ fdecl list \ ('c mdecl) list" + (type) "'c cdecl" <= (type) "char list \ ('c class)" + (type) "'c prog" <= (type) "('c cdecl) list" +(*>*) + +definition "class" :: "'m prog \ cname \ 'm class" +where + "class \ map_of" + +(* Not difficult to prove, but useful for directing particular sequences of equality -SM *) +lemma class_cons: "\ C \ fst x \ \ class (x # P) C = class P C" + by (simp add: class_def) + +definition is_class :: "'m prog \ cname \ bool" +where + "is_class P C \ class P C \ None" + +lemma finite_is_class: "finite {C. is_class P C}" +(*<*) +proof - + have "{C. is_class P C} = dom (map_of P)" + by (simp add: is_class_def class_def dom_def) + thus ?thesis by (simp add: finite_dom_map_of) +qed +(*>*) + +definition is_type :: "'m prog \ ty \ bool" +where + "is_type P T \ + (case T of Void \ True | Boolean \ True | Integer \ True | NT \ True + | Class C \ is_class P C)" + +lemma is_type_simps [simp]: + "is_type P Void \ is_type P Boolean \ is_type P Integer \ + is_type P NT \ is_type P (Class C) = is_class P C" +(*<*)by(simp add:is_type_def)(*>*) + + +abbreviation + "types P == Collect (is_type P)" + +lemma class_exists_equiv: + "(\x. fst x = cn \ x \ set P) = (class P cn \ None)" +proof(rule iffI) + assume "\x. fst x = cn \ x \ set P" then show "class P cn \ None" + by (metis class_def image_eqI map_of_eq_None_iff) +next + assume "class P cn \ None" then show "\x. fst x = cn \ x \ set P" + by (metis class_def fst_conv map_of_SomeD option.exhaust) +qed + +lemma class_exists_equiv2: + "(\x. fst x = cn \ x \ set (P1 @ P2)) = (class P1 cn \ None \ class P2 cn \ None)" +by (simp only: class_exists_equiv [where P = "P1@P2"], simp add: class_def) + +end diff --git a/thys/JinjaDCI/Common/Exceptions.thy b/thys/JinjaDCI/Common/Exceptions.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/Common/Exceptions.thy @@ -0,0 +1,188 @@ +(* Title: JinjaDCI/Common/Exceptions.thy + + Author: Gerwin Klein, Martin Strecker, Susannah Mansky + Copyright 2002 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory Common/Exceptions.thy by Gerwin Klein and Martin Strecker +*) + +section \ Exceptions \ + +theory Exceptions imports Objects begin + +definition ErrorCl :: "string" where "ErrorCl = ''Error''" +definition ThrowCl :: "string" where "ThrowCl = ''Throwable''" + +definition NullPointer :: cname +where + "NullPointer \ ''NullPointer''" + +definition ClassCast :: cname +where + "ClassCast \ ''ClassCast''" + +definition OutOfMemory :: cname +where + "OutOfMemory \ ''OutOfMemory''" + +definition NoClassDefFoundError :: cname +where + "NoClassDefFoundError \ ''NoClassDefFoundError''" + +definition IncompatibleClassChangeError :: cname +where + "IncompatibleClassChangeError \ ''IncompatibleClassChangeError''" + +definition NoSuchFieldError :: cname +where + "NoSuchFieldError \ ''NoSuchFieldError''" + +definition NoSuchMethodError :: cname +where + "NoSuchMethodError \ ''NoSuchMethodError''" + +definition sys_xcpts :: "cname set" +where + "sys_xcpts \ {NullPointer, ClassCast, OutOfMemory, NoClassDefFoundError, + IncompatibleClassChangeError, + NoSuchFieldError, NoSuchMethodError}" + +definition addr_of_sys_xcpt :: "cname \ addr" +where + "addr_of_sys_xcpt s \ if s = NullPointer then 0 else + if s = ClassCast then 1 else + if s = OutOfMemory then 2 else + if s = NoClassDefFoundError then 3 else + if s = IncompatibleClassChangeError then 4 else + if s = NoSuchFieldError then 5 else + if s = NoSuchMethodError then 6 else undefined" + + +lemmas sys_xcpts_defs = NullPointer_def ClassCast_def OutOfMemory_def NoClassDefFoundError_def + IncompatibleClassChangeError_def NoSuchFieldError_def NoSuchMethodError_def + +lemma Start_nsys_xcpts: "Start \ sys_xcpts" + by(simp add: Start_def sys_xcpts_def sys_xcpts_defs) + +lemma Start_nsys_xcpts1 [simp]: "Start \ NullPointer" "Start \ ClassCast" + "Start \ OutOfMemory" "Start \ NoClassDefFoundError" + "Start \ IncompatibleClassChangeError" "Start \ NoSuchFieldError" + "Start \ NoSuchMethodError" +using Start_nsys_xcpts by(auto simp: sys_xcpts_def) + +lemma Start_nsys_xcpts2 [simp]: "NullPointer \ Start" "ClassCast \ Start" + "OutOfMemory \ Start" "NoClassDefFoundError \ Start" + "IncompatibleClassChangeError \ Start" "NoSuchFieldError \ Start" + "NoSuchMethodError \ Start" +using Start_nsys_xcpts by(auto simp: sys_xcpts_def dest: sym) + +definition start_heap :: "'c prog \ heap" +where + "start_heap G \ Map.empty (addr_of_sys_xcpt NullPointer \ blank G NullPointer) + (addr_of_sys_xcpt ClassCast \ blank G ClassCast) + (addr_of_sys_xcpt OutOfMemory \ blank G OutOfMemory) + (addr_of_sys_xcpt NoClassDefFoundError \ blank G NoClassDefFoundError) + (addr_of_sys_xcpt IncompatibleClassChangeError \ blank G IncompatibleClassChangeError) + (addr_of_sys_xcpt NoSuchFieldError \ blank G NoSuchFieldError) + (addr_of_sys_xcpt NoSuchMethodError \ blank G NoSuchMethodError)" + +definition preallocated :: "heap \ bool" +where + "preallocated h \ \C \ sys_xcpts. \fs. h(addr_of_sys_xcpt C) = Some (C,fs)" + +subsection "System exceptions" + +lemma sys_xcpts_incl [simp]: "NullPointer \ sys_xcpts \ OutOfMemory \ sys_xcpts + \ ClassCast \ sys_xcpts \ NoClassDefFoundError \ sys_xcpts + \ IncompatibleClassChangeError \ sys_xcpts \ NoSuchFieldError \ sys_xcpts + \ NoSuchMethodError \ sys_xcpts" +(*<*)by(simp add: sys_xcpts_def)(*>*) + +lemma sys_xcpts_cases [consumes 1, cases set]: + "\ C \ sys_xcpts; P NullPointer; P OutOfMemory; P ClassCast; P NoClassDefFoundError; + P IncompatibleClassChangeError; P NoSuchFieldError; + P NoSuchMethodError \ \ P C" +(*<*)by (auto simp: sys_xcpts_def)(*>*) + +subsection "Starting heap" + +lemma start_heap_sys_xcpts: +assumes "C \ sys_xcpts" +shows "start_heap P (addr_of_sys_xcpt C) = Some(blank P C)" +by(rule sys_xcpts_cases[OF assms]) + (auto simp add: start_heap_def sys_xcpts_def addr_of_sys_xcpt_def sys_xcpts_defs) + +lemma start_heap_classes: + "start_heap P a = Some(C,fs) \ C \ sys_xcpts" + by(simp add: start_heap_def blank_def split: if_split_asm) + +lemma start_heap_nStart: "start_heap P a = Some obj \ fst(obj) \ Start" + by(cases obj, auto dest!: start_heap_classes simp: Start_nsys_xcpts) + +subsection "@{term preallocated}" + +lemma preallocated_dom [simp]: + "\ preallocated h; C \ sys_xcpts \ \ addr_of_sys_xcpt C \ dom h" +(*<*)by (fastforce simp:preallocated_def dom_def)(*>*) + + +lemma preallocatedD: + "\ preallocated h; C \ sys_xcpts \ \ \fs. h(addr_of_sys_xcpt C) = Some (C, fs)" +(*<*)by(auto simp: preallocated_def sys_xcpts_def)(*>*) + + +lemma preallocatedE [elim?]: + "\ preallocated h; C \ sys_xcpts; \fs. h(addr_of_sys_xcpt C) = Some(C,fs) \ P h C\ + \ P h C" +(*<*)by (fast dest: preallocatedD)(*>*) + + +lemma cname_of_xcp [simp]: + "\ preallocated h; C \ sys_xcpts \ \ cname_of h (addr_of_sys_xcpt C) = C" +(*<*)by (auto elim: preallocatedE)(*>*) + + +lemma typeof_ClassCast [simp]: + "preallocated h \ typeof\<^bsub>h\<^esub> (Addr(addr_of_sys_xcpt ClassCast)) = Some(Class ClassCast)" +(*<*)by (auto elim: preallocatedE)(*>*) + + +lemma typeof_OutOfMemory [simp]: + "preallocated h \ typeof\<^bsub>h\<^esub> (Addr(addr_of_sys_xcpt OutOfMemory)) = Some(Class OutOfMemory)" +(*<*)by (auto elim: preallocatedE)(*>*) + + +lemma typeof_NullPointer [simp]: + "preallocated h \ typeof\<^bsub>h\<^esub> (Addr(addr_of_sys_xcpt NullPointer)) = Some(Class NullPointer)" +(*<*)by (auto elim: preallocatedE)(*>*) + +lemma typeof_NoClassDefFoundError [simp]: + "preallocated h \ typeof\<^bsub>h\<^esub> (Addr(addr_of_sys_xcpt NoClassDefFoundError)) = Some(Class NoClassDefFoundError)" +(*<*)by (auto elim: preallocatedE)(*>*) + +lemma typeof_IncompatibleClassChangeError [simp]: + "preallocated h \ typeof\<^bsub>h\<^esub> (Addr(addr_of_sys_xcpt IncompatibleClassChangeError)) = Some(Class IncompatibleClassChangeError)" +(*<*)by (auto elim: preallocatedE)(*>*) + +lemma typeof_NoSuchFieldError [simp]: + "preallocated h \ typeof\<^bsub>h\<^esub> (Addr(addr_of_sys_xcpt NoSuchFieldError)) = Some(Class NoSuchFieldError)" +(*<*)by (auto elim: preallocatedE)(*>*) + +lemma typeof_NoSuchMethodError [simp]: + "preallocated h \ typeof\<^bsub>h\<^esub> (Addr(addr_of_sys_xcpt NoSuchMethodError)) = Some(Class NoSuchMethodError)" +(*<*)by (auto elim: preallocatedE)(*>*) + +lemma preallocated_hext: + "\ preallocated h; h \ h' \ \ preallocated h'" +(*<*)by (simp add: preallocated_def hext_def)(*>*) + +(*<*) +lemmas preallocated_upd_obj = preallocated_hext [OF _ hext_upd_obj] +lemmas preallocated_new = preallocated_hext [OF _ hext_new] +(*>*) + +lemma preallocated_start: + "preallocated (start_heap P)" + by(auto simp: start_heap_sys_xcpts blank_def preallocated_def) + +end diff --git a/thys/JinjaDCI/Common/Objects.thy b/thys/JinjaDCI/Common/Objects.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/Common/Objects.thy @@ -0,0 +1,211 @@ +(* Title: JinjaDCI/Common/Objects.thy + + Author: David von Oheimb, Susannah Mansky + Copyright 1999 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory Common/Objects.thy by David von Oheimb +*) + +section \ Objects and the Heap \ + +theory Objects imports TypeRel Value begin + +subsection\ Objects \ + +type_synonym + fields = "vname \ cname \ val" \ \field name, defining class, value\ +type_synonym + obj = "cname \ fields" \ \class instance with class name and fields\ +type_synonym + sfields = "vname \ val" \ \field name to value\ + +definition obj_ty :: "obj \ ty" +where + "obj_ty obj \ Class (fst obj)" + + \ \ initializes a given list of fields \ +definition init_fields :: "((vname \ cname) \ staticb \ ty) list \ fields" +where + "init_fields FDTs \ (map_of \ map (\((F,D),b,T). ((F,D),default_val T))) FDTs" + +definition init_sfields :: "((vname \ cname) \ staticb \ ty) list \ sfields" +where + "init_sfields FDTs \ (map_of \ map (\((F,D),b,T). (F,default_val T))) FDTs" + + \ \a new, blank object with default values for instance fields:\ +definition blank :: "'m prog \ cname \ obj" +where + "blank P C \ (C,init_fields (ifields P C))" + + \ \a new, blank object with default values for static fields:\ +definition sblank :: "'m prog \ cname \ sfields" +where + "sblank P C \ init_sfields (isfields P C)" + +lemma [simp]: "obj_ty (C,fs) = Class C" +(*<*)by (simp add: obj_ty_def)(*>*) + +(* replaced all vname, cname in below with `char list' and \ with returned option + so that pretty printing works -SM *) +translations + (type) "fields" <= (type) "char list \ char list \ val option" + (type) "obj" <= (type) "char list \ fields" + (type) "sfields" <= (type) "char list \ val option" + +subsection\ Heap \ + +type_synonym heap = "addr \ obj" + +(* replaced addr with nat and \ with returned option so that pretty printing works -SM *) +translations + (type) "heap" <= (type) "nat \ obj option" + +abbreviation + cname_of :: "heap \ addr \ cname" where + "cname_of hp a == fst (the (hp a))" + +definition new_Addr :: "heap \ addr option" +where + "new_Addr h \ if \a. h a = None then Some(LEAST a. h a = None) else None" + +definition cast_ok :: "'m prog \ cname \ heap \ val \ bool" +where + "cast_ok P C h v \ v = Null \ P \ cname_of h (the_Addr v) \\<^sup>* C" + +definition hext :: "heap \ heap \ bool" ("_ \ _" [51,51] 50) +where + "h \ h' \ \a C fs. h a = Some(C,fs) \ (\fs'. h' a = Some(C,fs'))" + +primrec typeof_h :: "heap \ val \ ty option" ("typeof\<^bsub>_\<^esub>") +where + "typeof\<^bsub>h\<^esub> Unit = Some Void" +| "typeof\<^bsub>h\<^esub> Null = Some NT" +| "typeof\<^bsub>h\<^esub> (Bool b) = Some Boolean" +| "typeof\<^bsub>h\<^esub> (Intg i) = Some Integer" +| "typeof\<^bsub>h\<^esub> (Addr a) = (case h a of None \ None | Some(C,fs) \ Some(Class C))" + +lemma new_Addr_SomeD: + "new_Addr h = Some a \ h a = None" + (*<*)by(fastforce simp: new_Addr_def split:if_splits intro:LeastI)(*>*) + +lemma [simp]: "(typeof\<^bsub>h\<^esub> v = Some Boolean) = (\b. v = Bool b)" + (*<*)by(induct v) auto(*>*) + +lemma [simp]: "(typeof\<^bsub>h\<^esub> v = Some Integer) = (\i. v = Intg i)" +(*<*)by(cases v) auto(*>*) + +lemma [simp]: "(typeof\<^bsub>h\<^esub> v = Some NT) = (v = Null)" + (*<*)by(cases v) auto(*>*) + +lemma [simp]: "(typeof\<^bsub>h\<^esub> v = Some(Class C)) = (\a fs. v = Addr a \ h a = Some(C,fs))" + (*<*)by(cases v) auto(*>*) + +lemma [simp]: "h a = Some(C,fs) \ typeof\<^bsub>(h(a\(C,fs')))\<^esub> v = typeof\<^bsub>h\<^esub> v" + (*<*)by(induct v) (auto simp:fun_upd_apply)(*>*) + +text\ For literal values the first parameter of @{term typeof} can be +set to @{term empty} because they do not contain addresses: \ + +abbreviation + typeof :: "val \ ty option" where + "typeof v == typeof_h Map.empty v" + +lemma typeof_lit_typeof: + "typeof v = Some T \ typeof\<^bsub>h\<^esub> v = Some T" + (*<*)by(cases v) auto(*>*) + +lemma typeof_lit_is_type: + "typeof v = Some T \ is_type P T" + (*<*)by (induct v) (auto simp:is_type_def)(*>*) + + +subsection \ Heap extension @{text"\"} \ + +lemma hextI: "\a C fs. h a = Some(C,fs) \ (\fs'. h' a = Some(C,fs')) \ h \ h'" +(*<*)by(auto simp: hext_def)(*>*) + +lemma hext_objD: "\ h \ h'; h a = Some(C,fs) \ \ \fs'. h' a = Some(C,fs')" +(*<*)by(auto simp: hext_def)(*>*) + +lemma hext_refl [iff]: "h \ h" +(*<*)by (rule hextI) fast(*>*) + +lemma hext_new [simp]: "h a = None \ h \ h(a\x)" +(*<*)by (rule hextI) (auto simp:fun_upd_apply)(*>*) + +lemma hext_trans: "\ h \ h'; h' \ h'' \ \ h \ h''" +(*<*)by (rule hextI) (fast dest: hext_objD)(*>*) + +lemma hext_upd_obj: "h a = Some (C,fs) \ h \ h(a\(C,fs'))" +(*<*)by (rule hextI) (auto simp:fun_upd_apply)(*>*) + +lemma hext_typeof_mono: "\ h \ h'; typeof\<^bsub>h\<^esub> v = Some T \ \ typeof\<^bsub>h'\<^esub> v = Some T" +(*<*) +proof(cases v) + case Addr assume "h \ h'" and "typeof\<^bsub>h\<^esub> v = \T\" + then show ?thesis using Addr by(fastforce simp:hext_def) +qed simp_all +(*>*) + +subsection\ Static field information function \ + +datatype init_state = Done | Processing | Prepared | Error + \ \@{term Done} = initialized\ + \ \@{term Processing} = currently being initialized\ + \ \@{term Prepared} = uninitialized and not currently being initialized\ + \ \@{term Error} = previous initialization attempt resulted in erroneous state\ + +inductive iprog :: "init_state \ init_state \ bool" ("_ \\<^sub>i _" [51,51] 50) +where + [simp]: "Prepared \\<^sub>i i" +| [simp]: "Processing \\<^sub>i Done" +| [simp]: "Processing \\<^sub>i Error" +| [simp]: "i \\<^sub>i i" + +lemma iprog_Done[simp]: "(Done \\<^sub>i i) = (i = Done)" + by(simp only: iprog.simps, simp) + +lemma iprog_Error[simp]: "(Error \\<^sub>i i) = (i = Error)" + by(simp only: iprog.simps, simp) + +lemma iprog_Processing[simp]: "(Processing \\<^sub>i i) = (i = Done \ i = Error \ i = Processing)" + by(simp only: iprog.simps, simp) + +lemma iprog_trans: "\ i \\<^sub>i i'; i' \\<^sub>i i'' \ \ i \\<^sub>i i''" +(*<*)by(case_tac i; case_tac i') simp_all(*>*) + +subsection\ Static Heap \ + +text \The static heap (sheap) is used for storing information about static + field values and initialization status for classes.\ + +type_synonym + sheap = "cname \ sfields \ init_state" + +translations + (type) "sheap" <= (type) "char list \ (sfields \ init_state) option" + +definition shext :: "sheap \ sheap \ bool" ("_ \\<^sub>s _" [51,51] 50) +where + "sh \\<^sub>s sh' \ \C sfs i. sh C = Some(sfs,i) \ (\sfs' i'. sh' C = Some(sfs',i') \ i \\<^sub>i i')" + + +lemma shextI: "\C sfs i. sh C = Some(sfs,i) \ (\sfs' i'. sh' C = Some(sfs',i') \ i \\<^sub>i i') \ sh \\<^sub>s sh'" +(*<*)by(auto simp: shext_def)(*>*) + +lemma shext_objD: "\ sh \\<^sub>s sh'; sh C = Some(sfs,i) \ \ \sfs' i'. sh' C = Some(sfs', i') \ i \\<^sub>i i'" +(*<*)by(auto simp: shext_def)(*>*) + +lemma shext_refl [iff]: "sh \\<^sub>s sh" +(*<*)by (rule shextI) auto(*>*) + +lemma shext_new [simp]: "sh C = None \ sh \\<^sub>s sh(C\x)" +(*<*)by (rule shextI) (auto simp:fun_upd_apply)(*>*) + +lemma shext_trans: "\ sh \\<^sub>s sh'; sh' \\<^sub>s sh'' \ \ sh \\<^sub>s sh''" +(*<*)by (rule shextI) (fast dest: iprog_trans shext_objD)(*>*) + +lemma shext_upd_obj: "\ sh C = Some (sfs,i); i \\<^sub>i i' \ \ sh \\<^sub>s sh(C\(sfs',i'))" +(*<*)by (rule shextI) (auto simp:fun_upd_apply)(*>*) + +end diff --git a/thys/JinjaDCI/Common/SystemClasses.thy b/thys/JinjaDCI/Common/SystemClasses.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/Common/SystemClasses.thy @@ -0,0 +1,57 @@ +(* Title: JinjaDCI/Common/SystemClasses.thy + + Author: Gerwin Klein, Susannah Mansky + Copyright 2002 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory Common/SystemClasses.thy by Gerwin Klein +*) + +section \ System Classes \ + +theory SystemClasses +imports Decl Exceptions +begin + +text \ + This theory provides definitions for the @{text Object} class, + and the system exceptions. +\ + +definition ObjectC :: "'m cdecl" +where + "ObjectC \ (Object, (undefined,[],[]))" + +definition NullPointerC :: "'m cdecl" +where + "NullPointerC \ (NullPointer, (Object,[],[]))" + +definition ClassCastC :: "'m cdecl" +where + "ClassCastC \ (ClassCast, (Object,[],[]))" + +definition OutOfMemoryC :: "'m cdecl" +where + "OutOfMemoryC \ (OutOfMemory, (Object,[],[]))" + +definition NoClassDefFoundC :: "'m cdecl" +where + "NoClassDefFoundC \ (NoClassDefFoundError, (Object,[],[]))" + +definition IncompatibleClassChangeC :: "'m cdecl" +where + "IncompatibleClassChangeC \ (IncompatibleClassChangeError, (Object,[],[]))" + +definition NoSuchFieldC :: "'m cdecl" +where + "NoSuchFieldC \ (NoSuchFieldError, (Object,[],[]))" + +definition NoSuchMethodC :: "'m cdecl" +where + "NoSuchMethodC \ (NoSuchMethodError, (Object,[],[]))" + +definition SystemClasses :: "'m cdecl list" +where + "SystemClasses \ [ObjectC, NullPointerC, ClassCastC, OutOfMemoryC, NoClassDefFoundC, + IncompatibleClassChangeC, NoSuchFieldC, NoSuchMethodC]" + +end diff --git a/thys/JinjaDCI/Common/Type.thy b/thys/JinjaDCI/Common/Type.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/Common/Type.thy @@ -0,0 +1,65 @@ +(* Title: JinjaDCI/Common/Type.thy + + Author: David von Oheimb, Tobias Nipkow, Susannah Mansky + Copyright 1999 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory Common/Type.thy by David von Oheimb and Tobias Nipkow +*) + +section \ Jinja types \ + +theory Type imports Auxiliary begin + +type_synonym cname = string \ \class names\ +type_synonym mname = string \ \method name\ +type_synonym vname = string \ \names for local/field variables\ + +definition Object :: cname +where + "Object \ ''Object''" + +definition this :: vname +where + "this \ ''this''" + +definition clinit :: "string" where "clinit = ''''" +definition init :: "string" where "init = ''''" + +definition start_m :: "string" where "start_m = ''''" +definition Start :: "string" where "Start = ''''" + +lemma start_m_neq_clinit [simp]: "start_m \ clinit" by(simp add: start_m_def clinit_def) +lemma Object_neq_Start [simp]: "Object \ Start" by(simp add: Object_def Start_def) +lemma Start_neq_Object [simp]: "Start \ Object" by(simp add: Object_def Start_def) + +\ \field/method static flag\ + +datatype staticb = Static | NonStatic + +\ \types\ +datatype ty + = Void \ \type of statements\ + | Boolean + | Integer + | NT \ \null type\ + | Class cname \ \class type\ + +definition is_refT :: "ty \ bool" +where + "is_refT T \ T = NT \ (\C. T = Class C)" + +lemma [iff]: "is_refT NT" +(*<*)by(simp add:is_refT_def)(*>*) + +lemma [iff]: "is_refT(Class C)" +(*<*)by(simp add:is_refT_def)(*>*) + +lemma refTE: + "\is_refT T; T = NT \ P; \C. T = Class C \ P \ \ P" +(*<*)by (auto simp add: is_refT_def)(*>*) + +lemma not_refTE: + "\ \is_refT T; T = Void \ T = Boolean \ T = Integer \ P \ \ P" +(*<*)by (cases T, auto simp add: is_refT_def)(*>*) + +end diff --git a/thys/JinjaDCI/Common/TypeRel.thy b/thys/JinjaDCI/Common/TypeRel.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/Common/TypeRel.thy @@ -0,0 +1,769 @@ +(* Title: JinjaDCI/Common/TypeRel.thy + Author: Tobias Nipkow, Susannah Mansky + Copyright 2003 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory Common/TypeRel.thy by Tobias Nipkow +*) + +section \ Relations between Jinja Types \ + +theory TypeRel imports + "HOL-Library.Transitive_Closure_Table" + Decl +begin + +subsection \ The subclass relations \ + +inductive_set + subcls1 :: "'m prog \ (cname \ cname) set" + and subcls1' :: "'m prog \ [cname, cname] \ bool" ("_ \ _ \\<^sup>1 _" [71,71,71] 70) + for P :: "'m prog" +where + "P \ C \\<^sup>1 D \ (C,D) \ subcls1 P" +| subcls1I: "\class P C = Some (D,rest); C \ Object\ \ P \ C \\<^sup>1 D" + +abbreviation + subcls :: "'m prog \ [cname, cname] \ bool" ("_ \ _ \\<^sup>* _" [71,71,71] 70) + where "P \ C \\<^sup>* D \ (C,D) \ (subcls1 P)\<^sup>*" + +lemma subcls1D: "P \ C \\<^sup>1 D \ C \ Object \ (\fs ms. class P C = Some (D,fs,ms))" +(*<*)by(erule subcls1.induct)(fastforce simp add:is_class_def)(*>*) + +lemma [iff]: "\ P \ Object \\<^sup>1 C" +(*<*)by(fastforce dest:subcls1D)(*>*) + +lemma [iff]: "(P \ Object \\<^sup>* C) = (C = Object)" +(*<*) +proof(rule iffI) + assume "P \ Object \\<^sup>* C" then show "C = Object" + by(auto elim: converse_rtranclE) +qed simp +(*>*) + +lemma subcls1_def2: + "subcls1 P = + (SIGMA C:{C. is_class P C}. {D. C\Object \ fst (the (class P C))=D})" +(*<*) + by (fastforce simp:is_class_def dest: subcls1D elim: subcls1I) +(*>*) + +lemma finite_subcls1: "finite (subcls1 P)" +(*<*) +proof - + let ?SIG = "SIGMA C:{C. is_class P C}. {D. fst (the (class P C)) = D \ C \ Object}" + have "subcls1 P = ?SIG" by(simp add: subcls1_def2) + also have "finite ?SIG" + proof(rule finite_SigmaI [OF finite_is_class]) + fix C assume C_in: "C \ {C. is_class P C}" + then show "finite {D. fst (the (class P C)) = D \ C \ Object}" + by(rule_tac finite_subset[where B = "{fst (the (class P C))}"]) auto + qed + ultimately show ?thesis by simp +qed +(*>*) + +primrec supercls_lst :: "'m prog \ cname list \ bool" where +"supercls_lst P (C#Cs) = ((\C' \ set Cs. P \ C' \\<^sup>* C) \ supercls_lst P Cs)" | +"supercls_lst P [] = True" + +lemma supercls_lst_app: + "\ supercls_lst P (C#Cs); P \ C \\<^sup>* C' \ \ supercls_lst P (C'#C#Cs)" + by auto + +subsection\ The subtype relations \ + +inductive + widen :: "'m prog \ ty \ ty \ bool" ("_ \ _ \ _" [71,71,71] 70) + for P :: "'m prog" +where + widen_refl[iff]: "P \ T \ T" +| widen_subcls: "P \ C \\<^sup>* D \ P \ Class C \ Class D" +| widen_null[iff]: "P \ NT \ Class C" + +abbreviation + widens :: "'m prog \ ty list \ ty list \ bool" + ("_ \ _ [\] _" [71,71,71] 70) where + "widens P Ts Ts' \ list_all2 (widen P) Ts Ts'" + +lemma [iff]: "(P \ T \ Void) = (T = Void)" +(*<*)by (auto elim: widen.cases)(*>*) + +lemma [iff]: "(P \ T \ Boolean) = (T = Boolean)" +(*<*)by (auto elim: widen.cases)(*>*) + +lemma [iff]: "(P \ T \ Integer) = (T = Integer)" +(*<*)by (auto elim: widen.cases)(*>*) + +lemma [iff]: "(P \ Void \ T) = (T = Void)" +(*<*)by (auto elim: widen.cases)(*>*) + +lemma [iff]: "(P \ Boolean \ T) = (T = Boolean)" +(*<*)by (auto elim: widen.cases)(*>*) + +lemma [iff]: "(P \ Integer \ T) = (T = Integer)" +(*<*)by (auto elim: widen.cases)(*>*) + + +lemma Class_widen: "P \ Class C \ T \ \D. T = Class D" +(*<*) +by (ind_cases "P \ Class C \ T") auto +(*>*) + +lemma [iff]: "(P \ T \ NT) = (T = NT)" +(*<*) +by(cases T) (auto dest:Class_widen) +(*>*) + +lemma Class_widen_Class [iff]: "(P \ Class C \ Class D) = (P \ C \\<^sup>* D)" +(*<*) +proof(rule iffI) + show "P \ Class C \ Class D \ P \ C \\<^sup>* D" + proof(ind_cases "P \ Class C \ Class D") qed(auto) +qed(auto elim: widen_subcls) +(*>*) + +lemma widen_Class: "(P \ T \ Class C) = (T = NT \ (\D. T = Class D \ P \ D \\<^sup>* C))" +(*<*)by(induct T, auto)(*>*) + + +lemma widen_trans[trans]: "\P \ S \ U; P \ U \ T\ \ P \ S \ T" +(*<*) +proof - + assume "P\S \ U" thus "\T. P \ U \ T \ P \ S \ T" + proof induct + case (widen_refl T T') thus "P \ T \ T'" . + next + case (widen_subcls C D T) + then obtain E where "T = Class E" by (blast dest: Class_widen) + with widen_subcls show "P \ Class C \ T" by (auto elim: rtrancl_trans) + next + case (widen_null C RT) + then obtain D where "RT = Class D" by (blast dest: Class_widen) + thus "P \ NT \ RT" by auto + qed +qed +(*>*) + +lemma widens_trans [trans]: "\P \ Ss [\] Ts; P \ Ts [\] Us\ \ P \ Ss [\] Us" +(*<*)by (rule list_all2_trans, rule widen_trans)(*>*) + + +(*<*) +lemmas widens_refl [iff] = list_all2_refl [of "widen P", OF widen_refl] for P +lemmas widens_Cons [iff] = list_all2_Cons1 [of "widen P"] for P +(*>*) + + +subsection\ Method lookup \ + +inductive + Methods :: "['m prog, cname, mname \ (staticb \ ty list \ ty \ 'm) \ cname] \ bool" + ("_ \ _ sees'_methods _" [51,51,51] 50) + for P :: "'m prog" +where + sees_methods_Object: + "\ class P Object = Some(D,fs,ms); Mm = map_option (\m. (m,Object)) \ map_of ms \ + \ P \ Object sees_methods Mm" +| sees_methods_rec: + "\ class P C = Some(D,fs,ms); C \ Object; P \ D sees_methods Mm; + Mm' = Mm ++ (map_option (\m. (m,C)) \ map_of ms) \ + \ P \ C sees_methods Mm'" + +lemma sees_methods_fun: +assumes 1: "P \ C sees_methods Mm" +shows "\Mm'. P \ C sees_methods Mm' \ Mm' = Mm" + (*<*) +using 1 +proof induct + case (sees_methods_rec C D fs ms Dres Cres Cres') + have "class": "class P C = Some (D, fs, ms)" + and notObj: "C \ Object" and Dmethods: "P \ D sees_methods Dres" + and IH: "\Dres'. P \ D sees_methods Dres' \ Dres' = Dres" + and Cres: "Cres = Dres ++ (map_option (\m. (m,C)) \ map_of ms)" + and Cmethods': "P \ C sees_methods Cres'" by fact+ + from Cmethods' notObj "class" obtain Dres' + where Dmethods': "P \ D sees_methods Dres'" + and Cres': "Cres' = Dres' ++ (map_option (\m. (m,C)) \ map_of ms)" + by(auto elim: Methods.cases) + from Cres Cres' IH[OF Dmethods'] show "Cres' = Cres" by simp +next + case sees_methods_Object thus ?case by(auto elim: Methods.cases) +qed +(*>*) + +lemma visible_methods_exist: + "P \ C sees_methods Mm \ Mm M = Some(m,D) \ + (\D' fs ms. class P D = Some(D',fs,ms) \ map_of ms M = Some m)" + (*<*)by(induct rule:Methods.induct) auto(*>*) + +lemma sees_methods_decl_above: +assumes Csees: "P \ C sees_methods Mm" +shows "Mm M = Some(m,D) \ P \ C \\<^sup>* D" + (*<*) +using Csees +proof induct +next + case sees_methods_Object thus ?case by auto +next + case sees_methods_rec thus ?case + by(fastforce simp:map_option_case split:option.splits + elim:converse_rtrancl_into_rtrancl[OF subcls1I]) +qed +(*>*) + +lemma sees_methods_idemp: +assumes Cmethods: "P \ C sees_methods Mm" +shows "\m D. Mm M = Some(m,D) \ + \Mm'. (P \ D sees_methods Mm') \ Mm' M = Some(m,D)" +(*<*) +using Cmethods +proof induct + case sees_methods_Object thus ?case + by(fastforce dest: Methods.sees_methods_Object) +next + case sees_methods_rec thus ?case + by(fastforce split:option.splits dest: Methods.sees_methods_rec) +qed +(*>*) + +(*FIXME something wrong with induct: need to attache [consumes 1] +directly to proof of thm, declare does not work. *) + +lemma sees_methods_decl_mono: +assumes sub: "P \ C' \\<^sup>* C" +shows "P \ C sees_methods Mm \ + \Mm' Mm\<^sub>2. P \ C' sees_methods Mm' \ Mm' = Mm ++ Mm\<^sub>2 \ + (\M m D. Mm\<^sub>2 M = Some(m,D) \ P \ D \\<^sup>* C)" +(*<*) + (is "_ \ \Mm' Mm2. ?Q C' C Mm' Mm2") +using sub +proof (induct rule:converse_rtrancl_induct) + assume "P \ C sees_methods Mm" + hence "?Q C C Mm Map.empty" by simp + thus "\Mm' Mm2. ?Q C C Mm' Mm2" by blast +next + fix C'' C' + assume sub1: "P \ C'' \\<^sup>1 C'" and sub: "P \ C' \\<^sup>* C" + and IH: "P \ C sees_methods Mm \ + \Mm' Mm2. P \ C' sees_methods Mm' \ + Mm' = Mm ++ Mm2 \ (\M m D. Mm2 M = Some(m,D) \ P \ D \\<^sup>* C)" + and Csees: "P \ C sees_methods Mm" + from IH[OF Csees] obtain Mm' Mm2 where C'sees: "P \ C' sees_methods Mm'" + and Mm': "Mm' = Mm ++ Mm2" + and subC:"\M m D. Mm2 M = Some(m,D) \ P \ D \\<^sup>* C" by blast + obtain fs ms where "class": "class P C'' = Some(C',fs,ms)" "C'' \ Object" + using subcls1D[OF sub1] by blast + let ?Mm3 = "map_option (\m. (m,C'')) \ map_of ms" + have "P \ C'' sees_methods (Mm ++ Mm2) ++ ?Mm3" + using sees_methods_rec[OF "class" C'sees refl] Mm' by simp + hence "?Q C'' C ((Mm ++ Mm2) ++ ?Mm3) (Mm2++?Mm3)" + using converse_rtrancl_into_rtrancl[OF sub1 sub] + by simp (simp add:map_add_def subC split:option.split) + thus "\Mm' Mm2. ?Q C'' C Mm' Mm2" by blast +qed +(*>*) + +lemma sees_methods_is_class_Object: + "P \ D sees_methods Mm \ is_class P Object" + by(induct rule: Methods.induct; simp add: is_class_def) + +lemma sees_methods_sub_Obj: "P \ C sees_methods Mm \ P \ C \\<^sup>* Object" +proof(induct rule: Methods.induct) + case (sees_methods_rec C D fs ms Mm Mm') show ?case + using subcls1I[OF sees_methods_rec.hyps(1,2)] sees_methods_rec.hyps(4) + by(rule converse_rtrancl_into_rtrancl) +qed(simp) + + +definition Method :: "'m prog \ cname \ mname \ staticb \ ty list \ ty \ 'm \ cname \ bool" + ("_ \ _ sees _, _ : _\_ = _ in _" [51,51,51,51,51,51,51,51] 50) +where + "P \ C sees M, b: Ts\T = m in D \ + \Mm. P \ C sees_methods Mm \ Mm M = Some((b,Ts,T,m),D)" + +definition has_method :: "'m prog \ cname \ mname \ staticb \ bool" + ("_ \ _ has _, _" [51,0,0,51] 50) +where + "P \ C has M, b \ \Ts T m D. P \ C sees M,b:Ts\T = m in D" + +lemma sees_method_fun: + "\P \ C sees M,b:TS\T = m in D; P \ C sees M,b':TS'\T' = m' in D' \ + \ b = b' \ TS' = TS \ T' = T \ m' = m \ D' = D" + (*<*)by(fastforce dest: sees_methods_fun simp:Method_def)(*>*) + +lemma sees_method_decl_above: + "P \ C sees M,b:Ts\T = m in D \ P \ C \\<^sup>* D" + (*<*)by(clarsimp simp:Method_def sees_methods_decl_above)(*>*) + +lemma visible_method_exists: + "P \ C sees M,b:Ts\T = m in D \ + \D' fs ms. class P D = Some(D',fs,ms) \ map_of ms M = Some(b,Ts,T,m)" +(*<*)by(fastforce simp:Method_def dest!: visible_methods_exist)(*>*) + + +lemma sees_method_idemp: + "P \ C sees M,b:Ts\T=m in D \ P \ D sees M,b:Ts\T=m in D" + (*<*)by(fastforce simp: Method_def intro:sees_methods_idemp)(*>*) + +lemma sees_method_decl_mono: +assumes sub: "P \ C' \\<^sup>* C" and + C_sees: "P \ C sees M,b:Ts\T=m in D" and + C'_sees: "P \ C' sees M,b':Ts'\T'=m' in D'" +shows "P \ D' \\<^sup>* D" + (*<*) +proof - + obtain Ms where Ms: "P \ C sees_methods Ms" + using C_sees by(auto simp: Method_def) + obtain Ms' Ms2 where Ms': "P \ C' sees_methods Ms'" and + Ms'_def: "Ms' = Ms ++ Ms2" and + Ms2_imp: "(\M m D. Ms2 M = \(m, D)\ \ P \ D \\<^sup>* C)" + using sees_methods_decl_mono[OF sub Ms] by clarsimp + have "(Ms ++ Ms2) M = \((b', Ts', T', m'), D')\" + using C'_sees sees_methods_fun[OF Ms'] Ms'_def by(clarsimp simp: Method_def) + then have "Ms2 M = \((b', Ts', T', m'), D')\ \ + Ms2 M = None \ b = b' \ Ts = Ts' \ T = T' \ m = m' \ D = D'" + using C_sees sees_methods_fun[OF Ms] by(clarsimp simp: Method_def) + also have "Ms2 M = \((b', Ts', T', m'), D')\ \ P \ D' \\<^sup>* C" + using Ms2_imp by simp + ultimately show ?thesis using sub sees_method_decl_above[OF C_sees] by auto +qed +(*>*) + +lemma sees_methods_is_class: "P \ C sees_methods Mm \ is_class P C" +(*<*)by (auto simp add: is_class_def elim: Methods.induct)(*>*) + +lemma sees_method_is_class: + "\ P \ C sees M,b:Ts\T=m in D \ \ is_class P C" +(*<*)by (auto simp add: is_class_def Method_def dest: sees_methods_is_class)(*>*) + +lemma sees_method_is_class': + "\ P \ C sees M,b:Ts\T=m in D \ \ is_class P D" +(*<*)by(drule sees_method_idemp, rule sees_method_is_class, assumption)(*>*) + +lemma sees_method_sub_Obj: "P \ C sees M,b: Ts\T = m in D \ P \ C \\<^sup>* Object" + by(auto simp: Method_def sees_methods_sub_Obj) + +subsection\ Field lookup \ + +inductive + Fields :: "['m prog, cname, ((vname \ cname) \ staticb \ ty) list] \ bool" + ("_ \ _ has'_fields _" [51,51,51] 50) + for P :: "'m prog" +where + has_fields_rec: + "\ class P C = Some(D,fs,ms); C \ Object; P \ D has_fields FDTs; + FDTs' = map (\(F,b,T). ((F,C),b,T)) fs @ FDTs \ + \ P \ C has_fields FDTs'" +| has_fields_Object: + "\ class P Object = Some(D,fs,ms); FDTs = map (\(F,b,T). ((F,Object),b,T)) fs \ + \ P \ Object has_fields FDTs" + +lemma has_fields_is_class: + "P \ C has_fields FDTs \ is_class P C" +(*<*)by (auto simp add: is_class_def elim: Fields.induct)(*>*) + +lemma has_fields_fun: +assumes 1: "P \ C has_fields FDTs" +shows "\FDTs'. P \ C has_fields FDTs' \ FDTs' = FDTs" + (*<*) +using 1 +proof induct + case (has_fields_rec C D fs ms Dres Cres Cres') + have "class": "class P C = Some (D, fs, ms)" + and notObj: "C \ Object" and DFields: "P \ D has_fields Dres" + and IH: "\Dres'. P \ D has_fields Dres' \ Dres' = Dres" + and Cres: "Cres = map (\(F,b,T). ((F,C),b,T)) fs @ Dres" + and CFields': "P \ C has_fields Cres'" by fact+ + from CFields' notObj "class" obtain Dres' + where DFields': "P \ D has_fields Dres'" + and Cres': "Cres' = map (\(F,b,T). ((F,C),b,T)) fs @ Dres'" + by(auto elim: Fields.cases) + from Cres Cres' IH[OF DFields'] show "Cres' = Cres" by simp +next + case has_fields_Object thus ?case by(auto elim: Fields.cases) +qed +(*>*) + +lemma all_fields_in_has_fields: +assumes sub: "P \ C has_fields FDTs" +shows "\ P \ C \\<^sup>* D; class P D = Some(D',fs,ms); (F,b,T) \ set fs \ + \ ((F,D),b,T) \ set FDTs" +(*<*) +using sub proof(induct) + case (has_fields_rec C D' fs ms FDTs FDTs') + then have C_D: "P \ C \\<^sup>* D" by simp + then show ?case proof(rule converse_rtranclE) + assume "C = D" + then show ?case using has_fields_rec by force + next + fix y assume sub1: "P \ C \\<^sup>1 y" and sub2: "P \ y \\<^sup>* D" + then show ?case using has_fields_rec subcls1D[OF sub1] by simp + qed +next + case (has_fields_Object D fs ms FDTs) + then show ?case by force +qed +(*>*) + +lemma has_fields_decl_above: +assumes fields: "P \ C has_fields FDTs" +shows "((F,D),b,T) \ set FDTs \ P \ C \\<^sup>* D" +(*<*) +using fields proof(induct) + case (has_fields_rec C D' fs ms FDTs FDTs') + then have "((F, D), b, T) \ (\x. case x of (F, x) \ ((F, C), x)) ` set fs \ + ((F, D), b, T) \ set FDTs" by clarsimp + then show ?case proof(rule disjE) + assume "((F, D), b, T) \ (\x. case x of (F, x) \ ((F, C), x)) ` set fs" + then show ?case using has_fields_rec by clarsimp + next + assume "((F, D), b, T) \ set FDTs" + then show ?case using has_fields_rec + by(blast dest:subcls1I converse_rtrancl_into_rtrancl) + qed +next + case (has_fields_Object D fs ms FDTs) + then show ?case by fastforce +qed +(*>*) + + +lemma subcls_notin_has_fields: +assumes fields: "P \ C has_fields FDTs" +shows "((F,D),b,T) \ set FDTs \ (D,C) \ (subcls1 P)\<^sup>+" +(*<*) +using fields proof(induct) + case (has_fields_rec C D' fs ms FDTs FDTs') + then have "((F, D), b, T) \ (\x. case x of (F, x) \ ((F, C), x)) ` set fs + \ ((F, D), b, T) \ set FDTs" by clarsimp + then show ?case proof(rule disjE) + assume "((F, D), b, T) \ (\x. case x of (F, x) \ ((F, C), x)) ` set fs" + then have CD[simp]: "C = D" and fs: "(F, b, T) \ set fs" by clarsimp+ + then have "(D, D) \ (subcls1 P)\<^sup>+ \ False" proof - + assume DD: "(D, D) \ (subcls1 P)\<^sup>+" + obtain z where z1: "P \ D \\<^sup>1 z" and z_s: "P \ z \\<^sup>* D" + using tranclD[OF DD] by clarsimp + have [simp]: "z = D'" using subcls1D[OF z1] has_fields_rec.hyps(1) by clarsimp + then have "((F, D), b, T) \ set FDTs" + using z_s all_fields_in_has_fields[OF has_fields_rec.hyps(3) _ has_fields_rec.hyps(1) fs] + by simp + then have "(D, z) \ (subcls1 P)\<^sup>+" using has_fields_rec.hyps(4) by simp + then show False using z1 by auto + qed + then show ?case by clarsimp + next + assume "((F, D), b, T) \ set FDTs" + then show ?case using has_fields_rec by(blast dest:subcls1I trancl_into_trancl) + qed +next + case (has_fields_Object D fs ms FDTs) + then show ?case by(fastforce dest: tranclD) +qed +(*>*) + +lemma subcls_notin_has_fields2: +assumes fields: "P \ C has_fields FDTs" +shows "\ C \ Object; P \ C \\<^sup>1 D \ \ (D,C) \ (subcls1 P)\<^sup>*" +using fields proof(induct arbitrary: D) + case has_fields_rec + have "\C C' P. (C, C') \ subcls1 P \ C \ Object \ (\fs ms. class P C = \(C', fs, ms)\)" + using subcls1D by blast + then have "(D, D) \ (subcls1 P)\<^sup>+" + by (metis (no_types) Pair_inject has_fields_rec.hyps(1) has_fields_rec.hyps(4) + has_fields_rec.prems(2) option.inject tranclD) + then show ?case + by (meson has_fields_rec.prems(2) rtrancl_into_trancl1) +qed(fastforce dest: tranclD) + +lemma has_fields_mono_lem: +assumes sub: "P \ D \\<^sup>* C" +shows "P \ C has_fields FDTs + \ \pre. P \ D has_fields pre@FDTs \ dom(map_of pre) \ dom(map_of FDTs) = {}" +(*<*) +using sub proof(induct rule:converse_rtrancl_induct) + case base + then show ?case by(rule_tac x = "[]" in exI) simp +next + case (step D' D) + then obtain pre where D_flds: "P \ D has_fields pre @ FDTs" and + dom: "dom (map_of pre) \ dom (map_of FDTs) = {}" by clarsimp + have "(D',C) \ (subcls1 P)^+" by (rule rtrancl_into_trancl2[OF step.hyps(1,2)]) + obtain fs ms where D'_cls: "class P D' = \(D, fs, ms)\" "D' \ Object" + using subcls1D[OF step.hyps(1)] by clarsimp+ + have "P \ D' has_fields map (\(F, T). ((F, D'), T)) fs @ pre @ FDTs" + using has_fields_rec[OF D'_cls D_flds] by simp + also have "dom (map_of (map (\(F, T). ((F, D'), T)) fs @ pre)) + \ dom (map_of FDTs) = {}" + using dom subcls_notin_has_fields[OF D_flds, where D=D'] step.hyps(1) + by(auto simp:dom_map_of_conv_image_fst) fast + ultimately show ?case + by(rule_tac x = "map (\(F,b,T). ((F,D'),b,T)) fs @ pre" in exI) simp +qed +(*>*) + +lemma has_fields_declaring_classes: +shows "P \ C has_fields FDTs + \ \pre FDTs'. FDTs = pre@FDTs' + \ (C \ Object \ (\D fs ms. class P C = \(D,fs,ms)\ \ P \ D has_fields FDTs')) + \ set(map (\t. snd(fst t)) pre) \ {C} + \ set(map (\t. snd(fst t)) FDTs') \ {C'. C' \ C \ P \ C \\<^sup>* C'}" +proof(induct rule:Fields.induct) + case (has_fields_rec C D fs ms FDTs FDTs') + have sup1: "P \ C \\<^sup>1 D" using has_fields_rec.hyps(1,2) by (simp add: subcls1.subcls1I) + have "P \ C has_fields FDTs'" + using Fields.has_fields_rec[OF has_fields_rec.hyps(1-3)] has_fields_rec by auto + then have nsup: "(D, C) \ (subcls1 P)\<^sup>*" using subcls_notin_has_fields2 sup1 by auto + show ?case using has_fields_rec sup1 nsup + by(rule_tac x = "map (\(F, y). ((F, C), y)) fs" in exI, clarsimp) auto +next + case has_fields_Object then show ?case by fastforce +qed + +lemma has_fields_mono_lem2: +assumes hf: "P \ C has_fields FDTs" + and cls: "class P C = Some(D,fs,ms)" and map_of: "map_of FDTs (F,C) = \(b,T)\" +shows "\FDTs'. FDTs = (map (\(F,b,T). ((F,C),b,T)) fs) @ FDTs' \ map_of FDTs' (F,C) = None" +using assms +proof(cases "C = Object") + case False + let ?pre = "map (\(F,b,T). ((F,C),b,T)) fs" + have sub: "P \ C \\<^sup>* D" using cls False by (simp add: r_into_rtrancl subcls1.subcls1I) + obtain FDTs' where fdts': "P \ D has_fields FDTs'" "FDTs = ?pre @ FDTs'" + using False assms(1,2) Fields.simps[of P C FDTs] by clarsimp + then have int: "dom (map_of ?pre) \ dom (map_of FDTs') = {}" + using has_fields_mono_lem[OF sub, of FDTs'] has_fields_fun[OF hf] by fastforce + have "C \ (\t. snd (fst t)) ` set FDTs'" + using has_fields_declaring_classes[OF hf] cls False + has_fields_fun[OF fdts'(1)] fdts'(2) + by clarify auto + then have "map_of FDTs' (F,C) = None" by(rule map_of_set_pcs_notin) + then show ?thesis using fdts' int by simp +qed(auto dest: has_fields_Object has_fields_fun) + + +lemma has_fields_is_class_Object: + "P \ D has_fields FDTs \ is_class P Object" + by(induct rule: Fields.induct; simp add: is_class_def) + +lemma Object_fields: + "\ P \ Object has_fields FDTs; C \ Object \ \ map_of FDTs (F,C) = None" + by(drule Fields.cases, auto simp: map_of_reinsert_neq_None) + + +definition has_field :: "'m prog \ cname \ vname \ staticb \ ty \ cname \ bool" + ("_ \ _ has _,_:_ in _" [51,51,51,51,51,51] 50) +where + "P \ C has F,b:T in D \ + \FDTs. P \ C has_fields FDTs \ map_of FDTs (F,D) = Some (b,T)" + + +lemma has_field_mono: +assumes has: " P \ C has F,b:T in D" and sub: "P \ C' \\<^sup>* C" +shows "P \ C' has F,b:T in D" +(*<*) +proof - + obtain FDTs where FDTs:"P \ C has_fields FDTs" and "map_of FDTs (F, D) = \(b, T)\" + using has by(clarsimp simp: has_field_def) + also obtain pre where "P \ C' has_fields pre @ FDTs" + and "dom (map_of pre) \ dom (map_of FDTs) = {}" + using has_fields_mono_lem[OF sub FDTs] by clarify + ultimately show ?thesis by(fastforce simp: has_field_def map_add_def split:option.splits) +qed +(*>*) + +lemma has_field_fun: + "\P \ C has F,b:T in D; P \ C has F,b':T' in D\ \ b = b' \ T' = T" +(*<*)by(fastforce simp:has_field_def dest:has_fields_fun)(*>*) + + +lemma has_field_idemp: +assumes has: "P \ C has F,b:T in D" +shows "P \ D has F,b:T in D" +(*<*) +proof - + obtain FDTs where C_flds: "P \ C has_fields FDTs" + and FDTs: "map_of FDTs (F, D) = \(b, T)\" (is "?FDTs") + using has by(clarsimp simp: has_field_def) + have map: "\C' fs. map_of (map (\(F, y). ((F, C'), y)) fs) (F, D) = \(b, T)\ \ D = C'" + by(frule map_of_SomeD) clarsimp + have "?FDTs \ P \ D has F,b:T in D" + using C_flds proof induct + case NObj: (has_fields_rec C' D' fs ms FDTs FDTs') + then show ?case using map by (fastforce intro: has_fields_rec simp: has_field_def) + next + case Obj: (has_fields_Object D fs ms FDTs) + then show ?case using map by(fastforce intro: has_fields_Object simp: has_field_def) + qed + then show ?thesis using FDTs by(rule_tac mp) +qed +(*>*) + +lemma visible_fields_exist: +assumes fields: "P \ C has_fields FDTs" and + FDTs: "map_of FDTs (F,D) = Some (b, T)" +shows "\D' fs ms. class P D = Some(D',fs,ms) \ map_of fs F = Some(b,T)" +proof - + have "map_of FDTs (F,D) = Some (b, T) \ + (\D' fs ms. class P D = Some(D',fs,ms) \ map_of fs F = Some(b,T))" + using fields proof induct + case (has_fields_rec C' D' fs ms FDTs') + with assms map_of_reinsert_SomeD map_of_reinsert_neq_None[where D=D and F=F and fs=fs] + show ?case proof(cases "C' = D") qed auto + next + case (has_fields_Object D' fs ms FDTs) + with assms map_of_reinsert_SomeD map_of_reinsert_neq_None[where D=D and F=F and fs=fs] + show ?case proof(cases "Object = D") qed auto + qed + then show ?thesis using FDTs by simp +qed + +lemma map_of_remap_SomeD: + "map_of (map (\((k,k'),x). (k,(k',x))) t) k = Some (k',x) \ map_of t (k, k') = Some x" +(*<*)by (induct t) (auto simp:fun_upd_apply split: if_split_asm)(*>*) + +lemma map_of_remap_SomeD2: + "map_of (map (\((k,k'),x,x'). (k,(k',x,x'))) t) k = Some (k',x,x') \ map_of t (k, k') = Some (x, x')" +(*<*)by (induct t) (auto simp:fun_upd_apply split: if_split_asm)(*>*) + +lemma has_field_decl_above: + "P \ C has F,b:T in D \ P \ C \\<^sup>* D" +(*<*) +by(auto simp: has_field_def + intro: has_fields_decl_above map_of_SomeD map_of_remap_SomeD2) +(*>*) + +definition sees_field :: "'m prog \ cname \ vname \ staticb \ ty \ cname \ bool" + ("_ \ _ sees _,_:_ in _" [51,51,51,51,51,51] 50) +where + "P \ C sees F,b:T in D \ + \FDTs. P \ C has_fields FDTs \ + map_of (map (\((F,D),b,T). (F,(D,b,T))) FDTs) F = Some(D,b,T)" + +lemma has_visible_field: + "P \ C sees F,b:T in D \ P \ C has F,b:T in D" +(*<*)by(auto simp add:has_field_def sees_field_def map_of_remap_SomeD2)(*>*) + +lemma sees_field_fun: + "\P \ C sees F,b:T in D; P \ C sees F,b':T' in D'\ \ b = b' \ T' = T \ D' = D" +(*<*)by(fastforce simp:sees_field_def dest:has_fields_fun)(*>*) + +lemma sees_field_decl_above: + "P \ C sees F,b:T in D \ P \ C \\<^sup>* D" +(*<*) +by(auto simp:sees_field_def + intro: has_fields_decl_above map_of_SomeD map_of_remap_SomeD2) +(*>*) + + +lemma sees_field_idemp: +assumes sees: "P \ C sees F,b:T in D" +shows "P \ D sees F,b:T in D" +(*<*) +proof - + obtain FDTs where C_flds: "P \ C has_fields FDTs" + and FDTs: "map_of (map (\((F, D), b, T). (F, D, b, T)) FDTs) F = \(D, b, T)\" + (is "?FDTs") + using sees by(clarsimp simp: sees_field_def) + have map: "\C' fs. map_of (map ((\((F, D), a). (F, D, a)) \ (\(F, y). ((F, C'), y))) fs) F + = \(D, b, T)\ + \ D = C' \ (F, b, T) \ set fs" + by(frule map_of_SomeD) clarsimp +\\ ?FDTs \ P \ D sees F,b:T in D \ + have "?FDTs \ (\FDTs. P \ D has_fields FDTs + \ map_of (map (\((F, D), a). (F, D, a)) FDTs) F = \(D, b, T)\)" + using C_flds proof induct + case NObj: (has_fields_rec C' D' fs ms FDTs FDTs') + then show ?case using map by (fastforce intro: has_fields_rec) + next + case Obj: (has_fields_Object D fs ms FDTs) + then show ?case using map by(fastforce intro: has_fields_Object) + qed + then show ?thesis using FDTs + by (smt map_eq_conv old.prod.case prod_cases3 sees_field_def split_cong) +qed +(*>*) + +lemma has_field_sees_aux: +assumes hf: "P \ C has_fields FDTs" and map: "map_of FDTs (F, C) = \(b, T)\" +shows "map_of (map (\((F, D), b, T). (F, D, b, T)) FDTs) F = \(C, b, T)\" +proof - + obtain D fs ms where fs: "class P C = Some(D,fs,ms)" + using visible_fields_exist[OF assms] by clarsimp + then obtain FDTs' where + "FDTs = map (\(F, b, T). ((F, C), b, T)) fs @ FDTs' \ map_of FDTs' (F, C) = None" + using has_fields_mono_lem2[OF hf fs map] by clarsimp + then show ?thesis using map_of_Some_None_split[OF _ _ map] by auto +qed + +lemma has_field_sees: "P \ C has F,b:T in C \ P \ C sees F,b:T in C" + by(auto simp:has_field_def sees_field_def has_field_sees_aux) + +lemma has_field_is_class: + "P \ C has F,b:T in D \ is_class P C" +(*<*)by (auto simp add: is_class_def has_field_def elim: Fields.induct)(*>*) + +lemma has_field_is_class': + "P \ C has F,b:T in D \ is_class P D" +(*<*)by(drule has_field_idemp, rule has_field_is_class, assumption)(*>*) + +subsection "Functional lookup" + +definition "method" :: "'m prog \ cname \ mname \ cname \ staticb \ ty list \ ty \ 'm" +where + "method P C M \ THE (D,b,Ts,T,m). P \ C sees M,b:Ts \ T = m in D" + +definition field :: "'m prog \ cname \ vname \ cname \ staticb \ ty" +where + "field P C F \ THE (D,b,T). P \ C sees F,b:T in D" + +definition fields :: "'m prog \ cname \ ((vname \ cname) \ staticb \ ty) list" +where + "fields P C \ THE FDTs. P \ C has_fields FDTs" + +lemma fields_def2 [simp]: "P \ C has_fields FDTs \ fields P C = FDTs" +(*<*)by (unfold fields_def) (auto dest: has_fields_fun)(*>*) + +lemma field_def2 [simp]: "P \ C sees F,b:T in D \ field P C F = (D,b,T)" +(*<*)by (unfold field_def) (auto dest: sees_field_fun)(*>*) + +lemma method_def2 [simp]: "P \ C sees M,b: Ts\T = m in D \ method P C M = (D,b,Ts,T,m)" +(*<*)by (unfold method_def) (auto dest: sees_method_fun)(*>*) + + +text \ The following are the fields for initializing an object (non-static fields) + and a class (just that class's static fields), respectively. \ + +definition ifields :: "'m prog \ cname \ ((vname \ cname) \ staticb \ ty) list" +where + "ifields P C \ filter (\((F,D),b,T). b = NonStatic) (fields P C)" + +definition isfields :: "'m prog \ cname \ ((vname \ cname) \ staticb \ ty) list" +where + "isfields P C \ filter (\((F,D),b,T). b = Static \ D = C) (fields P C)" + +lemma ifields_def2[simp]: "\ P \ C has_fields FDTs \ \ ifields P C = filter (\((F,D),b,T). b = NonStatic) FDTs" + by (simp add: ifields_def) + +lemma isfields_def2[simp]: "\ P \ C has_fields FDTs \ \ isfields P C = filter (\((F,D),b,T). b = Static \ D = C) FDTs" + by (simp add: isfields_def) + +lemma ifields_def3: "\ P \ C sees F,b:T in D; b = NonStatic \ \ (((F,D),b,T) \ set (ifields P C))" +(*<*) by (unfold ifields_def) (auto simp: sees_field_def map_of_SomeD map_of_remap_SomeD2) (*>*) + +lemma isfields_def3: "\ P \ C sees F,b:T in D; b = Static; D = C \ \ (((F,D),b,T) \ set (isfields P C))" +(*<*) by (unfold isfields_def) (auto simp: sees_field_def map_of_SomeD map_of_remap_SomeD2) (*>*) + + +definition seeing_class :: "'m prog \ cname \ mname \ cname option" where +"seeing_class P C M = + (if \Ts T m D. P \ C sees M,Static:Ts\T = m in D + then Some (fst(method P C M)) + else None)" + +lemma seeing_class_def2[simp]: + "P \ C sees M,Static:Ts\T = m in D \ seeing_class P C M = Some D" + by(fastforce simp: seeing_class_def) + +(*<*) +end +(*>*) diff --git a/thys/JinjaDCI/Common/Value.thy b/thys/JinjaDCI/Common/Value.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/Common/Value.thy @@ -0,0 +1,32 @@ +(* Title: Jinja/Common/Value.thy + Author: David von Oheimb, Tobias Nipkow + Copyright 1999 Technische Universitaet Muenchen +*) + +section \ Jinja Values \ + +theory Value imports TypeRel begin + +type_synonym addr = nat + +datatype val + = Unit \ \dummy result value of void expressions\ + | Null \ \null reference\ + | Bool bool \ \Boolean value\ + | Intg int \ \integer value\ + | Addr addr \ \addresses of objects in the heap\ + +primrec the_Intg :: "val \ int" where + "the_Intg (Intg i) = i" + +primrec the_Addr :: "val \ addr" where + "the_Addr (Addr a) = a" + +primrec default_val :: "ty \ val" \ \default value for all types\ where + "default_val Void = Unit" +| "default_val Boolean = Bool False" +| "default_val Integer = Intg 0" +| "default_val NT = Null" +| "default_val (Class C) = Null" + +end diff --git a/thys/JinjaDCI/Common/WellForm.thy b/thys/JinjaDCI/Common/WellForm.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/Common/WellForm.thy @@ -0,0 +1,503 @@ +(* Title: JinjaDCI/Common/WellForm.thy + + Author: Tobias Nipkow, Susannah Mansky + Copyright 2003 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory J/WellForm.thy by Tobias Nipkow +*) + +section \ Generic Well-formedness of programs \ + +theory WellForm imports TypeRel SystemClasses begin + +text \\noindent This theory defines global well-formedness conditions +for programs but does not look inside method bodies. Hence it works +for both Jinja and JVM programs. Well-typing of expressions is defined +elsewhere (in theory @{text WellType}). + +Because Jinja does not have method overloading, its policy for method +overriding is the classical one: \emph{covariant in the result type +but contravariant in the argument types.} This means the result type +of the overriding method becomes more specific, the argument types +become more general. +\ + +type_synonym 'm wf_mdecl_test = "'m prog \ cname \ 'm mdecl \ bool" + +definition wf_fdecl :: "'m prog \ fdecl \ bool" +where + "wf_fdecl P \ \(F,b,T). is_type P T" + +definition wf_mdecl :: "'m wf_mdecl_test \ 'm wf_mdecl_test" +where + "wf_mdecl wf_md P C \ \(M,b,Ts,T,m). + (\T\set Ts. is_type P T) \ is_type P T \ wf_md P C (M,b,Ts,T,m)" + +definition wf_clinit :: "'m mdecl list \ bool" where +"wf_clinit ms = (\m. (clinit,Static,[],Void,m)\set ms)" + +definition wf_cdecl :: "'m wf_mdecl_test \ 'm prog \ 'm cdecl \ bool" +where + "wf_cdecl wf_md P \ \(C,(D,fs,ms)). + (\f\set fs. wf_fdecl P f) \ distinct_fst fs \ + (\m\set ms. wf_mdecl wf_md P C m) \ distinct_fst ms \ + (C \ Object \ + is_class P D \ \ P \ D \\<^sup>* C \ + (\(M,b,Ts,T,m)\set ms. + \D' b' Ts' T' m'. P \ D sees M,b':Ts' \ T' = m' in D' \ + b = b' \ P \ Ts' [\] Ts \ P \ T \ T')) \ + wf_clinit ms" + +definition wf_syscls :: "'m prog \ bool" +where + "wf_syscls P \ {Object} \ sys_xcpts \ set(map fst P)" + +definition wf_prog :: "'m wf_mdecl_test \ 'm prog \ bool" +where + "wf_prog wf_md P \ wf_syscls P \ (\c \ set P. wf_cdecl wf_md P c) \ distinct_fst P" + + +subsection\ Well-formedness lemmas \ + +lemma class_wf: + "\class P C = Some c; wf_prog wf_md P\ \ wf_cdecl wf_md P (C,c)" +(*<*)by (unfold wf_prog_def class_def) (fast dest: map_of_SomeD)(*>*) + + +lemma class_Object [simp]: + "wf_prog wf_md P \ \C fs ms. class P Object = Some (C,fs,ms)" +(*<*)by (unfold wf_prog_def wf_syscls_def class_def) + (auto simp: map_of_SomeI) +(*>*) + + +lemma is_class_Object [simp]: + "wf_prog wf_md P \ is_class P Object" +(*<*)by (simp add: is_class_def)(*>*) + +lemma is_class_supclass: +assumes wf: "wf_prog wf_md P" and sub: "P \ C \\<^sup>* D" +shows "is_class P C \ is_class P D" +(*<*) +using sub proof(induct) + case step then show ?case + by(auto simp:wf_cdecl_def is_class_def dest!:class_wf[OF _ wf] subcls1D) +qed simp +(*>*) + +lemma is_class_xcpt: + "\ C \ sys_xcpts; wf_prog wf_md P \ \ is_class P C" +(*<*) +by (fastforce intro!: map_of_SomeI + simp add: wf_prog_def wf_syscls_def is_class_def class_def) +(*>*) + + +lemma subcls1_wfD: +assumes sub1: "P \ C \\<^sup>1 D" and wf: "wf_prog wf_md P" +shows "D \ C \ (D,C) \ (subcls1 P)\<^sup>+" +(*<*) +proof - + obtain fs ms where "C \ Object" and cls: "class P C = \(D, fs, ms)\" + using subcls1D[OF sub1] by clarify + then show ?thesis using wf class_wf[OF cls wf] r_into_trancl[OF sub1] + by(force simp add: wf_cdecl_def reflcl_trancl [THEN sym] + simp del: reflcl_trancl) +qed +(*>*) + + +lemma wf_cdecl_supD: + "\wf_cdecl wf_md P (C,D,r); C \ Object\ \ is_class P D" +(*<*)by (auto simp: wf_cdecl_def)(*>*) + + +lemma subcls_asym: + "\ wf_prog wf_md P; (C,D) \ (subcls1 P)\<^sup>+ \ \ (D,C) \ (subcls1 P)\<^sup>+" +(*<*)by(erule tranclE; fast dest!: subcls1_wfD intro: trancl_trans)(*>*) + + +lemma subcls_irrefl: + "\ wf_prog wf_md P; (C,D) \ (subcls1 P)\<^sup>+ \ \ C \ D" +(*<*)by (erule trancl_trans_induct) (auto dest: subcls1_wfD subcls_asym)(*>*) + + +lemma acyclic_subcls1: + "wf_prog wf_md P \ acyclic (subcls1 P)" +(*<*)by (unfold acyclic_def) (fast dest: subcls_irrefl)(*>*) + + +lemma wf_subcls1: + "wf_prog wf_md P \ wf ((subcls1 P)\)" +(*<*) +proof - + assume wf: "wf_prog wf_md P" + have "finite (subcls1 P)" by(rule finite_subcls1) + then have fin': "finite ((subcls1 P)\)" by(subst finite_converse) + + from wf have "acyclic (subcls1 P)" by(rule acyclic_subcls1) + then have acyc': "acyclic ((subcls1 P)\)" by (subst acyclic_converse) + + from fin' acyc' show ?thesis by (rule finite_acyclic_wf) +qed +(*>*) + + +lemma single_valued_subcls1: + "wf_prog wf_md G \ single_valued (subcls1 G)" +(*<*) +by(auto simp:wf_prog_def distinct_fst_def single_valued_def dest!:subcls1D) +(*>*) + + +lemma subcls_induct: + "\ wf_prog wf_md P; \C. \D. (C,D) \ (subcls1 P)\<^sup>+ \ Q D \ Q C \ \ Q C" +(*<*) + (is "?A \ PROP ?P \ _") +proof - + assume p: "PROP ?P" + assume ?A then have wf: "wf_prog wf_md P" by assumption + have wf':"wf (((subcls1 P)\<^sup>+)\)" using wf_trancl[OF wf_subcls1[OF wf]] + by(simp only: trancl_converse) + show ?thesis using wf_induct[where a = C and P = Q, OF wf' p] by simp +qed +(*>*) + + +lemma subcls1_induct_aux: +assumes "is_class P C" and wf: "wf_prog wf_md P" and QObj: "Q Object" +shows + "\ \C D fs ms. + \ C \ Object; is_class P C; class P C = Some (D,fs,ms) \ + wf_cdecl wf_md P (C,D,fs,ms) \ P \ C \\<^sup>1 D \ is_class P D \ Q D\ \ Q C \ + \ Q C" +(*<*) + (is "PROP ?P \ _") +proof - + assume p: "PROP ?P" + have "class P C \ None \ Q C" + proof(induct rule: subcls_induct[OF wf]) + case (1 C) + have "class P C \ None \ Q C" + proof(cases "C = Object") + case True + then show ?thesis using QObj by fast + next + case False + assume nNone: "class P C \ None" + then have is_cls: "is_class P C" by(simp add: is_class_def) + obtain D fs ms where cls: "class P C = \(D, fs, ms)\" using nNone by safe + also have wfC: "wf_cdecl wf_md P (C, D, fs, ms)" by(rule class_wf[OF cls wf]) + moreover have D: "is_class P D" by(rule wf_cdecl_supD[OF wfC False]) + moreover have "P \ C \\<^sup>1 D" by(rule subcls1I[OF cls False]) + moreover have "class P D \ None" using D by(simp add: is_class_def) + ultimately show ?thesis using 1 by (auto intro: p[OF False is_cls]) + qed + then show "class P C \ None \ Q C" by simp + qed + thus ?thesis using assms by(unfold is_class_def) simp +qed +(*>*) + +(* FIXME can't we prove this one directly?? *) +lemma subcls1_induct [consumes 2, case_names Object Subcls]: + "\ wf_prog wf_md P; is_class P C; Q Object; + \C D. \C \ Object; P \ C \\<^sup>1 D; is_class P D; Q D\ \ Q C \ + \ Q C" +(*<*)by (erule (2) subcls1_induct_aux) blast(*>*) + + +lemma subcls_C_Object: +assumes "class": "is_class P C" and wf: "wf_prog wf_md P" +shows "P \ C \\<^sup>* Object" +(*<*) +using wf "class" +proof(induct rule: subcls1_induct) + case Subcls + then show ?case by(simp add: converse_rtrancl_into_rtrancl) +qed fast +(*>*) + + +lemma is_type_pTs: +assumes "wf_prog wf_md P" and "(C,S,fs,ms) \ set P" and "(M,b,Ts,T,m) \ set ms" +shows "set Ts \ types P" +(*<*) +proof + from assms have "wf_mdecl wf_md P C (M,b,Ts,T,m)" + by (unfold wf_prog_def wf_cdecl_def) auto + hence "\t \ set Ts. is_type P t" by (unfold wf_mdecl_def) auto + moreover fix t assume "t \ set Ts" + ultimately have "is_type P t" by blast + thus "t \ types P" .. +qed +(*>*) + +lemma wf_supercls_distinct_app: +assumes wf:"wf_prog wf_md P" + and nObj: "C \ Object" and cls: "class P C = \(D, fs, ms)\" + and super: "supercls_lst P (C#Cs)" and dist: "distinct (C#Cs)" +shows "distinct (D#C#Cs)" +proof - + have "\ P \ D \\<^sup>* C" using subcls1_wfD[OF subcls1I[OF cls nObj] wf] + by (simp add: rtrancl_eq_or_trancl) + then show ?thesis using assms by auto +qed + + +subsection\ Well-formedness and method lookup \ + +lemma sees_wf_mdecl: +assumes wf: "wf_prog wf_md P" and sees: "P \ C sees M,b:Ts\T = m in D" +shows "wf_mdecl wf_md P D (M,b,Ts,T,m)" +(*<*) +using wf visible_method_exists[OF sees] proof(cases b) +qed (fastforce simp:wf_cdecl_def dest!:class_wf dest:map_of_SomeD)+ +(*>*) + +lemma sees_method_mono [rule_format (no_asm)]: +assumes sub: "P \ C' \\<^sup>* C" and wf: "wf_prog wf_md P" +shows "\D b Ts T m. P \ C sees M,b:Ts\T = m in D \ + (\D' Ts' T' m'. P \ C' sees M,b:Ts'\T' = m' in D' \ P \ Ts [\] Ts' \ P \ T' \ T)" +(*<*) + (is "\D b Ts T m. ?P C D b Ts T m \ ?Q C' D b Ts T m") +proof(rule disjE[OF rtranclD[OF sub]]) + assume "C' = C" + then show ?thesis using assms by fastforce +next + assume "C' \ C \ (C', C) \ (subcls1 P)\<^sup>+" + then have neq: "C' \ C" and subcls1: "(C', C) \ (subcls1 P)\<^sup>+" by simp+ + show ?thesis proof(induct rule: trancl_trans_induct[OF subcls1]) + case (2 x y z) + then have zy: "\D b Ts T m. ?P z D b Ts T m \ ?Q y D b Ts T m" by blast + have "\D b Ts T m. ?P z D b Ts T m \ ?Q x D b Ts T m" + proof - + fix D b Ts T m assume P: "?P z D b Ts T m" + then show "?Q x D b Ts T m" using zy[OF P] 2(2) + by(fast elim: widen_trans widens_trans) + qed + then show ?case by blast + next + case (1 x y) + have "\D b Ts T m. ?P y D b Ts T m \ ?Q x D b Ts T m" + proof - + fix D b Ts T m assume P: "?P y D b Ts T m" + then obtain Mm where sees: "P \ y sees_methods Mm" and + M: "Mm M = \((b, Ts, T, m), D)\" + by(clarsimp simp:Method_def) + obtain fs ms where nObj: "x \ Object" and + cls: "class P x = \(y, fs, ms)\" + using subcls1D[OF 1] by clarsimp + have x_meth: "P \ x sees_methods Mm ++ (map_option (\m. (m, x)) \ map_of ms)" + using sees_methods_rec[OF cls nObj sees] by simp + show "?Q x D b Ts T m" proof(cases "map_of ms M") + case None + then have "\m'. P \ x sees M, b : Ts\T = m' in D" using M x_meth + by(fastforce simp add:Method_def map_add_def split:option.split) + then show ?thesis by auto + next + case (Some a) + then obtain b' Ts' T' m' where a: "a = (b',Ts',T',m')" by(cases a) + then have "(\m' Mm. P \ y sees_methods Mm \ Mm M = \((b, Ts, T, m'), D)\) + \ b' = b \ P \ Ts [\] Ts' \ P \ T' \ T" + using nObj class_wf[OF cls wf] map_of_SomeD[OF Some] + by(clarsimp simp: wf_cdecl_def Method_def) fast + then show ?thesis using Some a sees M x_meth + by(fastforce simp:Method_def map_add_def split:option.split) + qed + qed + then show ?case by simp + qed +qed +(*>*) + + +lemma sees_method_mono2: + "\ P \ C' \\<^sup>* C; wf_prog wf_md P; + P \ C sees M,b:Ts\T = m in D; P \ C' sees M,b':Ts'\T' = m' in D' \ + \ b = b' \ P \ Ts [\] Ts' \ P \ T' \ T" +(*<*)by(blast dest:sees_method_mono sees_method_fun)(*>*) + +lemma mdecls_visible: +assumes wf: "wf_prog wf_md P" and "class": "is_class P C" +shows "\D fs ms. class P C = Some(D,fs,ms) + \ \Mm. P \ C sees_methods Mm \ (\(M,b,Ts,T,m) \ set ms. Mm M = Some((b,Ts,T,m),C))" +(*<*) +using wf "class" +proof (induct rule:subcls1_induct) + case Object + with wf have dfst:"distinct_fst ms" + by (unfold class_def wf_prog_def wf_cdecl_def) (fastforce dest:map_of_SomeD) + with dfst have "distinct_fst ms" + by(blast dest: distinct_fst_appendD) + with Object show ?case by(fastforce intro!: sees_methods_Object map_of_SomeI) +next + case Subcls + with wf have dfst:"distinct_fst ms" + by (unfold class_def wf_prog_def wf_cdecl_def) (fastforce dest:map_of_SomeD) + with dfst have "distinct_fst ms" + by(blast dest: distinct_fst_appendD) + with Subcls show ?case + by(fastforce elim:sees_methods_rec dest:subcls1D map_of_SomeI + simp:is_class_def) +qed +(*>*) + +lemma mdecl_visible: +assumes wf: "wf_prog wf_md P" and C: "(C,S,fs,ms) \ set P" and m: "(M,b,Ts,T,m) \ set ms" +shows "P \ C sees M,b:Ts\T = m in C" +(*<*) +proof - + from wf C have "class": "class P C = Some (S,fs,ms)" + by (auto simp add: wf_prog_def class_def is_class_def intro: map_of_SomeI) + from "class" have "is_class P C" by(auto simp:is_class_def) + with assms "class" show ?thesis + by(bestsimp simp:Method_def dest:mdecls_visible) +qed +(*>*) + + +lemma Call_lemma: +assumes sees: "P \ C sees M,b:Ts\T = m in D" and sub: "P \ C' \\<^sup>* C" and wf: "wf_prog wf_md P" +shows "\D' Ts' T' m'. + P \ C' sees M,b:Ts'\T' = m' in D' \ P \ Ts [\] Ts' \ P \ T' \ T \ P \ C' \\<^sup>* D' + \ is_type P T' \ (\T\set Ts'. is_type P T) \ wf_md P D' (M,b,Ts',T',m')" +(*<*) +using assms sees_method_mono[OF sub wf sees] +by(fastforce intro:sees_method_decl_above dest:sees_wf_mdecl + simp: wf_mdecl_def) +(*>*) + + +lemma wf_prog_lift: + assumes wf: "wf_prog (\P C bd. A P C bd) P" + and rule: + "\wf_md C M b Ts C T m bd. + wf_prog wf_md P \ + P \ C sees M,b:Ts\T = m in C \ + set Ts \ types P \ + bd = (M,b,Ts,T,m) \ + A P C bd \ + B P C bd" + shows "wf_prog (\P C bd. B P C bd) P" +(*<*) +proof - + have "\c. c\set P \ wf_cdecl A P c \ wf_cdecl B P c" + proof - + fix c assume "c\set P" and "wf_cdecl A P c" + then show "wf_cdecl B P c" + using rule[OF wf mdecl_visible[OF wf] is_type_pTs[OF wf]] + by (auto simp: wf_cdecl_def wf_mdecl_def) + qed + then show ?thesis using wf by (clarsimp simp: wf_prog_def) +qed +(*>*) + +lemma wf_sees_clinit: +assumes wf:"wf_prog wf_md P" and ex: "class P C = Some a" +shows "\m. P \ C sees clinit,Static:[] \ Void = m in C" +proof - + from ex obtain D fs ms where "a = (D,fs,ms)" by(cases a) + then have sP: "(C, D, fs, ms) \ set P" using ex map_of_SomeD[of P C a] by(simp add: class_def) + then have "wf_clinit ms" using assms by(unfold wf_prog_def wf_cdecl_def, auto) + then obtain m where sm: "(clinit, Static, [], Void, m) \ set ms" by (meson wf_clinit_def) + then have "P \ C sees clinit,Static:[] \ Void = m in C" + using mdecl_visible[OF wf sP sm] by simp + then show ?thesis by(rule exI) +qed +(*>*) + +lemma wf_sees_clinit1: +assumes wf:"wf_prog wf_md P" and ex: "class P C = Some a" +and "P \ C sees clinit,b:Ts \ T = m in D" +shows "b = Static \ Ts = [] \ T = Void \ D = C" +proof - + obtain m' where sees: "P \ C sees clinit,Static:[] \ Void = m' in C" + using wf_sees_clinit[OF wf ex] by clarify + then show ?thesis using sees wf by (meson assms(3) sees_method_fun) +qed + +lemma wf_NonStatic_nclinit: +assumes wf: "wf_prog wf_md P" and meth: "P \ C sees M,NonStatic:Ts\T=(mxs,mxl,ins,xt) in D" +shows "M \ clinit" +proof - + from sees_method_is_class[OF meth] obtain a where cls: "class P C = Some a" + by(clarsimp simp: is_class_def) + with wf wf_sees_clinit[OF wf cls] + obtain m where "P \ C sees clinit,Static:[]\Void=m in C" by clarsimp + with meth show ?thesis by(auto dest: sees_method_fun) +qed + +subsection\ Well-formedness and field lookup \ + +lemma wf_Fields_Ex: +assumes wf: "wf_prog wf_md P" and "is_class P C" +shows "\FDTs. P \ C has_fields FDTs" +(*<*) +using assms proof(induct rule:subcls1_induct) + case Object + then show ?case using class_Object[OF wf] + by(blast intro:has_fields_Object) +next + case Subcls + then show ?case by(blast intro:has_fields_rec dest:subcls1D) +qed +(*>*) + + +lemma has_fields_types: + "\ P \ C has_fields FDTs; (FD,b,T) \ set FDTs; wf_prog wf_md P \ \ is_type P T" +(*<*) +proof(induct rule:Fields.induct) +qed(fastforce dest!: class_wf simp: wf_cdecl_def wf_fdecl_def)+ +(*>*) + +lemma sees_field_is_type: + "\ P \ C sees F,b:T in D; wf_prog wf_md P \ \ is_type P T" +(*<*) + by (meson has_field_def has_fields_types has_visible_field map_of_SomeD) +(*>*) + + +lemma wf_syscls: + "set SystemClasses \ set P \ wf_syscls P" +(*<*) +by (force simp: image_def SystemClasses_def wf_syscls_def sys_xcpts_def + ObjectC_def NullPointerC_def ClassCastC_def OutOfMemoryC_def + NoClassDefFoundC_def + IncompatibleClassChangeC_def NoSuchFieldC_def NoSuchMethodC_def) +(*>*) + + +subsection\ Well-formedness and subclassing \ + +lemma wf_subcls_nCls: +assumes wf: "wf_prog wf_md P" and ns: "\ is_class P C" +shows "\ P \ D \\<^sup>* D'; D \ C \ \ D' \ C" +proof(induct rule: rtrancl.induct) + case (rtrancl_into_rtrancl a b c) + with ns show ?case by(clarsimp dest!: subcls1D wf_cdecl_supD[OF class_wf[OF _ wf]]) +qed(simp) + +lemma wf_subcls_nCls': +assumes wf: "wf_prog wf_md P" and ns: "\is_class P C\<^sub>0" +shows "\cd D'. cd \ set P \ \P \ fst cd \\<^sup>* C\<^sub>0" +proof - + fix cd D' assume cd: "cd \ set P" + then have cls: "is_class P (fst cd)" using class_exists_equiv is_class_def by blast + with wf_subcls_nCls[OF wf ns] ns show "\P \ fst cd \\<^sup>* C\<^sub>0" by(cases "fst cd = D'", auto) +qed + +lemma wf_nclass_nsub: + "\ wf_prog wf_md P; is_class P C; \is_class P C' \ \ \P \ C \\<^sup>* C'" + by(rule notI, auto dest: wf_subcls_nCls[where C=C' and D=C]) + +lemma wf_sys_xcpt_nsub_Start: +assumes wf: "wf_prog wf_md P" and ns: "\is_class P Start" and sx: "C \ sys_xcpts" +shows "\P \ C \\<^sup>* Start" +proof - + have Cns: "C \ Start" using Start_nsys_xcpts sx by clarsimp + show ?thesis using wf_subcls_nCls[OF wf ns _ Cns] by auto +qed + +end diff --git a/thys/JinjaDCI/Compiler/Compiler.thy b/thys/JinjaDCI/Compiler/Compiler.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/Compiler/Compiler.thy @@ -0,0 +1,72 @@ +(* Title: JinjaDCI/Compiler/Compiler.thy + + Author: Tobias Nipkow, Susannah Mansky + Copyright TUM 2003, UIUC 2019-20 + + Based on the Jinja theory Compiler/Compiler.thy by Tobias Nipkow +*) + +section \ Combining Stages 1 and 2 \ + +theory Compiler +imports Correctness1 Correctness2 +begin + +definition J2JVM :: "J_prog \ jvm_prog" +where + "J2JVM \ compP\<^sub>2 \ compP\<^sub>1" + +theorem comp_correct_NonStatic: +assumes wf: "wf_J_prog P" +and "method": "P \ C sees M,NonStatic:Ts\T = (pns,body) in C" +and eval: "P \ \body,(h,[this#pns [\] vs],sh)\ \ \e',(h',l',sh')\" +and sizes: "size vs = size pns + 1" "size rest = max_vars body" +shows "J2JVM P \ (None,h,[([],vs@rest,C,M,0,No_ics)],sh) -jvm\ (exception e',h',[],sh')" +(*<*) +proof - + let ?P\<^sub>1 = "compP\<^sub>1 P" + have nclinit: "M \ clinit" using wf_sees_clinit1[OF wf] visible_method_exists[OF "method"] + sees_method_idemp[OF "method"] by fastforce + have wf\<^sub>1: "wf_J\<^sub>1_prog ?P\<^sub>1" by(rule compP\<^sub>1_pres_wf[OF wf]) + have fv: "fv body \ set (this#pns)" + using wf_prog_wwf_prog[OF wf] "method" by(auto dest!:sees_wf_mdecl simp:wf_mdecl_def) + have init: "[this#pns [\] vs] \\<^sub>m [this#pns [\] vs@rest]" + using sizes by simp + have "?P\<^sub>1 \ C sees M,NonStatic: Ts\T = (compE\<^sub>1 (this#pns) body) in C" + using sees_method_compP[OF "method", of "\b (pns,e). compE\<^sub>1 (case b of NonStatic \ this#pns | Static \ pns) e"] + by(simp) + moreover obtain ls' where + "?P\<^sub>1 \\<^sub>1 \compE\<^sub>1 (this#pns) body, (h, vs@rest, sh)\ \ \fin\<^sub>1 e', (h',ls', sh')\" + using eval\<^sub>1_eval[OF wf_prog_wwf_prog[OF wf] eval fv init] sizes by auto + ultimately show ?thesis using comp\<^sub>2_correct[OF wf\<^sub>1] eval_final[OF eval] nclinit + by(fastforce simp add:J2JVM_def final_def) +qed +(*>*) + +theorem comp_correct_Static: +assumes wf: "wf_J_prog P" +and "method": "P \ C sees M,Static:Ts\T = (pns,body) in C" +and eval: "P \ \body,(h,[pns [\] vs],sh)\ \ \e',(h',l',sh')\" +and sizes: "size vs = size pns" "size rest = max_vars body" +and nclinit: "M \ clinit" +shows "J2JVM P \ (None,h,[([],vs@rest,C,M,0,No_ics)],sh) -jvm\ (exception e',h',[],sh')" +(*<*) +proof - + let ?P\<^sub>1 = "compP\<^sub>1 P" + have wf\<^sub>1: "wf_J\<^sub>1_prog ?P\<^sub>1" by(rule compP\<^sub>1_pres_wf[OF wf]) + have fv: "fv body \ set pns" + using wf_prog_wwf_prog[OF wf] "method" by(auto dest!:sees_wf_mdecl simp:wf_mdecl_def) + have init: "[pns [\] vs] \\<^sub>m [pns [\] vs@rest]" + using sizes by simp + have "?P\<^sub>1 \ C sees M,Static: Ts\T = (compE\<^sub>1 pns body) in C" + using sees_method_compP[OF "method", of "\b (pns,e). compE\<^sub>1 (case b of NonStatic \ this#pns | Static \ pns) e"] + by(simp) + moreover obtain ls' where + "?P\<^sub>1 \\<^sub>1 \compE\<^sub>1 pns body, (h, vs@rest, sh)\ \ \fin\<^sub>1 e', (h',ls', sh')\" + using eval\<^sub>1_eval[OF wf_prog_wwf_prog[OF wf] eval fv init] sizes by auto + ultimately show ?thesis using comp\<^sub>2_correct[OF wf\<^sub>1] eval_final[OF eval] nclinit + by(fastforce simp add:J2JVM_def final_def) +qed +(*>*) + +end diff --git a/thys/JinjaDCI/Compiler/Compiler1.thy b/thys/JinjaDCI/Compiler/Compiler1.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/Compiler/Compiler1.thy @@ -0,0 +1,72 @@ +(* Title: JinjaDCI/Compiler/Compiler1.thy + Author: Tobias Nipkow, Susannah Mansky + Copyright TUM 2003, UIUC 2019-20 + + Based on the Jinja theory Compiler/Compiler1.thy by Tobias Nipkow +*) + +section \ Compilation Stage 1 \ + +theory Compiler1 imports PCompiler J1 Hidden begin + +text\ Replacing variable names by indices. \ + +primrec compE\<^sub>1 :: "vname list \ expr \ expr\<^sub>1" + and compEs\<^sub>1 :: "vname list \ expr list \ expr\<^sub>1 list" where + "compE\<^sub>1 Vs (new C) = new C" +| "compE\<^sub>1 Vs (Cast C e) = Cast C (compE\<^sub>1 Vs e)" +| "compE\<^sub>1 Vs (Val v) = Val v" +| "compE\<^sub>1 Vs (e\<^sub>1 \bop\ e\<^sub>2) = (compE\<^sub>1 Vs e\<^sub>1) \bop\ (compE\<^sub>1 Vs e\<^sub>2)" +| "compE\<^sub>1 Vs (Var V) = Var(last_index Vs V)" +| "compE\<^sub>1 Vs (V:=e) = (last_index Vs V):= (compE\<^sub>1 Vs e)" +| "compE\<^sub>1 Vs (e\F{D}) = (compE\<^sub>1 Vs e)\F{D}" +| "compE\<^sub>1 Vs (C\\<^sub>sF{D}) = C\\<^sub>sF{D}" +| "compE\<^sub>1 Vs (e\<^sub>1\F{D}:=e\<^sub>2) = (compE\<^sub>1 Vs e\<^sub>1)\F{D} := (compE\<^sub>1 Vs e\<^sub>2)" +| "compE\<^sub>1 Vs (C\\<^sub>sF{D}:=e\<^sub>2) = C\\<^sub>sF{D} := (compE\<^sub>1 Vs e\<^sub>2)" +| "compE\<^sub>1 Vs (e\M(es)) = (compE\<^sub>1 Vs e)\M(compEs\<^sub>1 Vs es)" +| "compE\<^sub>1 Vs (C\\<^sub>sM(es)) = C\\<^sub>sM(compEs\<^sub>1 Vs es)" +| "compE\<^sub>1 Vs {V:T; e} = {(size Vs):T; compE\<^sub>1 (Vs@[V]) e}" +| "compE\<^sub>1 Vs (e\<^sub>1;;e\<^sub>2) = (compE\<^sub>1 Vs e\<^sub>1);;(compE\<^sub>1 Vs e\<^sub>2)" +| "compE\<^sub>1 Vs (if (e) e\<^sub>1 else e\<^sub>2) = if (compE\<^sub>1 Vs e) (compE\<^sub>1 Vs e\<^sub>1) else (compE\<^sub>1 Vs e\<^sub>2)" +| "compE\<^sub>1 Vs (while (e) c) = while (compE\<^sub>1 Vs e) (compE\<^sub>1 Vs c)" +| "compE\<^sub>1 Vs (throw e) = throw (compE\<^sub>1 Vs e)" +| "compE\<^sub>1 Vs (try e\<^sub>1 catch(C V) e\<^sub>2) = + try(compE\<^sub>1 Vs e\<^sub>1) catch(C (size Vs)) (compE\<^sub>1 (Vs@[V]) e\<^sub>2)" +| "compE\<^sub>1 Vs (INIT C (Cs,b) \ e) = INIT C (Cs,b) \ (compE\<^sub>1 Vs e)" +| "compE\<^sub>1 Vs (RI(C,e);Cs \ e') = RI(C,(compE\<^sub>1 Vs e));Cs \ (compE\<^sub>1 Vs e')" + +| "compEs\<^sub>1 Vs [] = []" +| "compEs\<^sub>1 Vs (e#es) = compE\<^sub>1 Vs e # compEs\<^sub>1 Vs es" + +lemma [simp]: "compEs\<^sub>1 Vs es = map (compE\<^sub>1 Vs) es" +(*<*)by(induct es type:list) simp_all(*>*) + +lemma [simp]: "\Vs. sub_RI (compE\<^sub>1 Vs e) = sub_RI e" + and [simp]: "\Vs. sub_RIs (compEs\<^sub>1 Vs es) = sub_RIs es" +proof(induct rule: sub_RI_sub_RIs_induct) qed(auto) + +primrec fin\<^sub>1:: "expr \ expr\<^sub>1" where + "fin\<^sub>1(Val v) = Val v" +| "fin\<^sub>1(throw e) = throw(fin\<^sub>1 e)" + +lemma comp_final: "final e \ compE\<^sub>1 Vs e = fin\<^sub>1 e" +(*<*)by(erule finalE, simp_all)(*>*) + + +lemma [simp]: + "\Vs. max_vars (compE\<^sub>1 Vs e) = max_vars e" +and "\Vs. max_varss (compEs\<^sub>1 Vs es) = max_varss es" +(*<*)by (induct e and es rule: max_vars.induct max_varss.induct) simp_all(*>*) + + +text\ Compiling programs: \ + +definition compP\<^sub>1 :: "J_prog \ J\<^sub>1_prog" +where + "compP\<^sub>1 \ compP (\b (pns,body). compE\<^sub>1 (case b of NonStatic \ this#pns | Static \ pns) body)" + +(*<*) +declare compP\<^sub>1_def[simp] +(*>*) + +end diff --git a/thys/JinjaDCI/Compiler/Compiler2.thy b/thys/JinjaDCI/Compiler/Compiler2.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/Compiler/Compiler2.thy @@ -0,0 +1,156 @@ +(* Title: JinjaDCI/Compiler/Compiler2.thy + Author: Tobias Nipkow, Susannah Mansky + Copyright TUM 2003, UIUC 2019-20 + + Based on the Jinja theory Compiler/Compiler2.thy by Tobias Nipkow +*) + +section \ Compilation Stage 2 \ + +theory Compiler2 +imports PCompiler J1 "../JVM/JVMExec" +begin + +lemma bop_expr_length_aux [simp]: + "length (case bop of Eq \ [CmpEq] | Add \ [IAdd]) = Suc 0" + by(cases bop, simp+) + +primrec compE\<^sub>2 :: "expr\<^sub>1 \ instr list" + and compEs\<^sub>2 :: "expr\<^sub>1 list \ instr list" where + "compE\<^sub>2 (new C) = [New C]" +| "compE\<^sub>2 (Cast C e) = compE\<^sub>2 e @ [Checkcast C]" +| "compE\<^sub>2 (Val v) = [Push v]" +| "compE\<^sub>2 (e\<^sub>1 \bop\ e\<^sub>2) = compE\<^sub>2 e\<^sub>1 @ compE\<^sub>2 e\<^sub>2 @ + (case bop of Eq \ [CmpEq] + | Add \ [IAdd])" +| "compE\<^sub>2 (Var i) = [Load i]" +| "compE\<^sub>2 (i:=e) = compE\<^sub>2 e @ [Store i, Push Unit]" +| "compE\<^sub>2 (e\F{D}) = compE\<^sub>2 e @ [Getfield F D]" +| "compE\<^sub>2 (C\\<^sub>sF{D}) = [Getstatic C F D]" +| "compE\<^sub>2 (e\<^sub>1\F{D} := e\<^sub>2) = + compE\<^sub>2 e\<^sub>1 @ compE\<^sub>2 e\<^sub>2 @ [Putfield F D, Push Unit]" +| "compE\<^sub>2 (C\\<^sub>sF{D} := e\<^sub>2) = + compE\<^sub>2 e\<^sub>2 @ [Putstatic C F D, Push Unit]" +| "compE\<^sub>2 (e\M(es)) = compE\<^sub>2 e @ compEs\<^sub>2 es @ [Invoke M (size es)]" +| "compE\<^sub>2 (C\\<^sub>sM(es)) = compEs\<^sub>2 es @ [Invokestatic C M (size es)]" +| "compE\<^sub>2 ({i:T; e}) = compE\<^sub>2 e" +| "compE\<^sub>2 (e\<^sub>1;;e\<^sub>2) = compE\<^sub>2 e\<^sub>1 @ [Pop] @ compE\<^sub>2 e\<^sub>2" +| "compE\<^sub>2 (if (e) e\<^sub>1 else e\<^sub>2) = + (let cnd = compE\<^sub>2 e; + thn = compE\<^sub>2 e\<^sub>1; + els = compE\<^sub>2 e\<^sub>2; + test = IfFalse (int(size thn + 2)); + thnex = Goto (int(size els + 1)) + in cnd @ [test] @ thn @ [thnex] @ els)" +| "compE\<^sub>2 (while (e) c) = + (let cnd = compE\<^sub>2 e; + bdy = compE\<^sub>2 c; + test = IfFalse (int(size bdy + 3)); + loop = Goto (-int(size bdy + size cnd + 2)) + in cnd @ [test] @ bdy @ [Pop] @ [loop] @ [Push Unit])" +| "compE\<^sub>2 (throw e) = compE\<^sub>2 e @ [instr.Throw]" +| "compE\<^sub>2 (try e\<^sub>1 catch(C i) e\<^sub>2) = + (let catch = compE\<^sub>2 e\<^sub>2 + in compE\<^sub>2 e\<^sub>1 @ [Goto (int(size catch)+2), Store i] @ catch)" +| "compE\<^sub>2 (INIT C (Cs,b) \ e) = []" +| "compE\<^sub>2 (RI(C,e);Cs \ e') = []" + +| "compEs\<^sub>2 [] = []" +| "compEs\<^sub>2 (e#es) = compE\<^sub>2 e @ compEs\<^sub>2 es" + +text\ Compilation of exception table. Is given start address of code +to compute absolute addresses necessary in exception table. \ + +primrec compxE\<^sub>2 :: "expr\<^sub>1 \ pc \ nat \ ex_table" + and compxEs\<^sub>2 :: "expr\<^sub>1 list \ pc \ nat \ ex_table" where + "compxE\<^sub>2 (new C) pc d = []" +| "compxE\<^sub>2 (Cast C e) pc d = compxE\<^sub>2 e pc d" +| "compxE\<^sub>2 (Val v) pc d = []" +| "compxE\<^sub>2 (e\<^sub>1 \bop\ e\<^sub>2) pc d = + compxE\<^sub>2 e\<^sub>1 pc d @ compxE\<^sub>2 e\<^sub>2 (pc + size(compE\<^sub>2 e\<^sub>1)) (d+1)" +| "compxE\<^sub>2 (Var i) pc d = []" +| "compxE\<^sub>2 (i:=e) pc d = compxE\<^sub>2 e pc d" +| "compxE\<^sub>2 (e\F{D}) pc d = compxE\<^sub>2 e pc d" +| "compxE\<^sub>2 (C\\<^sub>sF{D}) pc d = []" +| "compxE\<^sub>2 (e\<^sub>1\F{D} := e\<^sub>2) pc d = + compxE\<^sub>2 e\<^sub>1 pc d @ compxE\<^sub>2 e\<^sub>2 (pc + size(compE\<^sub>2 e\<^sub>1)) (d+1)" +| "compxE\<^sub>2 (C\\<^sub>sF{D} := e\<^sub>2) pc d = compxE\<^sub>2 e\<^sub>2 pc d" +| "compxE\<^sub>2 (e\M(es)) pc d = + compxE\<^sub>2 e pc d @ compxEs\<^sub>2 es (pc + size(compE\<^sub>2 e)) (d+1)" +| "compxE\<^sub>2 (C\\<^sub>sM(es)) pc d = compxEs\<^sub>2 es pc d" +| "compxE\<^sub>2 ({i:T; e}) pc d = compxE\<^sub>2 e pc d" +| "compxE\<^sub>2 (e\<^sub>1;;e\<^sub>2) pc d = + compxE\<^sub>2 e\<^sub>1 pc d @ compxE\<^sub>2 e\<^sub>2 (pc+size(compE\<^sub>2 e\<^sub>1)+1) d" +| "compxE\<^sub>2 (if (e) e\<^sub>1 else e\<^sub>2) pc d = + (let pc\<^sub>1 = pc + size(compE\<^sub>2 e) + 1; + pc\<^sub>2 = pc\<^sub>1 + size(compE\<^sub>2 e\<^sub>1) + 1 + in compxE\<^sub>2 e pc d @ compxE\<^sub>2 e\<^sub>1 pc\<^sub>1 d @ compxE\<^sub>2 e\<^sub>2 pc\<^sub>2 d)" +| "compxE\<^sub>2 (while (b) e) pc d = + compxE\<^sub>2 b pc d @ compxE\<^sub>2 e (pc+size(compE\<^sub>2 b)+1) d" +| "compxE\<^sub>2 (throw e) pc d = compxE\<^sub>2 e pc d" +| "compxE\<^sub>2 (try e\<^sub>1 catch(C i) e\<^sub>2) pc d = + (let pc\<^sub>1 = pc + size(compE\<^sub>2 e\<^sub>1) + in compxE\<^sub>2 e\<^sub>1 pc d @ compxE\<^sub>2 e\<^sub>2 (pc\<^sub>1+2) d @ [(pc,pc\<^sub>1,C,pc\<^sub>1+1,d)])" +| "compxE\<^sub>2 (INIT C (Cs, b) \ e) pc d = []" +| "compxE\<^sub>2 (RI(C, e);Cs \ e') pc d = []" + +| "compxEs\<^sub>2 [] pc d = []" +| "compxEs\<^sub>2 (e#es) pc d = compxE\<^sub>2 e pc d @ compxEs\<^sub>2 es (pc+size(compE\<^sub>2 e)) (d+1)" + +primrec max_stack :: "expr\<^sub>1 \ nat" + and max_stacks :: "expr\<^sub>1 list \ nat" where + "max_stack (new C) = 1" +| "max_stack (Cast C e) = max_stack e" +| "max_stack (Val v) = 1" +| "max_stack (e\<^sub>1 \bop\ e\<^sub>2) = max (max_stack e\<^sub>1) (max_stack e\<^sub>2) + 1" +| "max_stack (Var i) = 1" +| "max_stack (i:=e) = max_stack e" +| "max_stack (e\F{D}) = max_stack e" +| "max_stack (C\\<^sub>sF{D}) = 1" +| "max_stack (e\<^sub>1\F{D} := e\<^sub>2) = max (max_stack e\<^sub>1) (max_stack e\<^sub>2) + 1" +| "max_stack (C\\<^sub>sF{D} := e\<^sub>2) = max_stack e\<^sub>2" +| "max_stack (e\M(es)) = max (max_stack e) (max_stacks es) + 1" +| "max_stack (C\\<^sub>sM(es)) = max_stacks es + 1" +| "max_stack ({i:T; e}) = max_stack e" +| "max_stack (e\<^sub>1;;e\<^sub>2) = max (max_stack e\<^sub>1) (max_stack e\<^sub>2)" +| "max_stack (if (e) e\<^sub>1 else e\<^sub>2) = + max (max_stack e) (max (max_stack e\<^sub>1) (max_stack e\<^sub>2))" +| "max_stack (while (e) c) = max (max_stack e) (max_stack c)" +| "max_stack (throw e) = max_stack e" +| "max_stack (try e\<^sub>1 catch(C i) e\<^sub>2) = max (max_stack e\<^sub>1) (max_stack e\<^sub>2)" + +| "max_stacks [] = 0" +| "max_stacks (e#es) = max (max_stack e) (1 + max_stacks es)" + +lemma max_stack1': "\sub_RI e \ 1 \ max_stack e" +(*<*)by(induct e) (simp_all add:max_def)(*>*) + +lemma compE\<^sub>2_not_Nil': "\sub_RI e \ compE\<^sub>2 e \ []" +(*<*)by(induct e) auto(*>*) + +lemma compE\<^sub>2_nRet: "\i. i \ set (compE\<^sub>2 e\<^sub>1) \ i \ Return" + and "\i. i \ set (compEs\<^sub>2 es\<^sub>1) \ i \ Return" + by(induct rule: compE\<^sub>2.induct compEs\<^sub>2.induct, auto simp: nth_append split: bop.splits) + + +definition compMb\<^sub>2 :: "staticb \ expr\<^sub>1 \ jvm_method" +where + "compMb\<^sub>2 \ \b body. + let ins = compE\<^sub>2 body @ [Return]; + xt = compxE\<^sub>2 body 0 0 + in (max_stack body, max_vars body, ins, xt)" + +definition compP\<^sub>2 :: "J\<^sub>1_prog \ jvm_prog" +where + "compP\<^sub>2 \ compP compMb\<^sub>2" + +(*<*) +declare compP\<^sub>2_def [simp] +(*>*) + +lemma compMb\<^sub>2 [simp]: + "compMb\<^sub>2 b e = (max_stack e, max_vars e, + compE\<^sub>2 e @ [Return], compxE\<^sub>2 e 0 0)" +(*<*)by (simp add: compMb\<^sub>2_def)(*>*) + +end diff --git a/thys/JinjaDCI/Compiler/Correctness1.thy b/thys/JinjaDCI/Compiler/Correctness1.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/Compiler/Correctness1.thy @@ -0,0 +1,1058 @@ +(* Title: JinjaDCI/Compiler/Correctness1.thy + Author: Tobias Nipkow, Susannah Mansky + Copyright TUM 2003, UIUC 2019-20 + + Based on the Jinja theory Compiler/Correctness1.thy by Tobias Nipkow +*) + +section \ Correctness of Stage 1 \ + +theory Correctness1 +imports J1WellForm Compiler1 +begin + +subsection\Correctness of program compilation \ + +primrec unmod :: "expr\<^sub>1 \ nat \ bool" + and unmods :: "expr\<^sub>1 list \ nat \ bool" where +"unmod (new C) i = True" | +"unmod (Cast C e) i = unmod e i" | +"unmod (Val v) i = True" | +"unmod (e\<^sub>1 \bop\ e\<^sub>2) i = (unmod e\<^sub>1 i \ unmod e\<^sub>2 i)" | +"unmod (Var i) j = True" | +"unmod (i:=e) j = (i \ j \ unmod e j)" | +"unmod (e\F{D}) i = unmod e i" | +"unmod (C\\<^sub>sF{D}) i = True" | +"unmod (e\<^sub>1\F{D}:=e\<^sub>2) i = (unmod e\<^sub>1 i \ unmod e\<^sub>2 i)" | +"unmod (C\\<^sub>sF{D}:=e\<^sub>2) i = unmod e\<^sub>2 i" | +"unmod (e\M(es)) i = (unmod e i \ unmods es i)" | +"unmod (C\\<^sub>sM(es)) i = unmods es i" | +"unmod {j:T; e} i = unmod e i" | +"unmod (e\<^sub>1;;e\<^sub>2) i = (unmod e\<^sub>1 i \ unmod e\<^sub>2 i)" | +"unmod (if (e) e\<^sub>1 else e\<^sub>2) i = (unmod e i \ unmod e\<^sub>1 i \ unmod e\<^sub>2 i)" | +"unmod (while (e) c) i = (unmod e i \ unmod c i)" | +"unmod (throw e) i = unmod e i" | +"unmod (try e\<^sub>1 catch(C i) e\<^sub>2) j = (unmod e\<^sub>1 j \ (if i=j then False else unmod e\<^sub>2 j))" | +"unmod (INIT C (Cs,b) \ e) i = unmod e i" | +"unmod (RI(C,e);Cs \ e') i = (unmod e i \ unmod e' i)" | + +"unmods ([]) i = True" | +"unmods (e#es) i = (unmod e i \ unmods es i)" + +lemma hidden_unmod: "\Vs. hidden Vs i \ unmod (compE\<^sub>1 Vs e) i" and + "\Vs. hidden Vs i \ unmods (compEs\<^sub>1 Vs es) i" +(*<*) +apply(induct e and es rule: compE\<^sub>1.induct compEs\<^sub>1.induct) +apply (simp_all add:hidden_inacc) +apply(auto simp add:hidden_def) +done +(*>*) + + +lemma eval\<^sub>1_preserves_unmod: + "\ P \\<^sub>1 \e,(h,ls,sh)\ \ \e',(h',ls',sh')\; unmod e i; i < size ls \ + \ ls ! i = ls' ! i" +and "\ P \\<^sub>1 \es,(h,ls,sh)\ [\] \es',(h',ls',sh')\; unmods es i; i < size ls \ + \ ls ! i = ls' ! i" +(*<*) +proof(induct rule:eval\<^sub>1_evals\<^sub>1_inducts) + case (RInitInitFail\<^sub>1 e h l sh a h' l' sh' C sfs i sh'' D Cs e\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1) + have "final (throw a)" using eval\<^sub>1_final[OF RInitInitFail\<^sub>1.hyps(1)] by simp + then show ?case using RInitInitFail\<^sub>1 by(auto simp: eval\<^sub>1_preserves_len) +qed(auto dest!:eval\<^sub>1_preserves_len evals\<^sub>1_preserves_len split:if_split_asm) +(*>*) + + +lemma LAss_lem: + "\x \ set xs; size xs \ size ys \ + \ m\<^sub>1 \\<^sub>m m\<^sub>2(xs[\]ys) \ m\<^sub>1(x\y) \\<^sub>m m\<^sub>2(xs[\]ys[last_index xs x := y])" +(*<*) +by(simp add:map_le_def fun_upds_apply eq_sym_conv) +(*>*) +lemma Block_lem: +fixes l :: "'a \ 'b" +assumes 0: "l \\<^sub>m [Vs [\] ls]" + and 1: "l' \\<^sub>m [Vs [\] ls', V\v]" + and hidden: "V \ set Vs \ ls ! last_index Vs V = ls' ! last_index Vs V" + and size: "size ls = size ls'" "size Vs < size ls'" +shows "l'(V := l V) \\<^sub>m [Vs [\] ls']" +(*<*) +proof - + have "l'(V := l V) \\<^sub>m [Vs [\] ls', V\v](V := l V)" + using 1 by(rule map_le_upd) + also have "\ = [Vs [\] ls'](V := l V)" by simp + also have "\ \\<^sub>m [Vs [\] ls']" + proof (cases "l V") + case None thus ?thesis by simp + next + case (Some w) + hence "[Vs [\] ls] V = Some w" + using 0 by(force simp add: map_le_def split:if_splits) + hence VinVs: "V \ set Vs" and w: "w = ls ! last_index Vs V" + using size by(auto simp add:fun_upds_apply split:if_splits) + hence "w = ls' ! last_index Vs V" using hidden[OF VinVs] by simp + hence "[Vs [\] ls'](V := l V) = [Vs [\] ls']" using Some size VinVs + by(simp add: map_upds_upd_conv_last_index) + thus ?thesis by simp + qed + finally show ?thesis . +qed +(*>*) + +(*<*) +declare fun_upd_apply[simp del] +(*>*) + + +text\\noindent The main theorem: \ + +theorem assumes wf: "wwf_J_prog P" +shows eval\<^sub>1_eval: "P \ \e,(h,l,sh)\ \ \e',(h',l',sh')\ + \ (\Vs ls. \ fv e \ set Vs; l \\<^sub>m [Vs[\]ls]; size Vs + max_vars e \ size ls \ + \ \ls'. compP\<^sub>1 P \\<^sub>1 \compE\<^sub>1 Vs e,(h,ls,sh)\ \ \fin\<^sub>1 e',(h',ls',sh')\ \ l' \\<^sub>m [Vs[\]ls'])" +(*<*) + (is "_ \ (\Vs ls. PROP ?P e h l sh e' h' l' sh' Vs ls)" + is "_ \ (\Vs ls. \ _; _; _ \ \ \ls'. ?Post e h l sh e' h' l' sh' Vs ls ls')") +(*>*) + +and evals\<^sub>1_evals: "P \ \es,(h,l,sh)\ [\] \es',(h',l',sh')\ + \ (\Vs ls. \ fvs es \ set Vs; l \\<^sub>m [Vs[\]ls]; size Vs + max_varss es \ size ls \ + \ \ls'. compP\<^sub>1 P \\<^sub>1 \compEs\<^sub>1 Vs es,(h,ls,sh)\ [\] \compEs\<^sub>1 Vs es',(h',ls',sh')\ \ + l' \\<^sub>m [Vs[\]ls'])" +(*<*) + (is "_ \ (\Vs ls. PROP ?Ps es h l sh es' h' l' sh' Vs ls)" + is "_ \ (\Vs ls. \ _; _; _\ \ \ls'. ?Posts es h l sh es' h' l' sh' Vs ls ls')") +proof (induct rule:eval_evals_inducts) + case Nil thus ?case by(fastforce intro!:Nil\<^sub>1) +next + case (Cons e h l sh v h' l' sh' es es' h\<^sub>2 l\<^sub>2 sh\<^sub>2) + have "PROP ?P e h l sh (Val v) h' l' sh' Vs ls" by fact + with Cons.prems + obtain ls' where 1: "?Post e h l sh (Val v) h' l' sh' Vs ls ls'" + "size ls = size ls'" by(auto intro!:eval\<^sub>1_preserves_len) + have "PROP ?Ps es h' l' sh' es' h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls'" by fact + with 1 Cons.prems + obtain ls\<^sub>2 where 2: "?Posts es h' l' sh' es' h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls' ls\<^sub>2" by(auto) + from 1 2 Cons show ?case by(auto intro!:Cons\<^sub>1) +next + case ConsThrow thus ?case + by(fastforce intro!:ConsThrow\<^sub>1 dest: eval_final) +next + case (Block e h l V sh e' h' l' sh' T) + let ?Vs = "Vs @ [V]" + have IH: + "\fv e \ set ?Vs; l(V := None) \\<^sub>m [?Vs [\] ls]; + size ?Vs + max_vars e \ size ls\ + \ \ls'. compP\<^sub>1 P \\<^sub>1 \compE\<^sub>1 ?Vs e,(h,ls,sh)\ \ \fin\<^sub>1 e',(h', ls',sh')\ \ + l' \\<^sub>m [?Vs [\] ls']" and + fv: "fv {V:T; e} \ set Vs" and rel: "l \\<^sub>m [Vs [\] ls]" and + len: "length Vs + max_vars {V:T; e} \ length ls" by fact+ + have len': "length Vs < length ls" using len by auto + have "fv e \ set ?Vs" using fv by auto + moreover have "l(V := None) \\<^sub>m [?Vs [\] ls]" using rel len' by simp + moreover have "size ?Vs + max_vars e \ size ls" using len by simp + ultimately obtain ls' where + 1: "compP\<^sub>1 P \\<^sub>1 \compE\<^sub>1 ?Vs e,(h,ls,sh)\ \ \fin\<^sub>1 e',(h',ls',sh')\" + and rel': "l' \\<^sub>m [?Vs [\] ls']" using IH by blast + have [simp]: "length ls = length ls'" by(rule eval\<^sub>1_preserves_len[OF 1]) + show "\ls'. compP\<^sub>1 P \\<^sub>1 \compE\<^sub>1 Vs {V:T; e},(h,ls,sh)\ \ \fin\<^sub>1 e',(h',ls',sh')\ + \ l'(V := l V) \\<^sub>m [Vs [\] ls']" (is "\ls'. ?R ls'") + proof + show "?R ls'" + proof + show "compP\<^sub>1 P \\<^sub>1 \compE\<^sub>1 Vs {V:T; e},(h,ls,sh)\ \ \fin\<^sub>1 e',(h',ls',sh')\" + using 1 by(simp add:Block\<^sub>1) + next + show "l'(V := l V) \\<^sub>m [Vs [\] ls']" + proof - + have "l' \\<^sub>m [Vs [\] ls', V \ ls' ! length Vs]" + using len' rel' by simp + moreover + { assume VinVs: "V \ set Vs" + hence "hidden (Vs @ [V]) (last_index Vs V)" + by(rule hidden_last_index) + hence "unmod (compE\<^sub>1 (Vs @ [V]) e) (last_index Vs V)" + by(rule hidden_unmod) + moreover have "last_index Vs V < length ls" + using len' VinVs by simp + ultimately have "ls ! last_index Vs V = ls' ! last_index Vs V" + by(rule eval\<^sub>1_preserves_unmod[OF 1]) + } + ultimately show ?thesis using Block_lem[OF rel] len' by auto + qed + qed + qed +next + case (TryThrow e' h l sh a h' l' sh' D fs C V e\<^sub>2) + have "PROP ?P e' h l sh (Throw a) h' l' sh' Vs ls" by fact + with TryThrow.prems + obtain ls' where 1: "?Post e' h l sh (Throw a) h' l' sh' Vs ls ls'" by(auto) + show ?case using 1 TryThrow.hyps by(auto intro!:eval\<^sub>1_evals\<^sub>1.TryThrow\<^sub>1) +next + case (TryCatch e\<^sub>1 h l sh a h\<^sub>1 l\<^sub>1 sh\<^sub>1 D fs C e\<^sub>2 V e' h\<^sub>2 l\<^sub>2 sh\<^sub>2) + let ?e = "try e\<^sub>1 catch(C V) e\<^sub>2" + have IH\<^sub>1: "\fv e\<^sub>1 \ set Vs; l \\<^sub>m [Vs [\] ls]; + size Vs + max_vars e\<^sub>1 \ length ls\ + \ \ls\<^sub>1. compP\<^sub>1 P \\<^sub>1 \compE\<^sub>1 Vs e\<^sub>1,(h,ls,sh)\ \ + \fin\<^sub>1 (Throw a),(h\<^sub>1,ls\<^sub>1,sh\<^sub>1)\ \ + l\<^sub>1 \\<^sub>m [Vs [\] ls\<^sub>1]" and + fv: "fv ?e \ set Vs" and + rel: "l \\<^sub>m [Vs [\] ls]" and + len: "length Vs + max_vars ?e \ length ls" by fact+ + have "fv e\<^sub>1 \ set Vs" using fv by auto + moreover have "length Vs + max_vars e\<^sub>1 \ length ls" using len by(auto) + ultimately obtain ls\<^sub>1 where + 1: "compP\<^sub>1 P \\<^sub>1 \compE\<^sub>1 Vs e\<^sub>1,(h,ls,sh)\ \ \Throw a,(h\<^sub>1,ls\<^sub>1,sh\<^sub>1)\" + and rel\<^sub>1: "l\<^sub>1 \\<^sub>m [Vs [\] ls\<^sub>1]" using IH\<^sub>1 rel by fastforce + from 1 have [simp]: "size ls = size ls\<^sub>1" by(rule eval\<^sub>1_preserves_len) + let ?Vs = "Vs @ [V]" let ?ls = "(ls\<^sub>1[size Vs:=Addr a])" + have IH\<^sub>2: "\fv e\<^sub>2 \ set ?Vs; l\<^sub>1(V \ Addr a) \\<^sub>m [?Vs [\] ?ls]; + length ?Vs + max_vars e\<^sub>2 \ length ?ls\ \ \ls\<^sub>2. + compP\<^sub>1 P \\<^sub>1 \compE\<^sub>1 ?Vs e\<^sub>2,(h\<^sub>1,?ls,sh\<^sub>1)\ \ \fin\<^sub>1 e',(h\<^sub>2, ls\<^sub>2, sh\<^sub>2)\ \ + l\<^sub>2 \\<^sub>m [?Vs [\] ls\<^sub>2]" by fact + have len\<^sub>1: "size Vs < size ls\<^sub>1" using len by(auto) + have "fv e\<^sub>2 \ set ?Vs" using fv by auto + moreover have "l\<^sub>1(V \ Addr a) \\<^sub>m [?Vs [\] ?ls]" using rel\<^sub>1 len\<^sub>1 by simp + moreover have "length ?Vs + max_vars e\<^sub>2 \ length ?ls" using len by(auto) + ultimately obtain ls\<^sub>2 where + 2: "compP\<^sub>1 P \\<^sub>1 \compE\<^sub>1 ?Vs e\<^sub>2,(h\<^sub>1,?ls,sh\<^sub>1)\ \ \fin\<^sub>1 e',(h\<^sub>2, ls\<^sub>2, sh\<^sub>2)\" + and rel\<^sub>2: "l\<^sub>2 \\<^sub>m [?Vs [\] ls\<^sub>2]" using IH\<^sub>2 by blast + from 2 have [simp]: "size ls\<^sub>1 = size ls\<^sub>2" + by(fastforce dest: eval\<^sub>1_preserves_len) + show "\ls\<^sub>2. compP\<^sub>1 P \\<^sub>1 \compE\<^sub>1 Vs ?e,(h,ls,sh)\ \ \fin\<^sub>1 e',(h\<^sub>2,ls\<^sub>2,sh\<^sub>2)\ \ + l\<^sub>2(V := l\<^sub>1 V) \\<^sub>m [Vs [\] ls\<^sub>2]" (is "\ls\<^sub>2. ?R ls\<^sub>2") + proof + show "?R ls\<^sub>2" + proof + have hp: "h\<^sub>1 a = Some (D, fs)" by fact + have "P \ D \\<^sup>* C" by fact hence caught: "compP\<^sub>1 P \ D \\<^sup>* C" by simp + from TryCatch\<^sub>1[OF 1 _ caught len\<^sub>1 2, OF hp] + show "compP\<^sub>1 P \\<^sub>1 \compE\<^sub>1 Vs ?e,(h,ls,sh)\ \ \fin\<^sub>1 e',(h\<^sub>2,ls\<^sub>2,sh\<^sub>2)\" by simp + next + show "l\<^sub>2(V := l\<^sub>1 V) \\<^sub>m [Vs [\] ls\<^sub>2]" + proof - + have "l\<^sub>2 \\<^sub>m [Vs [\] ls\<^sub>2, V \ ls\<^sub>2 ! length Vs]" + using len\<^sub>1 rel\<^sub>2 by simp + moreover + { assume VinVs: "V \ set Vs" + hence "hidden (Vs @ [V]) (last_index Vs V)" by(rule hidden_last_index) + hence "unmod (compE\<^sub>1 (Vs @ [V]) e\<^sub>2) (last_index Vs V)" + by(rule hidden_unmod) + moreover have "last_index Vs V < length ?ls" + using len\<^sub>1 VinVs by simp + ultimately have "?ls ! last_index Vs V = ls\<^sub>2 ! last_index Vs V" + by(rule eval\<^sub>1_preserves_unmod[OF 2]) + moreover have "last_index Vs V < size Vs" using VinVs by simp + ultimately have "ls\<^sub>1 ! last_index Vs V = ls\<^sub>2 ! last_index Vs V" + using len\<^sub>1 by(simp del:size_last_index_conv) + } + ultimately show ?thesis using Block_lem[OF rel\<^sub>1] len\<^sub>1 by simp + qed + qed + qed +next + case Try thus ?case by(fastforce intro!:Try\<^sub>1) +next + case Throw thus ?case by(fastforce intro!:Throw\<^sub>1) +next + case ThrowNull thus ?case by(fastforce intro!:ThrowNull\<^sub>1) +next + case ThrowThrow thus ?case by(fastforce intro!:ThrowThrow\<^sub>1) +next + case (CondT e h l sh h\<^sub>1 l\<^sub>1 sh\<^sub>1 e\<^sub>1 e' h\<^sub>2 l\<^sub>2 sh\<^sub>2 e\<^sub>2) + have "PROP ?P e h l sh true h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls" by fact + with CondT.prems + obtain ls\<^sub>1 where 1: "?Post e h l sh true h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls ls\<^sub>1" + "size ls = size ls\<^sub>1" by(auto intro!:eval\<^sub>1_preserves_len) + have "PROP ?P e\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1 e' h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1" by fact + with 1 CondT.prems + obtain ls\<^sub>2 where 2: "?Post e\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1 e' h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1 ls\<^sub>2" by(auto) + from 1 2 show ?case by(auto intro!:CondT\<^sub>1) +next + case (CondF e h l sh h\<^sub>1 l\<^sub>1 sh\<^sub>1 e\<^sub>2 e' h\<^sub>2 l\<^sub>2 sh\<^sub>2 e\<^sub>1 Vs ls) + have "PROP ?P e h l sh false h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls" by fact + with CondF.prems + obtain ls\<^sub>1 where 1: "?Post e h l sh false h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls ls\<^sub>1" + "size ls = size ls\<^sub>1" by(auto intro!:eval\<^sub>1_preserves_len) + have "PROP ?P e\<^sub>2 h\<^sub>1 l\<^sub>1 sh\<^sub>1 e' h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1" by fact + with 1 CondF.prems + obtain ls\<^sub>2 where 2: "?Post e\<^sub>2 h\<^sub>1 l\<^sub>1 sh\<^sub>1 e' h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1 ls\<^sub>2" by(auto) + from 1 2 show ?case by(auto intro!:CondF\<^sub>1) +next + case CondThrow thus ?case by(fastforce intro!:CondThrow\<^sub>1) +next + case (Seq e h l sh v h\<^sub>1 l\<^sub>1 sh\<^sub>1 e\<^sub>1 e' h\<^sub>2 l\<^sub>2 sh\<^sub>2) + have "PROP ?P e h l sh (Val v) h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls" by fact + with Seq.prems + obtain ls\<^sub>1 where 1: "?Post e h l sh (Val v) h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls ls\<^sub>1" + "size ls = size ls\<^sub>1" by(auto intro!:eval\<^sub>1_preserves_len) + have "PROP ?P e\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1 e' h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1" by fact + with 1 Seq.prems + obtain ls\<^sub>2 where 2: "?Post e\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1 e' h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1 ls\<^sub>2" by(auto) + from 1 2 Seq show ?case by(auto intro!:Seq\<^sub>1) +next + case SeqThrow thus ?case by(fastforce intro!:SeqThrow\<^sub>1) +next + case WhileF thus ?case by(fastforce intro!:eval\<^sub>1_evals\<^sub>1.intros) +next + case (WhileT e h l sh h\<^sub>1 l\<^sub>1 sh\<^sub>1 c v h\<^sub>2 l\<^sub>2 sh\<^sub>2 e' h\<^sub>3 l\<^sub>3 sh\<^sub>3) + have "PROP ?P e h l sh true h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls" by fact + with WhileT.prems + obtain ls\<^sub>1 where 1: "?Post e h l sh true h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls ls\<^sub>1" + "size ls = size ls\<^sub>1" by(auto intro!:eval\<^sub>1_preserves_len) + have "PROP ?P c h\<^sub>1 l\<^sub>1 sh\<^sub>1 (Val v) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1" by fact + with 1 WhileT.prems + obtain ls\<^sub>2 where 2: "?Post c h\<^sub>1 l\<^sub>1 sh\<^sub>1 (Val v) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1 ls\<^sub>2" + "size ls\<^sub>1 = size ls\<^sub>2" by(auto intro!:eval\<^sub>1_preserves_len) + have "PROP ?P (While (e) c) h\<^sub>2 l\<^sub>2 sh\<^sub>2 e' h\<^sub>3 l\<^sub>3 sh\<^sub>3 Vs ls\<^sub>2" by fact + with 1 2 WhileT.prems + obtain ls\<^sub>3 where 3: "?Post (While (e) c) h\<^sub>2 l\<^sub>2 sh\<^sub>2 e' h\<^sub>3 l\<^sub>3 sh\<^sub>3 Vs ls\<^sub>2 ls\<^sub>3" by(auto) + from 1 2 3 show ?case by(auto intro!:WhileT\<^sub>1) +next + case (WhileBodyThrow e h l sh h\<^sub>1 l\<^sub>1 sh\<^sub>1 c e' h\<^sub>2 l\<^sub>2 sh\<^sub>2) + have "PROP ?P e h l sh true h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls" by fact + with WhileBodyThrow.prems + obtain ls\<^sub>1 where 1: "?Post e h l sh true h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls ls\<^sub>1" + "size ls = size ls\<^sub>1" by(auto intro!:eval\<^sub>1_preserves_len) + have "PROP ?P c h\<^sub>1 l\<^sub>1 sh\<^sub>1 (throw e') h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1" by fact + with 1 WhileBodyThrow.prems + obtain ls\<^sub>2 where 2: "?Post c h\<^sub>1 l\<^sub>1 sh\<^sub>1 (throw e') h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1 ls\<^sub>2" by auto + from 1 2 show ?case by(auto intro!:WhileBodyThrow\<^sub>1) +next + case WhileCondThrow thus ?case by(fastforce intro!:WhileCondThrow\<^sub>1) +next + case New thus ?case by(fastforce intro:eval\<^sub>1_evals\<^sub>1.intros) +next + case NewFail thus ?case by(fastforce intro:eval\<^sub>1_evals\<^sub>1.intros) +next + case NewInit then show ?case by(fastforce intro:eval\<^sub>1_evals\<^sub>1.intros) +next + case NewInitOOM then show ?case by(fastforce intro:eval\<^sub>1_evals\<^sub>1.intros) +next + case NewInitThrow then show ?case by(fastforce intro:eval\<^sub>1_evals\<^sub>1.intros) +next + case Cast thus ?case by(fastforce intro:eval\<^sub>1_evals\<^sub>1.intros) +next + case CastNull thus ?case by(fastforce intro:eval\<^sub>1_evals\<^sub>1.intros) +next + case CastThrow thus ?case by(fastforce intro:eval\<^sub>1_evals\<^sub>1.intros) +next + case (CastFail e h l sh a h\<^sub>1 l\<^sub>1 sh\<^sub>1 D fs C) + have "PROP ?P e h l sh (addr a) h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls" by fact + with CastFail.prems + obtain ls\<^sub>1 where 1: "?Post e h l sh (addr a) h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls ls\<^sub>1" by auto + show ?case using 1 CastFail.hyps + by(auto intro!:CastFail\<^sub>1[where D=D]) +next + case Val thus ?case by(fastforce intro:eval\<^sub>1_evals\<^sub>1.intros) +next + case (BinOp e h l sh v\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1 e\<^sub>1 v\<^sub>2 h\<^sub>2 l\<^sub>2 sh\<^sub>2 bop v) + have "PROP ?P e h l sh (Val v\<^sub>1) h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls" by fact + with BinOp.prems + obtain ls\<^sub>1 where 1: "?Post e h l sh (Val v\<^sub>1) h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls ls\<^sub>1" + "size ls = size ls\<^sub>1" by(auto intro!:eval\<^sub>1_preserves_len) + have "PROP ?P e\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1 (Val v\<^sub>2) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1" by fact + with 1 BinOp.prems + obtain ls\<^sub>2 where 2: "?Post e\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1 (Val v\<^sub>2) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1 ls\<^sub>2" by(auto) + from 1 2 BinOp show ?case by(auto intro!:BinOp\<^sub>1) +next + case (BinOpThrow2 e\<^sub>0 h l sh v\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1 e\<^sub>1 e h\<^sub>2 l\<^sub>2 sh\<^sub>2 bop) + have "PROP ?P e\<^sub>0 h l sh (Val v\<^sub>1) h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls" by fact + with BinOpThrow2.prems + obtain ls\<^sub>1 where 1: "?Post e\<^sub>0 h l sh (Val v\<^sub>1) h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls ls\<^sub>1" + "size ls = size ls\<^sub>1" by(auto intro!:eval\<^sub>1_preserves_len) + have "PROP ?P e\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1 (throw e) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1" by fact + with 1 BinOpThrow2.prems + obtain ls\<^sub>2 where 2: "?Post e\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1 (throw e) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1 ls\<^sub>2" by(auto) + from 1 2 BinOpThrow2 show ?case by(auto intro!:BinOpThrow\<^sub>2\<^sub>1) +next + case BinOpThrow1 thus ?case by(fastforce intro!:eval\<^sub>1_evals\<^sub>1.intros) +next + case Var thus ?case + by(force intro!:Var\<^sub>1 simp add: map_le_def fun_upds_apply) +next + case LAss thus ?case + by(fastforce simp add: LAss_lem intro:eval\<^sub>1_evals\<^sub>1.intros + dest:eval\<^sub>1_preserves_len) +next + case LAssThrow thus ?case by(fastforce intro:eval\<^sub>1_evals\<^sub>1.intros) +next + case FAcc thus ?case by(fastforce intro:eval\<^sub>1_evals\<^sub>1.intros) +next + case FAccNull thus ?case by(fastforce intro:eval\<^sub>1_evals\<^sub>1.intros) +next + case FAccThrow thus ?case by(fastforce intro:eval\<^sub>1_evals\<^sub>1.intros) +next + case (FAccNone e h l sh a h' l' sh' C fs F D) + have "PROP ?P e h l sh (addr a) h' l' sh' Vs ls" by fact + with FAccNone.prems + obtain ls\<^sub>2 where 2: "?Post e h l sh (addr a) h' l' sh' Vs ls ls\<^sub>2" by(auto) + from 2 FAccNone show ?case by(rule_tac x = ls\<^sub>2 in exI, auto elim!: FAccNone\<^sub>1) +next + case (FAccStatic e h l sh a h' l' sh' C fs F t D) + have "PROP ?P e h l sh (addr a) h' l' sh' Vs ls" by fact + with FAccStatic.prems + obtain ls\<^sub>2 where 2: "?Post e h l sh (addr a) h' l' sh' Vs ls ls\<^sub>2" by(auto) + from 2 FAccStatic show ?case by(rule_tac x = ls\<^sub>2 in exI, auto elim!: FAccStatic\<^sub>1) +next + case SFAcc then show ?case by(fastforce intro:eval\<^sub>1_evals\<^sub>1.intros) +next + case (SFAccInit C F t D sh h l v' h' l' sh' sfs i v) + have "PROP ?P (INIT D ([D],False) \ unit) h l sh (Val v') h' l' sh' Vs ls" by fact + with SFAccInit.prems + obtain ls\<^sub>2 where 1: "?Post (INIT D ([D],False) \ unit) h l sh (Val v') h' l' sh' Vs ls ls\<^sub>2" by(auto) + from 1 SFAccInit show ?case by(rule_tac x = ls\<^sub>2 in exI, auto intro: SFAccInit\<^sub>1) +next + case (SFAccInitThrow C F t D sh h l a h' l' sh') + have "PROP ?P (INIT D ([D],False) \ unit) h l sh (throw a) h' l' sh' Vs ls" by fact + with SFAccInitThrow.prems + obtain ls\<^sub>2 where 1: "?Post (INIT D ([D],False) \ unit) h l sh (throw a) h' l' sh' Vs ls ls\<^sub>2" by(auto) + from 1 SFAccInitThrow show ?case by(rule_tac x = ls\<^sub>2 in exI, auto intro: SFAccInitThrow\<^sub>1) +next + case SFAccNone then show ?case by(fastforce intro:eval\<^sub>1_evals\<^sub>1.intros) +next + case SFAccNonStatic then show ?case by(fastforce intro:eval\<^sub>1_evals\<^sub>1.intros) +next + case (FAss e\<^sub>1 h l sh a h\<^sub>1 l\<^sub>1 sh\<^sub>1 e\<^sub>2 v h\<^sub>2 l\<^sub>2 sh\<^sub>2 C fs fs' F D h\<^sub>2') + have "PROP ?P e\<^sub>1 h l sh (addr a) h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls" by fact + with FAss.prems + obtain ls\<^sub>1 where 1: "?Post e\<^sub>1 h l sh (addr a) h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls ls\<^sub>1" + "size ls = size ls\<^sub>1" by(auto intro!:eval\<^sub>1_preserves_len) + have "PROP ?P e\<^sub>2 h\<^sub>1 l\<^sub>1 sh\<^sub>1 (Val v) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1" by fact + with 1 FAss.prems + obtain ls\<^sub>2 where 2: "?Post e\<^sub>2 h\<^sub>1 l\<^sub>1 sh\<^sub>1 (Val v) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1 ls\<^sub>2" by(auto) + from 1 2 FAss show ?case by(auto intro!:FAss\<^sub>1) +next + case (FAssNull e\<^sub>1 h l sh h\<^sub>1 l\<^sub>1 sh\<^sub>1 e\<^sub>2 v h\<^sub>2 l\<^sub>2 sh\<^sub>2 F D) + have "PROP ?P e\<^sub>1 h l sh null h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls" by fact + with FAssNull.prems + obtain ls\<^sub>1 where 1: "?Post e\<^sub>1 h l sh null h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls ls\<^sub>1" + "size ls = size ls\<^sub>1" by(auto intro!:eval\<^sub>1_preserves_len) + have "PROP ?P e\<^sub>2 h\<^sub>1 l\<^sub>1 sh\<^sub>1 (Val v) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1" by fact + with 1 FAssNull.prems + obtain ls\<^sub>2 where 2: "?Post e\<^sub>2 h\<^sub>1 l\<^sub>1 sh\<^sub>1 (Val v) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1 ls\<^sub>2" by(auto) + from 1 2 FAssNull show ?case by(auto intro!:FAssNull\<^sub>1) +next + case FAssThrow1 thus ?case by(fastforce intro:eval\<^sub>1_evals\<^sub>1.intros) +next + case (FAssThrow2 e\<^sub>1 h l sh v h\<^sub>1 l\<^sub>1 sh\<^sub>1 e\<^sub>2 e h\<^sub>2 l\<^sub>2 sh\<^sub>2 F D) + have "PROP ?P e\<^sub>1 h l sh (Val v) h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls" by fact + with FAssThrow2.prems + obtain ls\<^sub>1 where 1: "?Post e\<^sub>1 h l sh (Val v) h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls ls\<^sub>1" + "size ls = size ls\<^sub>1" by(auto intro!:eval\<^sub>1_preserves_len) + have "PROP ?P e\<^sub>2 h\<^sub>1 l\<^sub>1 sh\<^sub>1 (throw e) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1" by fact + with 1 FAssThrow2.prems + obtain ls\<^sub>2 where 2: "?Post e\<^sub>2 h\<^sub>1 l\<^sub>1 sh\<^sub>1 (throw e) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1 ls\<^sub>2" by(auto) + from 1 2 FAssThrow2 show ?case by(auto intro!:FAssThrow\<^sub>2\<^sub>1) +next + case (FAssNone e\<^sub>1 h l sh a h' l' sh' e\<^sub>2 v h\<^sub>2 l\<^sub>2 sh\<^sub>2 C fs F D) + have "PROP ?P e\<^sub>1 h l sh (addr a) h' l' sh' Vs ls" by fact + with FAssNone.prems + obtain ls\<^sub>1 where 1: "?Post e\<^sub>1 h l sh (addr a) h' l' sh' Vs ls ls\<^sub>1" + "size ls = size ls\<^sub>1" by(auto intro!:eval\<^sub>1_preserves_len) + have "PROP ?P e\<^sub>2 h' l' sh' (Val v) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1" by fact + with 1 FAssNone.prems + obtain ls\<^sub>2 where 2: "?Post e\<^sub>2 h' l' sh' (Val v) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1 ls\<^sub>2" by(auto) + from 1 2 FAssNone show ?case by(auto intro!:FAssNone\<^sub>1) +next + case (FAssStatic e\<^sub>1 h l sh a h' l' sh' e\<^sub>2 v h\<^sub>2 l\<^sub>2 sh\<^sub>2 C fs F t D) + have "PROP ?P e\<^sub>1 h l sh (addr a) h' l' sh' Vs ls" by fact + with FAssStatic.prems + obtain ls\<^sub>1 where 1: "?Post e\<^sub>1 h l sh (addr a) h' l' sh' Vs ls ls\<^sub>1" + "size ls = size ls\<^sub>1" by(auto intro!:eval\<^sub>1_preserves_len) + have "PROP ?P e\<^sub>2 h' l' sh' (Val v) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1" by fact + with 1 FAssStatic.prems + obtain ls\<^sub>2 where 2: "?Post e\<^sub>2 h' l' sh' (Val v) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1 ls\<^sub>2" by(auto) + from 1 2 FAssStatic show ?case by(auto intro!:FAssStatic\<^sub>1) +next + case SFAss then show ?case by(fastforce intro:eval\<^sub>1_evals\<^sub>1.intros) +next + case (SFAssInit e\<^sub>2 h l sh v h\<^sub>1 l\<^sub>1 sh\<^sub>1 C F t D v' h' l' sh' sfs i sfs' sh'') + have "PROP ?P e\<^sub>2 h l sh (Val v) h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls" by fact + with SFAssInit.prems + obtain ls\<^sub>1 where 1: "?Post e\<^sub>2 h l sh (Val v) h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls ls\<^sub>1" "length ls = length ls\<^sub>1" + by(auto intro!:eval\<^sub>1_preserves_len) + then have Init_size: "length Vs \ length ls\<^sub>1" using SFAssInit.prems(3) by linarith + have "PROP ?P (INIT D ([D],False) \ unit) h\<^sub>1 l\<^sub>1 sh\<^sub>1 (Val v') h' l' sh' Vs ls\<^sub>1" by fact + with 1 Init_size SFAssInit.prems + obtain ls\<^sub>2 where 2: "?Post (INIT D ([D],False) \ unit) h\<^sub>1 l\<^sub>1 sh\<^sub>1 (Val v') h' l' sh' Vs ls\<^sub>1 ls\<^sub>2" + by auto + from 1 2 SFAssInit show ?case + by(auto simp add: comp_def + intro!: SFAssInit\<^sub>1 dest!:evals_final) +next + case (SFAssInitThrow e\<^sub>2 h l sh v h\<^sub>1 l\<^sub>1 sh\<^sub>1 C F t D a h\<^sub>2 l\<^sub>2 sh\<^sub>2) + have "PROP ?P e\<^sub>2 h l sh (Val v) h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls" by fact + with SFAssInitThrow.prems + obtain ls\<^sub>1 where 1: "?Post e\<^sub>2 h l sh (Val v) h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls ls\<^sub>1" "length ls = length ls\<^sub>1" + by(auto intro!:eval\<^sub>1_preserves_len) + then have Init_size: "length Vs \ length ls\<^sub>1" using SFAssInitThrow.prems(3) by linarith + have "PROP ?P (INIT D ([D],False) \ unit) h\<^sub>1 l\<^sub>1 sh\<^sub>1 (throw a) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1" by fact + with 1 Init_size SFAssInitThrow.prems + obtain ls\<^sub>2 where 2: "?Post (INIT D ([D],False) \ unit) h\<^sub>1 l\<^sub>1 sh\<^sub>1 (throw a) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1 ls\<^sub>2" + by auto + from 1 2 SFAssInitThrow show ?case + by(auto simp add: comp_def + intro!: SFAssInitThrow\<^sub>1 dest!:evals_final) +next + case SFAssThrow then show ?case by(fastforce intro:eval\<^sub>1_evals\<^sub>1.intros) +next + case (SFAssNone e\<^sub>2 h l sh v h\<^sub>2 l\<^sub>2 sh\<^sub>2 C F D) + have "PROP ?P e\<^sub>2 h l sh (Val v) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls" by fact + with SFAssNone.prems + obtain ls\<^sub>2 where 2: "?Post e\<^sub>2 h l sh (Val v) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls ls\<^sub>2" by(auto) + from 2 SFAssNone show ?case by(rule_tac x = ls\<^sub>2 in exI, auto elim!: SFAssNone\<^sub>1) +next + case SFAssNonStatic then show ?case by(fastforce intro:eval\<^sub>1_evals\<^sub>1.intros) +next + case (CallNull e h l sh h\<^sub>1 l\<^sub>1 sh\<^sub>1 es vs h\<^sub>2 l\<^sub>2 sh\<^sub>2 M) + have "PROP ?P e h l sh null h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls" by fact + with CallNull.prems + obtain ls\<^sub>1 where 1: "?Post e h l sh null h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls ls\<^sub>1" + "size ls = size ls\<^sub>1" by(auto intro!:eval\<^sub>1_preserves_len) + have "PROP ?Ps es h\<^sub>1 l\<^sub>1 sh\<^sub>1 (map Val vs) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1" by fact + with 1 CallNull.prems + obtain ls\<^sub>2 where 2: "?Posts es h\<^sub>1 l\<^sub>1 sh\<^sub>1 (map Val vs) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1 ls\<^sub>2" by(auto) + from 1 2 CallNull show ?case + by (auto simp add: comp_def elim!: CallNull\<^sub>1) +next + case CallObjThrow thus ?case by(fastforce intro:eval\<^sub>1_evals\<^sub>1.intros) +next + case (CallParamsThrow e h l sh v h\<^sub>1 l\<^sub>1 sh\<^sub>1 es vs ex es' h\<^sub>2 l\<^sub>2 sh\<^sub>2 M) + have "PROP ?P e h l sh (Val v) h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls" by fact + with CallParamsThrow.prems + obtain ls\<^sub>1 where 1: "?Post e h l sh (Val v) h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls ls\<^sub>1" + "size ls = size ls\<^sub>1" by(auto intro!:eval\<^sub>1_preserves_len) + have "PROP ?Ps es h\<^sub>1 l\<^sub>1 sh\<^sub>1 (map Val vs @ throw ex # es') h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1" by fact + with 1 CallParamsThrow.prems + obtain ls\<^sub>2 where 2: "?Posts es h\<^sub>1 l\<^sub>1 sh\<^sub>1 (map Val vs @ throw ex # es') h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1 ls\<^sub>2" by(auto) + from 1 2 CallParamsThrow show ?case + by (auto simp add: comp_def + elim!: CallParamsThrow\<^sub>1 dest!:evals_final) +next + case (CallNone e h l sh a h\<^sub>1 l\<^sub>1 sh\<^sub>1 ps vs h\<^sub>2 l\<^sub>2 sh\<^sub>2 C fs M) + have "PROP ?P e h l sh (addr a) h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls" by fact + with CallNone.prems + obtain ls\<^sub>1 where 1: "?Post e h l sh (addr a) h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls ls\<^sub>1" + "size ls = size ls\<^sub>1" by(auto intro!:eval\<^sub>1_preserves_len) + have "PROP ?Ps ps h\<^sub>1 l\<^sub>1 sh\<^sub>1 (map Val vs) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1" by fact + with 1 CallNone.prems + obtain ls\<^sub>2 where 2: "?Posts ps h\<^sub>1 l\<^sub>1 sh\<^sub>1 (map Val vs) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1 ls\<^sub>2" by(auto) + from 1 2 CallNone show ?case + by (auto simp add: comp_def + elim!: CallNone\<^sub>1 dest!:evals_final sees_method_compPD) +next + case (CallStatic e h l sh a h\<^sub>1 l\<^sub>1 sh\<^sub>1 ps vs h\<^sub>2 l\<^sub>2 sh\<^sub>2 C fs M Ts T pns body D) + have "PROP ?P e h l sh (addr a) h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls" by fact + with CallStatic.prems + obtain ls\<^sub>1 where 1: "?Post e h l sh (addr a) h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls ls\<^sub>1" + "size ls = size ls\<^sub>1" by(auto intro!:eval\<^sub>1_preserves_len) + let ?Vs = pns + have mdecl: "P \ C sees M,Static: Ts\T = (pns, body) in D" by fact + have mdecl\<^sub>1: "compP\<^sub>1 P \ C sees M,Static: Ts\T = (compE\<^sub>1 ?Vs body) in D" + using sees_method_compP[OF mdecl, of "\b (pns,e). compE\<^sub>1 (case b of NonStatic \ this#pns | Static \ pns) e"] + by(simp) + have "PROP ?Ps ps h\<^sub>1 l\<^sub>1 sh\<^sub>1 (map Val vs) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1" by fact + with 1 CallStatic.prems + obtain ls\<^sub>2 where 2: "?Posts ps h\<^sub>1 l\<^sub>1 sh\<^sub>1 (map Val vs) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1 ls\<^sub>2" by(auto) + from 1 2 mdecl\<^sub>1 CallStatic show ?case + by (auto simp add: comp_def + elim!: CallStatic\<^sub>1 dest!:evals_final) +next + case (Call e h l sh a h\<^sub>1 l\<^sub>1 sh\<^sub>1 es vs h\<^sub>2 l\<^sub>2 sh\<^sub>2 C fs M Ts T pns body D l\<^sub>2' b' h\<^sub>3 l\<^sub>3 sh\<^sub>3) + have "PROP ?P e h l sh (addr a) h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls" by fact + with Call.prems + obtain ls\<^sub>1 where 1: "?Post e h l sh (addr a) h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls ls\<^sub>1" + "size ls = size ls\<^sub>1" by(auto intro!:eval\<^sub>1_preserves_len) + have "PROP ?Ps es h\<^sub>1 l\<^sub>1 sh\<^sub>1 (map Val vs) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1" by fact + with 1 Call.prems + obtain ls\<^sub>2 where 2: "?Posts es h\<^sub>1 l\<^sub>1 sh\<^sub>1 (map Val vs) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1 ls\<^sub>2" + "size ls\<^sub>1 = size ls\<^sub>2" by(auto intro!:evals\<^sub>1_preserves_len) + let ?Vs = "this#pns" + let ?ls = "Addr a # vs @ replicate (max_vars body) undefined" + have mdecl: "P \ C sees M,NonStatic: Ts\T = (pns, body) in D" by fact + have fv_body: "fv body \ set ?Vs" and wf_size: "size Ts = size pns" + using wf mdecl by(auto dest!:sees_wf_mdecl simp:wf_mdecl_def) + have mdecl\<^sub>1: "compP\<^sub>1 P \ C sees M,NonStatic: Ts\T = (compE\<^sub>1 ?Vs body) in D" + using sees_method_compP[OF mdecl, of "\b (pns,e). compE\<^sub>1 (case b of NonStatic \ this#pns | Static \ pns) e"] + by(simp) + have [simp]: "l\<^sub>2' = [this \ Addr a, pns [\] vs]" by fact + have Call_size: "size vs = size pns" by fact + have "PROP ?P body h\<^sub>2 l\<^sub>2' sh\<^sub>2 b' h\<^sub>3 l\<^sub>3 sh\<^sub>3 ?Vs ?ls" by fact + with 1 2 fv_body Call_size Call.prems + obtain ls\<^sub>3 where 3: "?Post body h\<^sub>2 l\<^sub>2' sh\<^sub>2 b' h\<^sub>3 l\<^sub>3 sh\<^sub>3 ?Vs ?ls ls\<^sub>3" by(auto) + have hp: "h\<^sub>2 a = Some (C, fs)" by fact + from 1 2 3 hp mdecl\<^sub>1 wf_size Call_size show ?case + by(fastforce simp add: comp_def + intro!: Call\<^sub>1 dest!:evals_final) +next + case (SCallParamsThrow es h l sh vs ex es' h\<^sub>2 l\<^sub>2 sh\<^sub>2 C M) + have "PROP ?Ps es h l sh (map Val vs @ throw ex # es') h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls" by fact + with SCallParamsThrow.prems + obtain ls\<^sub>2 where 2: "?Posts es h l sh (map Val vs @ throw ex # es') h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls ls\<^sub>2" by(auto) + from 2 SCallParamsThrow show ?case + by (fastforce simp add: comp_def + elim!: SCallParamsThrow\<^sub>1 dest!:evals_final) +next + case (SCall ps h l sh vs h\<^sub>2 l\<^sub>2 sh\<^sub>2 C M Ts T pns body D sfs l\<^sub>2' e' h\<^sub>3 l\<^sub>3 sh\<^sub>3) + have "PROP ?Ps ps h l sh (map Val vs) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls" by fact + with SCall.prems + obtain ls\<^sub>2 where 2: "?Posts ps h l sh (map Val vs) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls ls\<^sub>2" + "size ls = size ls\<^sub>2" by(auto intro!:evals\<^sub>1_preserves_len) + let ?Vs = "pns" + let ?ls = "vs @ replicate (max_vars body) undefined" + have mdecl: "P \ C sees M,Static: Ts\T = (pns, body) in D" by fact + have fv_body: "fv body \ set ?Vs" and wf_size: "size Ts = size pns" + using wf mdecl by(auto dest!:sees_wf_mdecl simp:wf_mdecl_def) + have mdecl\<^sub>1: "compP\<^sub>1 P \ C sees M,Static: Ts\T = (compE\<^sub>1 ?Vs body) in D" + using sees_method_compP[OF mdecl, of "\b (pns,e). compE\<^sub>1 (case b of NonStatic \ this#pns | Static \ pns) e"] + by(simp) + have [simp]: "l\<^sub>2' = [pns [\] vs]" by fact + have SCall_size: "size vs = size pns" by fact + have "PROP ?P body h\<^sub>2 l\<^sub>2' sh\<^sub>2 e' h\<^sub>3 l\<^sub>3 sh\<^sub>3 ?Vs ?ls" by fact + with 2 fv_body SCall_size SCall.prems + obtain ls\<^sub>3 where 3: "?Post body h\<^sub>2 l\<^sub>2' sh\<^sub>2 e' h\<^sub>3 l\<^sub>3 sh\<^sub>3 ?Vs ?ls ls\<^sub>3" by(auto) + have shp: "sh\<^sub>2 D = \(sfs, Done)\ \ M = clinit \ sh\<^sub>2 D = \(sfs, Processing)\" by fact + from 2 3 shp mdecl\<^sub>1 wf_size SCall_size show ?case + by(fastforce simp add: comp_def + intro!: SCall\<^sub>1 dest!:evals_final) +next + case (SCallNone ps h l sh vs h' l' sh' C M) + have "PROP ?Ps ps h l sh (map Val vs) h' l' sh' Vs ls" by fact + with SCallNone.prems + obtain ls\<^sub>2 where 2: "?Posts ps h l sh (map Val vs) h' l' sh' Vs ls ls\<^sub>2" by(auto) + from 2 SCallNone show ?case + by(rule_tac x = ls\<^sub>2 in exI, + auto simp add: comp_def elim!: SCallNone\<^sub>1 dest!:evals_final sees_method_compPD) +next + case (SCallNonStatic ps h l sh vs h' l' sh' C M Ts T pns body D) + let ?Vs = "this#pns" + have mdecl: "P \ C sees M,NonStatic: Ts\T = (pns, body) in D" by fact + have mdecl\<^sub>1: "compP\<^sub>1 P \ C sees M,NonStatic: Ts\T = (compE\<^sub>1 ?Vs body) in D" + using sees_method_compP[OF mdecl, of "\b (pns,e). compE\<^sub>1 (case b of NonStatic \ this#pns | Static \ pns) e"] + by(simp) + have "PROP ?Ps ps h l sh (map Val vs) h' l' sh' Vs ls" by fact + with SCallNonStatic.prems + obtain ls\<^sub>2 where 2: "?Posts ps h l sh (map Val vs) h' l' sh' Vs ls ls\<^sub>2" by(auto) + from 2 mdecl\<^sub>1 SCallNonStatic show ?case + by (auto simp add: comp_def + elim!: SCallNonStatic\<^sub>1 dest!:evals_final) +next + case (SCallInitThrow ps h l sh vs h\<^sub>1 l\<^sub>1 sh\<^sub>1 C M Ts T pns body D a h\<^sub>2 l\<^sub>2 sh\<^sub>2) + have "PROP ?Ps ps h l sh (map Val vs) h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls" by fact + with SCallInitThrow.prems + obtain ls\<^sub>1 where 1: "?Posts ps h l sh (map Val vs) h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls ls\<^sub>1" "length ls = length ls\<^sub>1" + by(auto intro!:evals\<^sub>1_preserves_len) + then have Init_size: "length Vs \ length ls\<^sub>1" using SCallInitThrow.prems(3) by linarith + have "PROP ?P (INIT D ([D],False) \ unit) h\<^sub>1 l\<^sub>1 sh\<^sub>1 (throw a) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1" by fact + with 1 Init_size SCallInitThrow.prems + obtain ls\<^sub>2 where 2: "?Post (INIT D ([D],False) \ unit) h\<^sub>1 l\<^sub>1 sh\<^sub>1 (throw a) h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1 ls\<^sub>2" + by auto + let ?Vs = "pns" + have mdecl: "P \ C sees M,Static: Ts\T = (pns, body) in D" by fact + have mdecl\<^sub>1: "compP\<^sub>1 P \ C sees M,Static: Ts\T = (compE\<^sub>1 ?Vs body) in D" + using sees_method_compP[OF mdecl, of "\b (pns,e). compE\<^sub>1 (case b of NonStatic \ this#pns | Static \ pns) e"] + by(simp) + from 1 2 mdecl\<^sub>1 SCallInitThrow show ?case + by(auto simp add: comp_def + intro!: SCallInitThrow\<^sub>1 dest!:evals_final) +next + case (SCallInit ps h l sh vs h\<^sub>1 l\<^sub>1 sh\<^sub>1 C M Ts T pns body D v' h\<^sub>2 l\<^sub>2 sh\<^sub>2 l\<^sub>2' e' h\<^sub>3 l\<^sub>3 sh\<^sub>3) + have "PROP ?Ps ps h l sh (map Val vs) h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls" by fact + with SCallInit.prems + obtain ls\<^sub>1 where 1: "?Posts ps h l sh (map Val vs) h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls ls\<^sub>1" "length ls = length ls\<^sub>1" + by(auto intro!:evals\<^sub>1_preserves_len) + then have Init_size: "length Vs \ length ls\<^sub>1" using SCallInit.prems(3) by linarith + have "PROP ?P (INIT D ([D],False) \ unit) h\<^sub>1 l\<^sub>1 sh\<^sub>1 (Val v') h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1" by fact + with 1 Init_size SCallInit.prems + obtain ls\<^sub>2 where 2: "?Post (INIT D ([D],False) \ unit) h\<^sub>1 l\<^sub>1 sh\<^sub>1 (Val v') h\<^sub>2 l\<^sub>2 sh\<^sub>2 Vs ls\<^sub>1 ls\<^sub>2" + by auto + let ?Vs = "pns" + let ?ls = "vs @ replicate (max_vars body) undefined" + have mdecl: "P \ C sees M,Static: Ts\T = (pns, body) in D" by fact + have fv_body: "fv body \ set ?Vs" and wf_size: "size Ts = size pns" + using wf mdecl by(auto dest!:sees_wf_mdecl simp:wf_mdecl_def) + have mdecl\<^sub>1: "compP\<^sub>1 P \ C sees M,Static: Ts\T = (compE\<^sub>1 ?Vs body) in D" + using sees_method_compP[OF mdecl, of "\b (pns,e). compE\<^sub>1 (case b of NonStatic \ this#pns | Static \ pns) e"] + by(simp) + have [simp]: "l\<^sub>2' = [pns [\] vs]" by fact + have SCall_size: "size vs = size pns" by fact + have nclinit: "M \ clinit" by fact + have "PROP ?P body h\<^sub>2 l\<^sub>2' sh\<^sub>2 e' h\<^sub>3 l\<^sub>3 sh\<^sub>3 ?Vs ?ls" by fact + with 2 fv_body SCall_size SCallInit.prems + obtain ls\<^sub>3 where 3: "?Post body h\<^sub>2 l\<^sub>2' sh\<^sub>2 e' h\<^sub>3 l\<^sub>3 sh\<^sub>3 ?Vs ?ls ls\<^sub>3" by(auto) + have shp: "\sfs. sh\<^sub>1 D = \(sfs, Done)\" by fact + from 1 2 3 shp mdecl\<^sub>1 wf_size SCall_size nclinit show ?case + by(auto simp add: comp_def + intro!: SCallInit\<^sub>1 dest!:evals_final) +next +\ \ init cases \ + case InitFinal then show ?case by(fastforce intro:eval\<^sub>1_evals\<^sub>1.intros) +next + case (InitNone sh C C' Cs e h l e' h' l' sh') + let ?sh1 = "sh(C \ (sblank P C, Prepared))" + have "PROP ?P (INIT C' (C # Cs,False) \ e) h l ?sh1 e' h' l' sh' Vs ls" by fact + with InitNone.prems + obtain ls\<^sub>2 where 2: "?Post (INIT C' (C # Cs,False) \ e) h l ?sh1 e' h' l' sh' Vs ls ls\<^sub>2" by(auto) + from 2 InitNone show ?case by (auto elim!: InitNone\<^sub>1) +next + case InitDone then show ?case by(fastforce intro:eval\<^sub>1_evals\<^sub>1.intros) +next + case InitProcessing then show ?case by(fastforce intro:eval\<^sub>1_evals\<^sub>1.intros) +next + case InitError then show ?case by(fastforce intro:eval\<^sub>1_evals\<^sub>1.intros) +next + case InitObject then show ?case by(fastforce intro:eval\<^sub>1_evals\<^sub>1.intros) +next + case (InitNonObject sh C sfs D fs ms sh' C' Cs e h l e' h1 l1 sh1) + let ?f = "(\b (pns,body). compE\<^sub>1 (case b of NonStatic \ this#pns | Static \ pns) body)" + have cls: "class (compP ?f P) C = \(D,fs,map (compM ?f) ms)\" + by(rule class_compP[OF InitNonObject.hyps(3)]) + have "PROP ?P (INIT C' (D # C # Cs,False) \ e) h l sh' e' h1 l1 sh1 Vs ls" by fact + with InitNonObject.prems + obtain ls\<^sub>2 where 2: "?Post (INIT C' (D # C # Cs,False) \ e) h l sh' e' h1 l1 sh1 Vs ls ls\<^sub>2" by(auto) + from 2 cls InitNonObject show ?case by (auto elim!: InitNonObject\<^sub>1) +next + case InitRInit then show ?case by(fastforce intro:eval\<^sub>1_evals\<^sub>1.intros) +next + case (RInit e h l sh v h' l' sh' C sfs i sh'' C' Cs e' e\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1) + have "PROP ?P e h l sh (Val v) h' l' sh' Vs ls" by fact + with RInit.prems + obtain ls\<^sub>1 where 1: "?Post e h l sh (Val v) h' l' sh' Vs ls ls\<^sub>1" + "size ls = size ls\<^sub>1" by(auto intro!:eval\<^sub>1_preserves_len) + have "PROP ?P (INIT C' (Cs,True) \ e') h' l' sh'' e\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls\<^sub>1" by fact + with 1 RInit.prems + obtain ls\<^sub>2 where 2: "?Post (INIT C' (Cs,True) \ e') h' l' sh'' e\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls\<^sub>1 ls\<^sub>2" by(auto) + from 1 2 RInit show ?case by (auto elim!: RInit\<^sub>1) +next + case (RInitInitFail e h l sh a h' l' sh' C sfs i sh'' D Cs e' e\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1) + have "PROP ?P e h l sh (throw a) h' l' sh' Vs ls" by fact + with RInitInitFail.prems + obtain ls\<^sub>1 where 1: "?Post e h l sh (throw a) h' l' sh' Vs ls ls\<^sub>1" + "size ls = size ls\<^sub>1" by(auto intro!:eval\<^sub>1_preserves_len) + have fv: "fv (RI (D,throw a) ; Cs \ e') \ set Vs" + using RInitInitFail.hyps(1) eval_final RInitInitFail.prems(1) subset_eq by fastforce + have l': "l' \\<^sub>m [Vs [\] ls\<^sub>1]" by (simp add: "1"(1)) + have "PROP ?P (RI (D,throw a) ; Cs \ e') h' l' sh'' e\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls\<^sub>1" by fact + with 1 eval_final[OF RInitInitFail.hyps(1)] RInitInitFail.prems + obtain ls\<^sub>2 where 2: "?Post (RI (D,throw a) ; Cs \ e') h' l' sh'' e\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1 Vs ls\<^sub>1 ls\<^sub>2" + by fastforce + from 1 2 RInitInitFail show ?case + by(fastforce simp add: comp_def + intro!: RInitInitFail\<^sub>1 dest!:eval_final) +next + case RInitFailFinal then show ?case by(fastforce intro:eval\<^sub>1_evals\<^sub>1.intros) +qed +(*>*) + + +subsection\Preservation of well-formedness\ + +text\ The compiler preserves well-formedness. Is less trivial than it +may appear. We start with two simple properties: preservation of +well-typedness \ + +lemma compE\<^sub>1_pres_wt: "\Vs Ts U. + \ P,[Vs[\]Ts] \ e :: U; size Ts = size Vs \ + \ compP f P,Ts \\<^sub>1 compE\<^sub>1 Vs e :: U" +and "\Vs Ts Us. + \ P,[Vs[\]Ts] \ es [::] Us; size Ts = size Vs \ + \ compP f P,Ts \\<^sub>1 compEs\<^sub>1 Vs es [::] Us" +(*<*) +apply(induct e and es rule: compE\<^sub>1.induct compEs\<^sub>1.induct) +apply clarsimp +apply(fastforce) +apply clarsimp +apply(fastforce split:bop.splits) +apply (fastforce simp:map_upds_apply_eq_Some split:if_split_asm) +apply (fastforce simp:map_upds_apply_eq_Some split:if_split_asm) +apply(fastforce) +apply(fastforce) +apply(fastforce) +apply(fastforce) +apply (fastforce dest!: sees_method_compP[where f = f]) +apply (fastforce dest!: sees_method_compP[where f = f]) +apply (fastforce simp:nth_append) +apply (fastforce) +apply (fastforce) +apply (fastforce) +apply (fastforce) +apply (fastforce simp:nth_append) +apply simp +apply simp +apply simp +apply (fastforce) +done +(*>*) + +text\\noindent and the correct block numbering: \ + +lemma \: "\Vs n. size Vs = n \ \ (compE\<^sub>1 Vs e) n" +and \s: "\Vs n. size Vs = n \ \s (compEs\<^sub>1 Vs es) n" +(*<*)by (induct e and es rule: \.induct \s.induct) + (force | simp,metis length_append_singleton)+(*>*) + +text\ The main complication is preservation of definite assignment +@{term"\"}. \ + +lemma image_last_index: "A \ set(xs@[x]) \ last_index (xs @ [x]) ` A = + (if x \ A then insert (size xs) (last_index xs ` (A-{x})) else last_index xs ` A)" +(*<*) +by(auto simp:image_def) +(*>*) + + +lemma A_compE\<^sub>1_None[simp]: + "\Vs. \ e = None \ \ (compE\<^sub>1 Vs e) = None" +and "\Vs. \s es = None \ \s (compEs\<^sub>1 Vs es) = None" +(*<*)by(induct e and es rule: compE\<^sub>1.induct compEs\<^sub>1.induct)(auto simp:hyperset_defs)(*>*) + + +lemma A_compE\<^sub>1: + "\A Vs. \ \ e = \A\; fv e \ set Vs \ \ \ (compE\<^sub>1 Vs e) = \last_index Vs ` A\" +and "\A Vs. \ \s es = \A\; fvs es \ set Vs \ \ \s (compEs\<^sub>1 Vs es) = \last_index Vs ` A\" +(*<*) +proof(induct e and es rule: fv.induct fvs.induct) + case (Block V' T e) + hence "fv e \ set (Vs@[V'])" by fastforce + moreover obtain B where "\ e = \B\" + using Block.prems by(simp add: hyperset_defs) + moreover from calculation have "B \ set (Vs@[V'])" by(auto dest!:A_fv) + ultimately show ?case using Block + by(auto simp add: hyperset_defs image_last_index last_index_size_conv) +next + case (TryCatch e\<^sub>1 C V' e\<^sub>2) + hence fve\<^sub>2: "fv e\<^sub>2 \ set (Vs@[V'])" by auto + show ?case + proof (cases "\ e\<^sub>1") + assume A\<^sub>1: "\ e\<^sub>1 = None" + then obtain A\<^sub>2 where A\<^sub>2: "\ e\<^sub>2 = \A\<^sub>2\" using TryCatch + by(simp add:hyperset_defs) + hence "A\<^sub>2 \ set (Vs@[V'])" using TryCatch.prems A_fv[OF A\<^sub>2] by simp blast + thus ?thesis using TryCatch fve\<^sub>2 A\<^sub>1 A\<^sub>2 + by(auto simp add:hyperset_defs image_last_index last_index_size_conv) + next + fix A\<^sub>1 assume A\<^sub>1: "\ e\<^sub>1 = \A\<^sub>1\" + show ?thesis + proof (cases "\ e\<^sub>2") + assume A\<^sub>2: "\ e\<^sub>2 = None" + then show ?case using TryCatch A\<^sub>1 by(simp add:hyperset_defs) + next + fix A\<^sub>2 assume A\<^sub>2: "\ e\<^sub>2 = \A\<^sub>2\" + have "A\<^sub>1 \ set Vs" using TryCatch.prems A_fv[OF A\<^sub>1] by simp blast + moreover + have "A\<^sub>2 \ set (Vs@[V'])" using TryCatch.prems A_fv[OF A\<^sub>2] by simp blast + ultimately show ?thesis using TryCatch A\<^sub>1 A\<^sub>2 + by (auto simp add: Diff_subset_conv last_index_size_conv subsetD hyperset_defs + dest!: sym [of _ A]) + qed + qed +next + case (Cond e e\<^sub>1 e\<^sub>2) + { assume "\ e = None \ \ e\<^sub>1 = None \ \ e\<^sub>2 = None" + hence ?case using Cond by(auto simp add:hyperset_defs image_Un) + } + moreover + { fix A A\<^sub>1 A\<^sub>2 + assume "\ e = \A\" and A\<^sub>1: "\ e\<^sub>1 = \A\<^sub>1\" and A\<^sub>2: "\ e\<^sub>2 = \A\<^sub>2\" + moreover + have "A\<^sub>1 \ set Vs" using Cond.prems A_fv[OF A\<^sub>1] by simp blast + moreover + have "A\<^sub>2 \ set Vs" using Cond.prems A_fv[OF A\<^sub>2] by simp blast + ultimately have ?case using Cond + by(auto simp add:hyperset_defs image_Un + inj_on_image_Int[OF inj_on_last_index]) + } + ultimately show ?case by fastforce +qed (auto simp add:hyperset_defs) +(*>*) + + +lemma D_None[iff]: "\ (e::'a exp) None" and [iff]: "\s (es::'a exp list) None" +(*<*)by(induct e and es rule: \.induct \s.induct)(simp_all)(*>*) + + +lemma D_last_index_compE\<^sub>1: + "\A Vs. \ A \ set Vs; fv e \ set Vs \ \ + \ e \A\ \ \ (compE\<^sub>1 Vs e) \last_index Vs ` A\" +and "\A Vs. \ A \ set Vs; fvs es \ set Vs \ \ + \s es \A\ \ \s (compEs\<^sub>1 Vs es) \last_index Vs ` A\" +(*<*) +proof(induct e and es rule: \.induct \s.induct) + case (BinOp e\<^sub>1 bop e\<^sub>2) + hence IH\<^sub>1: "\ (compE\<^sub>1 Vs e\<^sub>1) \last_index Vs ` A\" by simp + show ?case + proof (cases "\ e\<^sub>1") + case None thus ?thesis using BinOp by simp + next + case (Some A\<^sub>1) + have indexA\<^sub>1: "\ (compE\<^sub>1 Vs e\<^sub>1) = \last_index Vs ` A\<^sub>1\" + using A_compE\<^sub>1[OF Some] BinOp.prems by auto + have "A \ A\<^sub>1 \ set Vs" using BinOp.prems A_fv[OF Some] by auto + hence "\ (compE\<^sub>1 Vs e\<^sub>2) \last_index Vs ` (A \ A\<^sub>1)\" using BinOp Some by auto + hence "\ (compE\<^sub>1 Vs e\<^sub>2) \last_index Vs ` A \ last_index Vs ` A\<^sub>1\" + by(simp add: image_Un) + thus ?thesis using IH\<^sub>1 indexA\<^sub>1 by auto + qed +next + case (FAss e\<^sub>1 F D e\<^sub>2) + hence IH\<^sub>1: "\ (compE\<^sub>1 Vs e\<^sub>1) \last_index Vs ` A\" by simp + show ?case + proof (cases "\ e\<^sub>1") + case None thus ?thesis using FAss by simp + next + case (Some A\<^sub>1) + have indexA\<^sub>1: "\ (compE\<^sub>1 Vs e\<^sub>1) = \last_index Vs ` A\<^sub>1\" + using A_compE\<^sub>1[OF Some] FAss.prems by auto + have "A \ A\<^sub>1 \ set Vs" using FAss.prems A_fv[OF Some] by auto + hence "\ (compE\<^sub>1 Vs e\<^sub>2) \last_index Vs ` (A \ A\<^sub>1)\" using FAss Some by auto + hence "\ (compE\<^sub>1 Vs e\<^sub>2) \last_index Vs ` A \ last_index Vs ` A\<^sub>1\" + by(simp add: image_Un) + thus ?thesis using IH\<^sub>1 indexA\<^sub>1 by auto + qed +next + case (Call e\<^sub>1 M es) + hence IH\<^sub>1: "\ (compE\<^sub>1 Vs e\<^sub>1) \last_index Vs ` A\" by simp + show ?case + proof (cases "\ e\<^sub>1") + case None thus ?thesis using Call by simp + next + case (Some A\<^sub>1) + have indexA\<^sub>1: "\ (compE\<^sub>1 Vs e\<^sub>1) = \last_index Vs ` A\<^sub>1\" + using A_compE\<^sub>1[OF Some] Call.prems by auto + have "A \ A\<^sub>1 \ set Vs" using Call.prems A_fv[OF Some] by auto + hence "\s (compEs\<^sub>1 Vs es) \last_index Vs ` (A \ A\<^sub>1)\" using Call Some by auto + hence "\s (compEs\<^sub>1 Vs es) \last_index Vs ` A \ last_index Vs ` A\<^sub>1\" + by(simp add: image_Un) + thus ?thesis using IH\<^sub>1 indexA\<^sub>1 by auto + qed +next + case (TryCatch e\<^sub>1 C V e\<^sub>2) + have "\ A\{V} \ set(Vs@[V]); fv e\<^sub>2 \ set(Vs@[V]); \ e\<^sub>2 \A\{V}\\ \ + \ (compE\<^sub>1 (Vs@[V]) e\<^sub>2) \last_index (Vs@[V]) ` (A\{V})\" by fact + hence "\ (compE\<^sub>1 (Vs@[V]) e\<^sub>2) \last_index (Vs@[V]) ` (A\{V})\" + using TryCatch.prems by(simp add:Diff_subset_conv) + moreover have "last_index (Vs@[V]) ` A \ last_index Vs ` A \ {size Vs}" + using TryCatch.prems by(auto simp add: image_last_index split:if_split_asm) + ultimately show ?case using TryCatch + by(auto simp:hyperset_defs elim!:D_mono') +next + case (Seq e\<^sub>1 e\<^sub>2) + hence IH\<^sub>1: "\ (compE\<^sub>1 Vs e\<^sub>1) \last_index Vs ` A\" by simp + show ?case + proof (cases "\ e\<^sub>1") + case None thus ?thesis using Seq by simp + next + case (Some A\<^sub>1) + have indexA\<^sub>1: "\ (compE\<^sub>1 Vs e\<^sub>1) = \last_index Vs ` A\<^sub>1\" + using A_compE\<^sub>1[OF Some] Seq.prems by auto + have "A \ A\<^sub>1 \ set Vs" using Seq.prems A_fv[OF Some] by auto + hence "\ (compE\<^sub>1 Vs e\<^sub>2) \last_index Vs ` (A \ A\<^sub>1)\" using Seq Some by auto + hence "\ (compE\<^sub>1 Vs e\<^sub>2) \last_index Vs ` A \ last_index Vs ` A\<^sub>1\" + by(simp add: image_Un) + thus ?thesis using IH\<^sub>1 indexA\<^sub>1 by auto + qed +next + case (Cond e e\<^sub>1 e\<^sub>2) + hence IH\<^sub>1: "\ (compE\<^sub>1 Vs e) \last_index Vs ` A\" by simp + show ?case + proof (cases "\ e") + case None thus ?thesis using Cond by simp + next + case (Some B) + have indexB: "\ (compE\<^sub>1 Vs e) = \last_index Vs ` B\" + using A_compE\<^sub>1[OF Some] Cond.prems by auto + have "A \ B \ set Vs" using Cond.prems A_fv[OF Some] by auto + hence "\ (compE\<^sub>1 Vs e\<^sub>1) \last_index Vs ` (A \ B)\" + and "\ (compE\<^sub>1 Vs e\<^sub>2) \last_index Vs ` (A \ B)\" + using Cond Some by auto + hence "\ (compE\<^sub>1 Vs e\<^sub>1) \last_index Vs ` A \ last_index Vs ` B\" + and "\ (compE\<^sub>1 Vs e\<^sub>2) \last_index Vs ` A \ last_index Vs ` B\" + by(simp add: image_Un)+ + thus ?thesis using IH\<^sub>1 indexB by auto + qed +next + case (While e\<^sub>1 e\<^sub>2) + hence IH\<^sub>1: "\ (compE\<^sub>1 Vs e\<^sub>1) \last_index Vs ` A\" by simp + show ?case + proof (cases "\ e\<^sub>1") + case None thus ?thesis using While by simp + next + case (Some A\<^sub>1) + have indexA\<^sub>1: "\ (compE\<^sub>1 Vs e\<^sub>1) = \last_index Vs ` A\<^sub>1\" + using A_compE\<^sub>1[OF Some] While.prems by auto + have "A \ A\<^sub>1 \ set Vs" using While.prems A_fv[OF Some] by auto + hence "\ (compE\<^sub>1 Vs e\<^sub>2) \last_index Vs ` (A \ A\<^sub>1)\" using While Some by auto + hence "\ (compE\<^sub>1 Vs e\<^sub>2) \last_index Vs ` A \ last_index Vs ` A\<^sub>1\" + by(simp add: image_Un) + thus ?thesis using IH\<^sub>1 indexA\<^sub>1 by auto + qed +next + case (Block V T e) + have "\ A-{V} \ set(Vs@[V]); fv e \ set(Vs@[V]); \ e \A-{V}\ \ \ + \ (compE\<^sub>1 (Vs@[V]) e) \last_index (Vs@[V]) ` (A-{V})\" by fact + hence "\ (compE\<^sub>1 (Vs@[V]) e) \last_index (Vs@[V]) ` (A-{V})\" + using Block.prems by(simp add:Diff_subset_conv) + moreover have "size Vs \ last_index Vs ` A" + using Block.prems by(auto simp add:image_def size_last_index_conv) + ultimately show ?case using Block + by(auto simp add: image_last_index Diff_subset_conv hyperset_defs elim!: D_mono') +next + case (Cons_exp e\<^sub>1 es) + hence IH\<^sub>1: "\ (compE\<^sub>1 Vs e\<^sub>1) \last_index Vs ` A\" by simp + show ?case + proof (cases "\ e\<^sub>1") + case None thus ?thesis using Cons_exp by simp + next + case (Some A\<^sub>1) + have indexA\<^sub>1: "\ (compE\<^sub>1 Vs e\<^sub>1) = \last_index Vs ` A\<^sub>1\" + using A_compE\<^sub>1[OF Some] Cons_exp.prems by auto + have "A \ A\<^sub>1 \ set Vs" using Cons_exp.prems A_fv[OF Some] by auto + hence "\s (compEs\<^sub>1 Vs es) \last_index Vs ` (A \ A\<^sub>1)\" using Cons_exp Some by auto + hence "\s (compEs\<^sub>1 Vs es) \last_index Vs ` A \ last_index Vs ` A\<^sub>1\" + by(simp add: image_Un) + thus ?thesis using IH\<^sub>1 indexA\<^sub>1 by auto + qed +qed (simp_all add:hyperset_defs) +(*>*) + + +lemma last_index_image_set: "distinct xs \ last_index xs ` set xs = {..*) + + +lemma D_compE\<^sub>1: + "\ \ e \set Vs\; fv e \ set Vs; distinct Vs \ \ \ (compE\<^sub>1 Vs e) \{.." +(*<*)by(fastforce dest!: D_last_index_compE\<^sub>1[OF subset_refl] simp add:last_index_image_set)(*>*) + + +lemma D_compE\<^sub>1': +assumes "\ e \set(V#Vs)\" and "fv e \ set(V#Vs)" and "distinct(V#Vs)" +shows "\ (compE\<^sub>1 (V#Vs) e) \{..length Vs}\" +(*<*) +proof - + have "{..size Vs} = {..1) +qed +(*>*) + +lemma compP\<^sub>1_pres_wf: "wf_J_prog P \ wf_J\<^sub>1_prog (compP\<^sub>1 P)" +(*<*) +apply simp +apply(rule wf_prog_compPI) + prefer 2 apply assumption +apply(case_tac m) +apply(simp add:wf_mdecl_def wf_J\<^sub>1_mdecl_def) +apply(clarify) apply(rename_tac C M b Ts T x1 x2 pns body) +apply(case_tac b) + apply clarsimp + apply(frule WT_fv) + apply(auto intro!: compE\<^sub>1_pres_wt D_compE\<^sub>1 \)[1] +apply clarsimp +apply(frule WT_fv) +apply(fastforce intro!: compE\<^sub>1_pres_wt D_compE\<^sub>1' \) +done +(*>*) + + +end diff --git a/thys/JinjaDCI/Compiler/Correctness2.thy b/thys/JinjaDCI/Compiler/Correctness2.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/Compiler/Correctness2.thy @@ -0,0 +1,3202 @@ +(* Title: JinjaDCI/Compiler/Correctness2.thy + Author: Tobias Nipkow, Susannah Mansky + Copyright TUM 2003, UIUC 2019-20 + + Based on the Jinja theory Compiler/Correctness2.thy by Tobias Nipkow +*) + +section \ Correctness of Stage 2 \ + +theory Correctness2 +imports "HOL-Library.Sublist" Compiler2 J1WellForm "../J/EConform" +begin + +(*<*)hide_const (open) Throw(*>*) + +subsection\ Instruction sequences \ + +text\ How to select individual instructions and subsequences of +instructions from a program given the class, method and program +counter. \ + +definition before :: "jvm_prog \ cname \ mname \ nat \ instr list \ bool" + ("(_,_,_,_/ \ _)" [51,0,0,0,51] 50) where + "P,C,M,pc \ is \ prefix is (drop pc (instrs_of P C M))" + +definition at :: "jvm_prog \ cname \ mname \ nat \ instr \ bool" + ("(_,_,_,_/ \ _)" [51,0,0,0,51] 50) where + "P,C,M,pc \ i \ (\is. drop pc (instrs_of P C M) = i#is)" + +lemma [simp]: "P,C,M,pc \ []" +(*<*)by(simp add:before_def)(*>*) + + +lemma [simp]: "P,C,M,pc \ (i#is) = (P,C,M,pc \ i \ P,C,M,pc + 1 \ is)" +(*<*)by(fastforce simp add:before_def at_def prefix_def drop_Suc drop_tl)(*>*) + +(*<*) +declare drop_drop[simp del] +(*>*) + + +lemma [simp]: "P,C,M,pc \ (is\<^sub>1 @ is\<^sub>2) = (P,C,M,pc \ is\<^sub>1 \ P,C,M,pc + size is\<^sub>1 \ is\<^sub>2)" +(*<*) +apply(simp add:before_def prefix_def) +apply(subst add.commute) +apply(simp add: drop_drop[symmetric]) +apply fastforce +done +(*>*) + +(*<*) +declare drop_drop[simp] +(*>*) + + +lemma [simp]: "P,C,M,pc \ i \ instrs_of P C M ! pc = i" +(*<*)by(clarsimp simp add:at_def strict_prefix_def nth_via_drop)(*>*) + +lemma beforeM: + "P \ C sees M,b: Ts\T = body in D \ + compP\<^sub>2 P,D,M,0 \ compE\<^sub>2 body @ [Return]" +(*<*) +apply(drule sees_method_idemp) +apply(simp add:before_def compP\<^sub>2_def compMb\<^sub>2_def) +done +(*>*) + +text\ This lemma executes a single instruction by rewriting: \ + +lemma [simp]: + "P,C,M,pc \ instr \ + (P \ (None, h, (vs,ls,C,M,pc,ics) # frs, sh) -jvm\ \') = + ((None, h, (vs,ls,C,M,pc,ics) # frs, sh) = \' \ + (\\. exec(P,(None, h, (vs,ls,C,M,pc,ics) # frs, sh)) = Some \ \ P \ \ -jvm\ \'))" +(*<*) +apply(simp only: exec_all_def) +apply(blast intro: converse_rtranclE converse_rtrancl_into_rtrancl) +done +(*>*) + + +subsection\ Exception tables \ + +definition pcs :: "ex_table \ nat set" +where + "pcs xt \ \(f,t,C,h,d) \ set xt. {f ..< t}" + +lemma pcs_subset: +shows "(\pc d. pcs(compxE\<^sub>2 e pc d) \ {pc..2 e)})" +and "(\pc d. pcs(compxEs\<^sub>2 es pc d) \ {pc..2 es)})" +(*<*) +apply(induct e and es rule: compxE\<^sub>2.induct compxEs\<^sub>2.induct) +apply (simp_all add:pcs_def) +apply (fastforce split:bop.splits)+ +done +(*>*) + + +lemma [simp]: "pcs [] = {}" +(*<*)by(simp add:pcs_def)(*>*) + + +lemma [simp]: "pcs (x#xt) = {fst x ..< fst(snd x)} \ pcs xt" +(*<*)by(auto simp add: pcs_def)(*>*) + + +lemma [simp]: "pcs(xt\<^sub>1 @ xt\<^sub>2) = pcs xt\<^sub>1 \ pcs xt\<^sub>2" +(*<*)by(simp add:pcs_def)(*>*) + + +lemma [simp]: "pc < pc\<^sub>0 \ pc\<^sub>0+size(compE\<^sub>2 e) \ pc \ pc \ pcs(compxE\<^sub>2 e pc\<^sub>0 d)" +(*<*)using pcs_subset by fastforce(*>*) + + +lemma [simp]: "pc < pc\<^sub>0 \ pc\<^sub>0+size(compEs\<^sub>2 es) \ pc \ pc \ pcs(compxEs\<^sub>2 es pc\<^sub>0 d)" +(*<*)using pcs_subset by fastforce(*>*) + + +lemma [simp]: "pc\<^sub>1 + size(compE\<^sub>2 e\<^sub>1) \ pc\<^sub>2 \ pcs(compxE\<^sub>2 e\<^sub>1 pc\<^sub>1 d\<^sub>1) \ pcs(compxE\<^sub>2 e\<^sub>2 pc\<^sub>2 d\<^sub>2) = {}" +(*<*)using pcs_subset by fastforce(*>*) + + +lemma [simp]: "pc\<^sub>1 + size(compE\<^sub>2 e) \ pc\<^sub>2 \ pcs(compxE\<^sub>2 e pc\<^sub>1 d\<^sub>1) \ pcs(compxEs\<^sub>2 es pc\<^sub>2 d\<^sub>2) = {}" +(*<*)using pcs_subset by fastforce(*>*) + + +lemma [simp]: + "pc \ pcs xt\<^sub>0 \ match_ex_table P C pc (xt\<^sub>0 @ xt\<^sub>1) = match_ex_table P C pc xt\<^sub>1" +(*<*)by (induct xt\<^sub>0) (auto simp: matches_ex_entry_def)(*>*) + + +lemma [simp]: "\ x \ set xt; pc \ pcs xt \ \ \ matches_ex_entry P D pc x" +(*<*)by(auto simp:matches_ex_entry_def pcs_def)(*>*) + + +lemma [simp]: +assumes xe: "xe \ set(compxE\<^sub>2 e pc d)" and outside: "pc' < pc \ pc+size(compE\<^sub>2 e) \ pc'" +shows "\ matches_ex_entry P C pc' xe" +(*<*) +proof + assume "matches_ex_entry P C pc' xe" + with xe have "pc' \ pcs(compxE\<^sub>2 e pc d)" + by(force simp add:matches_ex_entry_def pcs_def) + with outside show False by simp +qed +(*>*) + + +lemma [simp]: +assumes xe: "xe \ set(compxEs\<^sub>2 es pc d)" and outside: "pc' < pc \ pc+size(compEs\<^sub>2 es) \ pc'" +shows "\ matches_ex_entry P C pc' xe" +(*<*) +proof + assume "matches_ex_entry P C pc' xe" + with xe have "pc' \ pcs(compxEs\<^sub>2 es pc d)" + by(force simp add:matches_ex_entry_def pcs_def) + with outside show False by simp +qed +(*>*) + + +lemma match_ex_table_app[simp]: + "\xte \ set xt\<^sub>1. \ matches_ex_entry P D pc xte \ + match_ex_table P D pc (xt\<^sub>1 @ xt) = match_ex_table P D pc xt" +(*<*)by(induct xt\<^sub>1) simp_all(*>*) + + +lemma [simp]: + "\x \ set xtab. \ matches_ex_entry P C pc x \ + match_ex_table P C pc xtab = None" +(*<*)using match_ex_table_app[where ?xt = "[]"] by fastforce(*>*) + + +lemma match_ex_entry: + "matches_ex_entry P C pc (start, end, catch_type, handler) = + (start \ pc \ pc < end \ P \ C \\<^sup>* catch_type)" +(*<*)by(simp add:matches_ex_entry_def)(*>*) + + +definition caught :: "jvm_prog \ pc \ heap \ addr \ ex_table \ bool" where + "caught P pc h a xt \ + (\entry \ set xt. matches_ex_entry P (cname_of h a) pc entry)" + +definition beforex :: "jvm_prog \ cname \ mname \ ex_table \ nat set \ nat \ bool" + ("(2_,/_,/_ \/ _ /'/ _,/_)" [51,0,0,0,0,51] 50) where + "P,C,M \ xt / I,d \ + (\xt\<^sub>0 xt\<^sub>1. ex_table_of P C M = xt\<^sub>0 @ xt @ xt\<^sub>1 \ pcs xt\<^sub>0 \ I = {} \ pcs xt \ I \ + (\pc \ I. \C pc' d'. match_ex_table P C pc xt\<^sub>1 = \(pc',d')\ \ d' \ d))" + +definition dummyx :: "jvm_prog \ cname \ mname \ ex_table \ nat set \ nat \ bool" ("(2_,_,_ \/ _ '/_,_)" [51,0,0,0,0,51] 50) where + "P,C,M \ xt/I,d \ P,C,M \ xt/I,d" + +lemma beforexD1: "P,C,M \ xt / I,d \ pcs xt \ I" +(*<*)by(auto simp add:beforex_def)(*>*) + + +lemma beforex_mono: "\ P,C,M \ xt/I,d'; d' \ d \ \ P,C,M \ xt/I,d" +(*<*)by(fastforce simp:beforex_def)(*>*) + + +lemma [simp]: "P,C,M \ xt/I,d \ P,C,M \ xt/I,Suc d" +(*<*)by(fastforce intro:beforex_mono)(*>*) + + +lemma beforex_append[simp]: + "pcs xt\<^sub>1 \ pcs xt\<^sub>2 = {} \ + P,C,M \ xt\<^sub>1 @ xt\<^sub>2/I,d = + (P,C,M \ xt\<^sub>1/I-pcs xt\<^sub>2,d \ P,C,M \ xt\<^sub>2/I-pcs xt\<^sub>1,d \ P,C,M \ xt\<^sub>1@xt\<^sub>2/I,d)" +(*<*) +apply(rule iffI) + prefer 2 + apply(simp add:dummyx_def) +apply(auto simp add: beforex_def dummyx_def) + apply(rule_tac x = xt\<^sub>0 in exI) + apply auto +apply(rule_tac x = "xt\<^sub>0@xt\<^sub>1" in exI) +apply auto +done +(*>*) + + +lemma beforex_appendD1: + "\ P,C,M \ xt\<^sub>1 @ xt\<^sub>2 @ [(f,t,D,h,d)] / I,d; + pcs xt\<^sub>1 \ J; J \ I; J \ pcs xt\<^sub>2 = {} \ + \ P,C,M \ xt\<^sub>1 / J,d" +(*<*) +apply(auto simp:beforex_def) +apply(rule exI,rule exI,rule conjI, rule refl) +apply(rule conjI, blast) +apply(auto) +apply(subgoal_tac "pc \ pcs xt\<^sub>2") + prefer 2 apply blast +apply (auto split:if_split_asm) +done +(*>*) + + +lemma beforex_appendD2: + "\ P,C,M \ xt\<^sub>1 @ xt\<^sub>2 @ [(f,t,D,h,d)] / I,d; + pcs xt\<^sub>2 \ J; J \ I; J \ pcs xt\<^sub>1 = {} \ + \ P,C,M \ xt\<^sub>2 / J,d" +(*<*) +apply(auto simp:beforex_def) +apply(rule_tac x = "xt\<^sub>0 @ xt\<^sub>1" in exI) +apply fastforce +done +(*>*) + + +lemma beforexM: + "P \ C sees M,b: Ts\T = body in D \ compP\<^sub>2 P,D,M \ compxE\<^sub>2 body 0 0/{..2 body)},0" +(*<*) +apply(drule sees_method_idemp) +apply(drule sees_method_compP[where f = compMb\<^sub>2]) +apply(simp add:beforex_def compP\<^sub>2_def compMb\<^sub>2_def) +apply(rule_tac x = "[]" in exI) +using pcs_subset apply fastforce +done +(*>*) + + +lemma match_ex_table_SomeD2: + "\ match_ex_table P D pc (ex_table_of P C M) = \(pc',d')\; + P,C,M \ xt/I,d; \x \ set xt. \ matches_ex_entry P D pc x; pc \ I \ + \ d' \ d" +(*<*) +apply(auto simp:beforex_def) +apply(subgoal_tac "pc \ pcs xt\<^sub>0") +apply auto +done +(*>*) + + +lemma match_ex_table_SomeD1: + "\ match_ex_table P D pc (ex_table_of P C M) = \(pc',d')\; + P,C,M \ xt / I,d; pc \ I; pc \ pcs xt \ \ d' \ d" +(*<*)by(auto elim: match_ex_table_SomeD2)(*>*) + + +subsection\ The correctness proof \ + +(*<*) +declare nat_add_distrib[simp] caught_def[simp] +declare fun_upd_apply[simp del] +(*>*) + +definition + handle :: "jvm_prog \ cname \ mname \ addr \ heap \ val list \ val list \ nat \ init_call_status \ frame list \ sheap + \ jvm_state" where + "handle P C M a h vs ls pc ics frs sh = find_handler P a h ((vs,ls,C,M,pc,ics) # frs) sh" + +lemma aux_isin[simp]: "\ B \ A; a \ B \ \ a \ A" +(*<*)by blast(*>*) + +lemma handle_frs_tl_neq: + "ics_of f \ No_ics + \ (xp, h, f#frs, sh) \ handle P C M xa h' vs l pc ics frs sh'" + by(simp add: handle_def find_handler_frs_tl_neq del: find_handler.simps) + +subsubsection "Correctness proof inductive hypothesis" + +\ \ frame definitions for use by correctness proof inductive hypothesis \ +fun calling_to_called :: "frame \ frame" where +"calling_to_called (stk,loc,D,M,pc,ics) = (stk,loc,D,M,pc,case ics of Calling C Cs \ Called (C#Cs))" + +fun calling_to_scalled :: "frame \ frame" where +"calling_to_scalled (stk,loc,D,M,pc,ics) = (stk,loc,D,M,pc,case ics of Calling C Cs \ Called Cs)" + +fun calling_to_calling :: "frame \ cname \ frame" where +"calling_to_calling (stk,loc,D,M,pc,ics) C' = (stk,loc,D,M,pc,case ics of Calling C Cs \ Calling C' (C#Cs))" + +fun calling_to_throwing :: "frame \ addr \ frame" where +"calling_to_throwing (stk,loc,D,M,pc,ics) a = (stk,loc,D,M,pc,case ics of Calling C Cs \ Throwing (C#Cs) a)" + +fun calling_to_sthrowing :: "frame \ addr \ frame" where +"calling_to_sthrowing (stk,loc,D,M,pc,ics) a = (stk,loc,D,M,pc,case ics of Calling C Cs \ Throwing Cs a)" + + +\ \ pieces of the correctness proof's inductive hypothesis, which depend on the + expression being compiled) \ + +fun Jcc_cond :: "J\<^sub>1_prog \ ty list \ cname \ mname \ val list \ pc \ init_call_status + \ nat set \ heap \ sheap \ expr\<^sub>1 \ bool" where +"Jcc_cond P E C M vs pc ics I h sh (INIT C\<^sub>0 (Cs,b) \ e') + = ((\T. P,E,h,sh \\<^sub>1 INIT C\<^sub>0 (Cs,b) \ e' : T) \ unit = e' \ ics = No_ics)" | +"Jcc_cond P E C M vs pc ics I h sh (RI(C',e\<^sub>0);Cs \ e') + = (((e\<^sub>0 = C'\\<^sub>sclinit([]) \ (\T. P,E,h,sh \\<^sub>1 RI(C',e\<^sub>0);Cs \ e':T)) + \ ((\a. e\<^sub>0 = Throw a) \ (\C \ set(C'#Cs). is_class P C))) + \ unit = e' \ ics = No_ics)" | +"Jcc_cond P E C M vs pc ics I h sh (C'\\<^sub>sM'(es)) + = (let e = (C'\\<^sub>sM'(es)) + in if M' = clinit \ es = [] then (\T. P,E,h,sh \\<^sub>1 e:T) \ (\Cs. ics = Called Cs) + else (compP\<^sub>2 P,C,M,pc \ compE\<^sub>2 e \ compP\<^sub>2 P,C,M \ compxE\<^sub>2 e pc (size vs)/I,size vs + \ {pc..2 e)} \ I \ \sub_RI e \ ics = No_ics) + )" | +"Jcc_cond P E C M vs pc ics I h sh e + = (compP\<^sub>2 P,C,M,pc \ compE\<^sub>2 e \ compP\<^sub>2 P,C,M \ compxE\<^sub>2 e pc (size vs)/I,size vs + \ {pc..2 e)} \ I \ \sub_RI e \ ics = No_ics)" + + +fun Jcc_frames :: "jvm_prog \ cname \ mname \ val list \ val list \ pc \ init_call_status + \ frame list \ expr\<^sub>1 \ frame list" where +"Jcc_frames P C M vs ls pc ics frs (INIT C\<^sub>0 (C'#Cs,b) \ e') + = (case b of False \ (vs,ls,C,M,pc,Calling C' Cs) # frs + | True \ (vs,ls,C,M,pc,Called (C'#Cs)) # frs + )" | +"Jcc_frames P C M vs ls pc ics frs (INIT C\<^sub>0 (Nil,b) \ e') + = (vs,ls,C,M,pc,Called [])#frs" | +"Jcc_frames P C M vs ls pc ics frs (RI(C',e\<^sub>0);Cs \ e') + = (case e\<^sub>0 of Throw a \ (vs,ls,C,M,pc,Throwing (C'#Cs) a) # frs + | _ \ (vs,ls,C,M,pc,Called (C'#Cs)) # frs )" | +"Jcc_frames P C M vs ls pc ics frs (C'\\<^sub>sM'(es)) + = (if M' = clinit \ es = [] + then create_init_frame P C'#(vs,ls,C,M,pc,ics)#frs + else (vs,ls,C,M,pc,ics)#frs + )" | +"Jcc_frames P C M vs ls pc ics frs e + = (vs,ls,C,M,pc,ics)#frs" + +fun Jcc_rhs :: "J\<^sub>1_prog \ ty list \ cname \ mname \ val list \ val list \ pc \ init_call_status + \ frame list \ heap \ val list \ sheap \ val \ expr\<^sub>1 \ jvm_state" where +"Jcc_rhs P E C M vs ls pc ics frs h' ls' sh' v (INIT C\<^sub>0 (Cs,b) \ e') + = (None,h',(vs,ls,C,M,pc,Called [])#frs,sh')" | +"Jcc_rhs P E C M vs ls pc ics frs h' ls' sh' v (RI(C',e\<^sub>0);Cs \ e') + = (None,h',(vs,ls,C,M,pc,Called [])#frs,sh')" | +"Jcc_rhs P E C M vs ls pc ics frs h' ls' sh' v (C'\\<^sub>sM'(es)) + = (let e = (C'\\<^sub>sM'(es)) + in if M' = clinit \ es = [] + then (None,h',(vs,ls,C,M,pc,ics)#frs,sh'(C'\(fst(the(sh' C')),Done))) + else (None,h',(v#vs,ls',C,M,pc+size(compE\<^sub>2 e),ics)#frs,sh') + )" | +"Jcc_rhs P E C M vs ls pc ics frs h' ls' sh' v e + = (None,h',(v#vs,ls',C,M,pc+size(compE\<^sub>2 e),ics)#frs,sh')" + +fun Jcc_err :: "jvm_prog \ cname \ mname \ heap \ val list \ val list \ pc \ init_call_status + \ frame list \ sheap \ nat set \ heap \ val list \ sheap \ addr \ expr\<^sub>1 + \ bool" where +"Jcc_err P C M h vs ls pc ics frs sh I h' ls' sh' xa (INIT C\<^sub>0 (Cs,b) \ e') + = (\vs'. P \ (None,h,Jcc_frames P C M vs ls pc ics frs (INIT C\<^sub>0 (Cs,b) \ e'),sh) + -jvm\ handle P C M xa h' (vs'@vs) ls pc ics frs sh')" | +"Jcc_err P C M h vs ls pc ics frs sh I h' ls' sh' xa (RI(C',e\<^sub>0);Cs \ e') + = (\vs'. P \ (None,h,Jcc_frames P C M vs ls pc ics frs (RI(C',e\<^sub>0);Cs \ e'),sh) + -jvm\ handle P C M xa h' (vs'@vs) ls pc ics frs sh')" | +"Jcc_err P C M h vs ls pc ics frs sh I h' ls' sh' xa (C'\\<^sub>sM'(es)) + = (let e = (C'\\<^sub>sM'(es)) + in if M' = clinit \ es = [] + then case ics of + Called Cs \ P \ (None,h,Jcc_frames P C M vs ls pc ics frs e,sh) + -jvm\ (None,h',(vs,ls,C,M,pc,Throwing Cs xa)#frs,(sh'(C' \ (fst(the(sh' C')),Error)))) + else (\pc\<^sub>1. pc \ pc\<^sub>1 \ pc\<^sub>1 < pc + size(compE\<^sub>2 e) \ + \ caught P pc\<^sub>1 h' xa (compxE\<^sub>2 e pc (size vs)) \ + (\vs'. P \ (None,h,Jcc_frames P C M vs ls pc ics frs e,sh) + -jvm\ handle P C M xa h' (vs'@vs) ls' pc\<^sub>1 ics frs sh')) + )" | +"Jcc_err P C M h vs ls pc ics frs sh I h' ls' sh' xa e + = (\pc\<^sub>1. pc \ pc\<^sub>1 \ pc\<^sub>1 < pc + size(compE\<^sub>2 e) \ + \ caught P pc\<^sub>1 h' xa (compxE\<^sub>2 e pc (size vs)) \ + (\vs'. P \ (None,h,Jcc_frames P C M vs ls pc ics frs e,sh) + -jvm\ handle P C M xa h' (vs'@vs) ls' pc\<^sub>1 ics frs sh'))" + +fun Jcc_pieces :: "J\<^sub>1_prog \ ty list \ cname \ mname \ heap \ val list \ val list \ pc \ init_call_status + \ frame list \ sheap \ nat set \ heap \ val list \ sheap \ val \ addr \ expr\<^sub>1 + \ bool \ frame list \ jvm_state \ bool" where +"Jcc_pieces P E C M h vs ls pc ics frs sh I h' ls' sh' v xa e + = (Jcc_cond P E C M vs pc ics I h sh e, Jcc_frames (compP\<^sub>2 P) C M vs ls pc ics frs e, + Jcc_rhs P E C M vs ls pc ics frs h' ls' sh' v e, + Jcc_err (compP\<^sub>2 P) C M h vs ls pc ics frs sh I h' ls' sh' xa e)" + +\ \ @{text Jcc_pieces} lemmas \ + +lemma nsub_RI_Jcc_pieces: +assumes [simp]: "P \ compP\<^sub>2 P\<^sub>1" + and nsub: "\sub_RI e" +shows "Jcc_pieces P\<^sub>1 E C M h vs ls pc ics frs sh I h' ls' sh' v xa e + = (let cond = P,C,M,pc \ compE\<^sub>2 e \ P,C,M \ compxE\<^sub>2 e pc (size vs)/I,size vs + \ {pc..2 e)} \ I \ ics = No_ics; + frs' = (vs,ls,C,M,pc,ics)#frs; + rhs = (None,h',(v#vs,ls',C,M,pc+size(compE\<^sub>2 e),ics)#frs,sh'); + err = (\pc\<^sub>1. pc \ pc\<^sub>1 \ pc\<^sub>1 < pc + size(compE\<^sub>2 e) \ + \ caught P pc\<^sub>1 h' xa (compxE\<^sub>2 e pc (size vs)) \ + (\vs'. P \ (None,h,frs',sh) -jvm\ handle P C M xa h' (vs'@vs) ls' pc\<^sub>1 ics frs sh')) + in (cond, frs',rhs, err) + )" +proof - + have NC: "\C'. e \ C'\\<^sub>sclinit([])" using assms(2) proof(cases e) qed(simp_all) + then show ?thesis using assms + proof(cases e) + case (SCall C M es) + then have "M \ clinit" using nsub by simp + then show ?thesis using SCall nsub proof(cases es) qed(simp_all) + qed(simp_all) +qed + +lemma Jcc_pieces_Cast: +assumes [simp]: "P \ compP\<^sub>2 P\<^sub>1" + and "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v xa (Cast C' e) + = (True, frs\<^sub>0, (xp',h',(v#vs',ls',C\<^sub>0,M',pc',ics')#frs',sh'), err)" +shows "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v' xa e + = (True, frs\<^sub>0, (xp',h',(v'#vs',ls',C\<^sub>0,M',pc' - 1,ics')#frs',sh'), + (\pc\<^sub>1. pc \ pc\<^sub>1 \ pc\<^sub>1 < pc + size(compE\<^sub>2 e) \ + \ caught P pc\<^sub>1 h\<^sub>1 xa (compxE\<^sub>2 e pc (size vs)) \ + (\vs'. P \ (None,h\<^sub>0,frs\<^sub>0,sh\<^sub>0) -jvm\ handle P C M xa h\<^sub>1 (vs'@vs) ls\<^sub>1 pc\<^sub>1 ics frs sh\<^sub>1)))" +proof - + have pc: "{pc..2 e)} \ I" using assms by clarsimp + show ?thesis using assms nsub_RI_Jcc_pieces[where e=e] pc by clarsimp +qed + +lemma Jcc_pieces_BinOp1: +assumes + "Jcc_pieces P E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>2 ls\<^sub>2 sh\<^sub>2 v xa (e \bop\ e') + = (True, frs\<^sub>0, (xp',h',(v#vs',ls',C\<^sub>0,M',pc',ics')#frs',sh'), err)" +shows "\err. Jcc_pieces P E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 + (I - pcs (compxE\<^sub>2 e' (pc + length (compE\<^sub>2 e)) (Suc (length vs')))) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v' xa e + = (True, frs\<^sub>0, (xp',h\<^sub>1,(v'#vs',ls\<^sub>1,C\<^sub>0,M',pc' - size (compE\<^sub>2 e') - 1,ics')#frs',sh\<^sub>1), err)" +proof - + have bef: "compP compMb\<^sub>2 P,C\<^sub>0,M' \ compxE\<^sub>2 e pc (length vs) + / I - pcs (compxE\<^sub>2 e' (pc + length (compE\<^sub>2 e)) (Suc (length vs'))),length vs" + using assms by clarsimp + have vs: "vs = vs'" using assms by simp + show ?thesis using assms nsub_RI_Jcc_pieces[where e=e] bef vs by clarsimp +qed + +lemma Jcc_pieces_BinOp2: +assumes [simp]: "P \ compP\<^sub>2 P\<^sub>1" + and "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>2 ls\<^sub>2 sh\<^sub>2 v xa (e \bop\ e') + = (True, frs\<^sub>0, (xp',h',(v#vs',ls',C\<^sub>0,M',pc',ics')#frs',sh'), err)" +shows "\err. Jcc_pieces P\<^sub>1 E C M h\<^sub>1 (v\<^sub>1#vs) ls\<^sub>1 (pc + size (compE\<^sub>2 e)) ics frs sh\<^sub>1 + (I - pcs (compxE\<^sub>2 e pc (length vs'))) h\<^sub>2 ls\<^sub>2 sh\<^sub>2 v' xa e' + = (True, (v\<^sub>1#vs,ls\<^sub>1,C,M,pc + size (compE\<^sub>2 e),ics)#frs, + (xp',h',(v'#v\<^sub>1#vs',ls',C\<^sub>0,M',pc' - 1,ics')#frs',sh'), + (\pc\<^sub>1. pc + size (compE\<^sub>2 e) \ pc\<^sub>1 \ pc\<^sub>1 < pc + size (compE\<^sub>2 e) + length (compE\<^sub>2 e') \ + \ caught P pc\<^sub>1 h\<^sub>2 xa (compxE\<^sub>2 e' (pc + size (compE\<^sub>2 e)) (Suc (length vs))) \ + (\vs'. P \ (None,h\<^sub>1,(v\<^sub>1#vs,ls\<^sub>1,C,M,pc + size (compE\<^sub>2 e),ics)#frs,sh\<^sub>1) + -jvm\ handle P C M xa h\<^sub>2 (vs'@v\<^sub>1#vs) ls\<^sub>2 pc\<^sub>1 ics frs sh\<^sub>2)))" +proof - + have bef: "compP compMb\<^sub>2 P\<^sub>1,C\<^sub>0,M' \ compxE\<^sub>2 e pc (length vs) + / I - pcs (compxE\<^sub>2 e' (pc + length (compE\<^sub>2 e)) (Suc (length vs'))),length vs" + using assms by clarsimp + have vs: "vs = vs'" using assms by simp + show ?thesis using assms nsub_RI_Jcc_pieces[where e=e'] bef vs by clarsimp +qed + +lemma Jcc_pieces_FAcc: +assumes + "Jcc_pieces P E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v xa (e\F{D}) + = (True, frs\<^sub>0, (xp',h',(v#vs',ls',C\<^sub>0,M',pc',ics')#frs',sh'), err)" +shows "\err. Jcc_pieces P E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v' xa e + = (True, frs\<^sub>0, (xp',h',(v'#vs',ls',C\<^sub>0,M',pc' - 1,ics')#frs',sh'), err)" +proof - + have pc: "{pc..2 e)} \ I" using assms by clarsimp + then show ?thesis using assms nsub_RI_Jcc_pieces[where e=e] by clarsimp +qed + +lemma Jcc_pieces_LAss: +assumes [simp]: "P \ compP\<^sub>2 P\<^sub>1" + and "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v xa (i:=e) + = (True, frs\<^sub>0, (xp',h',(v#vs',ls',C\<^sub>0,M',pc',ics')#frs',sh'), err)" +shows "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v' xa e + = (True, frs\<^sub>0, (xp',h',(v'#vs',ls',C\<^sub>0,M',pc' - 2,ics')#frs',sh'), + (\pc\<^sub>1. pc \ pc\<^sub>1 \ pc\<^sub>1 < pc + size(compE\<^sub>2 e) \ + \ caught P pc\<^sub>1 h\<^sub>1 xa (compxE\<^sub>2 e pc (size vs)) \ + (\vs'. P \ (None,h\<^sub>0,frs\<^sub>0,sh\<^sub>0) -jvm\ handle P C M xa h\<^sub>1 (vs'@vs) ls\<^sub>1 pc\<^sub>1 ics frs sh\<^sub>1)))" +proof - + have pc: "{pc..2 e)} \ I" using assms by clarsimp + show ?thesis using assms nsub_RI_Jcc_pieces[where e=e] pc by clarsimp +qed + +lemma Jcc_pieces_FAss1: +assumes + "Jcc_pieces P E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>2 ls\<^sub>2 sh\<^sub>2 v xa (e\F{D}:=e') + = (True, frs\<^sub>0, (xp',h',(v#vs',ls',C\<^sub>0,M',pc',ics')#frs',sh'), err)" +shows "\err. Jcc_pieces P E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 + (I - pcs (compxE\<^sub>2 e' (pc + length (compE\<^sub>2 e)) (Suc (length vs')))) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v' xa e + = (True, frs\<^sub>0, (xp',h\<^sub>1,(v'#vs',ls\<^sub>1,C\<^sub>0,M',pc' - size (compE\<^sub>2 e') - 2,ics')#frs',sh\<^sub>1), err)" +proof - + show ?thesis using assms nsub_RI_Jcc_pieces[where e=e] by clarsimp +qed + +lemma Jcc_pieces_FAss2: +assumes + "Jcc_pieces P E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>2 ls\<^sub>2 sh\<^sub>2 v xa (e\F{D}:=e') + = (True, frs\<^sub>0, (xp',h',(v#vs',ls',C\<^sub>0,M',pc',ics')#frs',sh'), err)" +shows "Jcc_pieces P E C M h\<^sub>1 (v\<^sub>1#vs) ls\<^sub>1 (pc + size (compE\<^sub>2 e)) ics frs sh\<^sub>1 + (I - pcs (compxE\<^sub>2 e pc (length vs'))) h\<^sub>2 ls\<^sub>2 sh\<^sub>2 v' xa e' + = (True, (v\<^sub>1#vs,ls\<^sub>1,C,M,pc + size (compE\<^sub>2 e),ics)#frs, + (xp',h',(v'#v\<^sub>1#vs',ls',C\<^sub>0,M',pc' - 2,ics')#frs',sh'), + (\pc\<^sub>1. (pc + size (compE\<^sub>2 e)) \ pc\<^sub>1 \ pc\<^sub>1 < pc + size (compE\<^sub>2 e) + size(compE\<^sub>2 e') \ + \ caught (compP\<^sub>2 P) pc\<^sub>1 h\<^sub>2 xa (compxE\<^sub>2 e' (pc + size (compE\<^sub>2 e)) (size (v\<^sub>1#vs))) \ + (\vs'. (compP\<^sub>2 P) \ (None,h\<^sub>1,(v\<^sub>1#vs,ls\<^sub>1,C,M,pc + size (compE\<^sub>2 e),ics)#frs,sh\<^sub>1) + -jvm\ handle (compP\<^sub>2 P) C M xa h\<^sub>2 (vs'@v\<^sub>1#vs) ls\<^sub>2 pc\<^sub>1 ics frs sh\<^sub>2)))" +proof - + show ?thesis using assms nsub_RI_Jcc_pieces[where e=e'] by clarsimp +qed + +lemma Jcc_pieces_SFAss: +assumes + "Jcc_pieces P E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h' ls' sh' v xa (C'\\<^sub>sF{D}:=e) + = (True, frs\<^sub>0, (xp',h',(v#vs',ls',C\<^sub>0,M',pc',ics')#frs',sh'), err)" +shows "\err. Jcc_pieces P E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v' xa e + = (True, frs\<^sub>0, (xp',h\<^sub>1,(v'#vs',ls\<^sub>1,C\<^sub>0,M',pc' - 2,ics')#frs',sh\<^sub>1), err)" +proof - + have pc: "{pc..2 e)} \ I" using assms by clarsimp + show ?thesis using assms nsub_RI_Jcc_pieces[where e=e] pc by clarsimp +qed + +lemma Jcc_pieces_Call1: +assumes + "Jcc_pieces P E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>3 ls\<^sub>3 sh\<^sub>3 v xa (e\M\<^sub>0(es)) + = (True, frs\<^sub>0, (xp',h',(v#vs',ls',C',M',pc',ics')#frs',sh'), err)" +shows "\err. Jcc_pieces P E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 + (I - pcs (compxEs\<^sub>2 es (pc + length (compE\<^sub>2 e)) (Suc (length vs')))) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v' xa e + = (True, frs\<^sub>0, + (xp',h\<^sub>1,(v'#vs',ls\<^sub>1,C',M',pc' - size (compEs\<^sub>2 es) - 1,ics')#frs',sh\<^sub>1), err)" +proof - + show ?thesis using assms nsub_RI_Jcc_pieces[where e=e] by clarsimp +qed + +lemma Jcc_pieces_clinit: +assumes [simp]: "P \ compP\<^sub>2 P\<^sub>1" + and cond: "Jcc_cond P\<^sub>1 E C M vs pc ics I h sh (C1\\<^sub>sclinit([]))" +shows "Jcc_pieces P\<^sub>1 E C M h vs ls pc ics frs sh I h' ls' sh' v xa (C1\\<^sub>sclinit([])) + = (True, create_init_frame P C1 # (vs,ls,C,M,pc,ics)#frs, + (None, h', (vs,ls,C,M,pc,ics)#frs, sh'(C1\(fst(the(sh' C1)),Done))), + P \ (None,h,create_init_frame P C1 # (vs,ls,C,M,pc,ics)#frs,sh) -jvm\ + (case ics of Called Cs \ (None,h',(vs,ls,C,M,pc,Throwing Cs xa)#frs,(sh'(C1 \ (fst(the(sh' C1)),Error))))))" +using assms by(auto split: init_call_status.splits list.splits bool.splits) + +lemma Jcc_pieces_SCall_clinit_body: +assumes [simp]: "P \ compP\<^sub>2 P\<^sub>1" and wf: "wf_J\<^sub>1_prog P\<^sub>1" + and "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>3 ls\<^sub>2 sh\<^sub>3 v xa (C1\\<^sub>sclinit([])) + = (True, frs', rhs', err')" + and method: "P\<^sub>1 \ C1 sees clinit,Static: []\Void = body in D" +shows "Jcc_pieces P\<^sub>1 [] D clinit h\<^sub>2 [] (replicate (max_vars body) undefined) 0 + No_ics (tl frs') sh\<^sub>2 {..2 body)} h\<^sub>3 ls\<^sub>3 sh\<^sub>3 v xa body + = (True, frs', + (None,h\<^sub>3,([v],ls\<^sub>3,D,clinit,size(compE\<^sub>2 body), No_ics)#tl frs',sh\<^sub>3), + \pc\<^sub>1. 0 \ pc\<^sub>1 \ pc\<^sub>1 < size(compE\<^sub>2 body) \ + \ caught P pc\<^sub>1 h\<^sub>3 xa (compxE\<^sub>2 body 0 0) \ + (\vs'. P \ (None,h\<^sub>2,frs',sh\<^sub>2) -jvm\ handle P D clinit xa h\<^sub>3 vs' ls\<^sub>3 pc\<^sub>1 + No_ics (tl frs') sh\<^sub>3))" +proof - + have M_in_D: "P\<^sub>1 \ D sees clinit,Static: []\Void = body in D" + using method by(rule sees_method_idemp) + hence M_code: "compP\<^sub>2 P\<^sub>1,D,clinit,0 \ compE\<^sub>2 body @ [Return]" + and M_xtab: "compP\<^sub>2 P\<^sub>1,D,clinit \ compxE\<^sub>2 body 0 0/{..2 body)},0" + by(rule beforeM, rule beforexM) + have nsub: "\sub_RI body" by(rule sees_wf\<^sub>1_nsub_RI[OF wf method]) + then show ?thesis using assms nsub_RI_Jcc_pieces M_code M_xtab by clarsimp +qed + +lemma Jcc_pieces_Cons: +assumes [simp]: "P \ compP\<^sub>2 P\<^sub>1" + and "P,C,M,pc \ compEs\<^sub>2 (e#es)" and "P,C,M \ compxEs\<^sub>2 (e#es) pc (size vs)/I,size vs" + and "{pc..2 (e#es))} \ I" + and "ics = No_ics" + and "\sub_RIs (e#es)" +shows "Jcc_pieces P\<^sub>1 E C M h vs ls pc ics frs sh + (I - pcs (compxEs\<^sub>2 es (pc + length (compE\<^sub>2 e)) (Suc (length vs)))) h' ls' sh' v xa e + = (True, (vs, ls, C, M, pc, ics) # frs, + (None, h', (v#vs, ls', C, M, pc + length (compE\<^sub>2 e), ics) # frs, sh'), + \pc\<^sub>1\pc. pc\<^sub>1 < pc + length (compE\<^sub>2 e) \ \ caught P pc\<^sub>1 h' xa (compxE\<^sub>2 e pc (length vs)) + \ (\vs'. P \ (None, h, (vs, ls, C, M, pc, ics) # frs, sh) + -jvm\ handle P C M xa h' (vs'@vs) ls' pc\<^sub>1 ics frs sh'))" +proof - + show ?thesis using assms nsub_RI_Jcc_pieces[where e=e] by auto +qed + +lemma Jcc_pieces_InitNone: +assumes [simp]: "P \ compP\<^sub>2 P\<^sub>1" + and "Jcc_pieces P\<^sub>1 E C M h vs l pc ics frs sh I h' l' sh' v xa (INIT C' (C\<^sub>0 # Cs,False) \ e) + = (True, frs', (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), err)" +shows + "Jcc_pieces P\<^sub>1 E C M h vs l pc ics frs (sh(C\<^sub>0 \ (sblank P C\<^sub>0, Prepared))) + I h' l' sh' v xa (INIT C' (C\<^sub>0 # Cs,False) \ e) + = (True, frs', (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), + \vs'. P \ (None,h,frs',(sh(C\<^sub>0 \ (sblank P\<^sub>1 C\<^sub>0, Prepared)))) + -jvm\ handle P C M xa h' (vs'@vs) l pc ics frs sh')" +proof - + have "Jcc_cond P\<^sub>1 E C M vs pc ics I h sh (INIT C' (C\<^sub>0 # Cs,False) \ e)" using assms by simp + then obtain T where "P\<^sub>1,E,h,sh \\<^sub>1 INIT C' (C\<^sub>0 # Cs,False) \ unit : T" by fastforce + then have "P\<^sub>1,E,h,sh(C\<^sub>0 \ (sblank P\<^sub>1 C\<^sub>0, Prepared)) \\<^sub>1 INIT C' (C\<^sub>0 # Cs,False) \ unit : T" + by(auto simp: fun_upd_apply) + then have "Ex (WTrt2\<^sub>1 P\<^sub>1 E h (sh(C\<^sub>0 \ (sblank P\<^sub>1 C\<^sub>0, Prepared))) (INIT C' (C\<^sub>0 # Cs,False) \ unit))" + by(simp only: exI) + then show ?thesis using assms by clarsimp +qed + +lemma Jcc_pieces_InitDP: +assumes [simp]: "P \ compP\<^sub>2 P\<^sub>1" + and "Jcc_pieces P\<^sub>1 E C M h vs l pc ics frs sh I h' l' sh' v xa (INIT C' (C\<^sub>0 # Cs,False) \ e) + = (True, frs', (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), err)" +shows + "Jcc_pieces P\<^sub>1 E C M h vs l pc ics frs sh I h' l' sh' v xa (INIT C' (Cs,True) \ e) + = (True, (calling_to_scalled (hd frs'))#(tl frs'), + (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), + \vs'. P \ (None,h,calling_to_scalled (hd frs')#(tl frs'),sh) + -jvm\ handle P C M xa h' (vs'@vs) l pc ics frs sh')" +proof - + have "Jcc_cond P\<^sub>1 E C M vs pc ics I h sh (INIT C' (C\<^sub>0 # Cs,False) \ e)" using assms by simp + then obtain T where "P\<^sub>1,E,h,sh \\<^sub>1 INIT C' (C\<^sub>0 # Cs,False) \ unit : T" by fastforce + then have "P\<^sub>1,E,h,sh \\<^sub>1 INIT C' (Cs,True) \ unit : T" + by (auto; metis list.sel(2) list.set_sel(2)) + then have wtrt: "Ex (WTrt2\<^sub>1 P\<^sub>1 E h sh (INIT C' (Cs,True) \ unit))" by(simp only: exI) + show ?thesis using assms wtrt + proof(cases Cs) + case (Cons C1 Cs1) + then show ?thesis using assms wtrt + by(case_tac "method P C1 clinit") clarsimp + qed(clarsimp) +qed + +lemma Jcc_pieces_InitError: +assumes [simp]: "P \ compP\<^sub>2 P\<^sub>1" + and "Jcc_pieces P\<^sub>1 E C M h vs l pc ics frs sh I h' l' sh' v xa (INIT C' (C\<^sub>0 # Cs,False) \ e) + = (True, frs', (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), err)" + and err: "sh C\<^sub>0 = Some(sfs,Error)" +shows + "Jcc_pieces P\<^sub>1 E C M h vs l pc ics frs sh I h' l' sh' v xa (RI (C\<^sub>0, THROW NoClassDefFoundError);Cs \ e) + = (True, (calling_to_throwing (hd frs') (addr_of_sys_xcpt NoClassDefFoundError))#(tl frs'), + (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), + \vs'. P \ (None,h, (calling_to_throwing (hd frs') (addr_of_sys_xcpt NoClassDefFoundError))#(tl frs'),sh) + -jvm\ handle P C M xa h' (vs'@vs) l pc ics frs sh')" +proof - + show ?thesis using assms + proof(cases Cs) + case (Cons C1 Cs1) + then show ?thesis using assms + by(case_tac "method P C1 clinit", case_tac "method P C\<^sub>0 clinit") clarsimp + qed(clarsimp) +qed + +lemma Jcc_pieces_InitObj: +assumes [simp]: "P \ compP\<^sub>2 P\<^sub>1" + and "Jcc_pieces P\<^sub>1 E C M h vs l pc ics frs sh I h' l' (sh(C\<^sub>0 \ (sfs,Processing))) v xa (INIT C' (C\<^sub>0 # Cs,False) \ e) + = (True, frs', (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), err)" +shows + "Jcc_pieces P\<^sub>1 E C M h vs l pc ics frs (sh(C\<^sub>0 \ (sfs,Processing))) I h' l' sh'' v xa (INIT C' (C\<^sub>0 # Cs,True) \ e) + = (True, calling_to_called (hd frs')#(tl frs'), + (None, h', (vs, l, C, M, pc, Called []) # frs, sh''), + \vs'. P \ (None,h,calling_to_called (hd frs')#(tl frs'),sh') + -jvm\ handle P C M xa h' (vs'@vs) l pc ics frs sh'')" +proof - + have "Jcc_cond P\<^sub>1 E C M vs pc ics I h sh (INIT C' (C\<^sub>0 # Cs,False) \ e)" using assms by simp + then obtain T where "P\<^sub>1,E,h,sh \\<^sub>1 INIT C' (C\<^sub>0 # Cs,False) \ unit : T" by fastforce + then have "P\<^sub>1,E,h,sh(C\<^sub>0 \ (sfs,Processing)) \\<^sub>1 INIT C' (C\<^sub>0 # Cs,True) \ unit : T" + using assms by clarsimp (auto simp: fun_upd_apply) + then have wtrt: "Ex (WTrt2\<^sub>1 P\<^sub>1 E h (sh(C\<^sub>0 \ (sfs,Processing))) (INIT C' (C\<^sub>0 # Cs,True) \ unit))" + by(simp only: exI) + show ?thesis using assms wtrt by clarsimp +qed + +lemma Jcc_pieces_InitNonObj: +assumes [simp]: "P \ compP\<^sub>2 P\<^sub>1" + and "is_class P\<^sub>1 D" and "D \ set (C\<^sub>0#Cs)" and "\C \ set (C\<^sub>0#Cs). P\<^sub>1 \ C \\<^sup>* D" + and pcs: "Jcc_pieces P\<^sub>1 E C M h vs l pc ics frs sh I h' l' (sh(C\<^sub>0 \ (sfs,Processing))) v xa (INIT C' (C\<^sub>0 # Cs,False) \ e) + = (True, frs', (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), err)" +shows + "Jcc_pieces P\<^sub>1 E C M h vs l pc ics frs (sh(C\<^sub>0 \ (sfs,Processing))) I h' l' sh'' v xa (INIT C' (D # C\<^sub>0 # Cs,False) \ e) + = (True, calling_to_calling (hd frs') D#(tl frs'), + (None, h', (vs, l, C, M, pc, Called []) # frs, sh''), + \vs'. P \ (None,h,calling_to_calling (hd frs') D#(tl frs'),sh') + -jvm\ handle P C M xa h' (vs'@vs) l pc ics frs sh'')" +proof - + have "Jcc_cond P\<^sub>1 E C M vs pc ics I h sh (INIT C' (C\<^sub>0 # Cs,False) \ e)" using assms by simp + then obtain T where "P\<^sub>1,E,h,sh \\<^sub>1 INIT C' (C\<^sub>0 # Cs,False) \ unit : T" by fastforce + then have "P\<^sub>1,E,h,sh(C\<^sub>0 \ (sfs,Processing)) \\<^sub>1 INIT C' (D # C\<^sub>0 # Cs,False) \ unit : T" + using assms by clarsimp (auto simp: fun_upd_apply) + then have wtrt: "Ex (WTrt2\<^sub>1 P\<^sub>1 E h (sh(C\<^sub>0 \ (sfs,Processing))) (INIT C' (D # C\<^sub>0 # Cs,False) \ unit))" + by(simp only: exI) + show ?thesis using assms wtrt by clarsimp +qed + +lemma Jcc_pieces_InitRInit: +assumes [simp]: "P \ compP\<^sub>2 P\<^sub>1" and wf: "wf_J\<^sub>1_prog P\<^sub>1" + and "Jcc_pieces P\<^sub>1 E C M h vs l pc ics frs sh I h' l' sh' v xa (INIT C' (C\<^sub>0 # Cs,True) \ e) + = (True, frs', (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), err)" +shows + "Jcc_pieces P\<^sub>1 E C M h vs l pc ics frs sh I h' l' sh' v xa (RI (C\<^sub>0,C\<^sub>0\\<^sub>sclinit([])) ; Cs \ e) + = (True, frs', + (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), + \vs'. P \ (None,h,frs',sh) + -jvm\ handle P C M xa h' (vs'@vs) l pc ics frs sh')" +proof - + have cond: "Jcc_cond P\<^sub>1 E C M vs pc ics I h sh (INIT C' (C\<^sub>0 # Cs,True) \ e)" using assms by simp + then have clinit: "\T. P\<^sub>1,E,h,sh \\<^sub>1 C\<^sub>0\\<^sub>sclinit([]) : T" using wf + by clarsimp (auto simp: is_class_def intro: wf\<^sub>1_types_clinit) + then obtain T where cT: "P\<^sub>1,E,h,sh \\<^sub>1 C\<^sub>0\\<^sub>sclinit([]) : T" by blast + obtain T where "P\<^sub>1,E,h,sh \\<^sub>1 INIT C' (C\<^sub>0 # Cs,True) \ unit : T" using cond by fastforce + then have "P\<^sub>1,E,h,sh \\<^sub>1 RI (C\<^sub>0,C\<^sub>0\\<^sub>sclinit([])) ; Cs \ unit : T" + using assms by (auto intro: cT) + then have wtrt: "Ex (WTrt2\<^sub>1 P\<^sub>1 E h sh (RI (C\<^sub>0,C\<^sub>0\\<^sub>sclinit([])) ; Cs \ unit))" + by(simp only: exI) + then show ?thesis using assms by simp +qed + +lemma Jcc_pieces_RInit_clinit: +assumes [simp]: "P \ compP\<^sub>2 P\<^sub>1" and wf: "wf_J\<^sub>1_prog P\<^sub>1" + and "Jcc_pieces P\<^sub>1 E C M h vs l pc ics frs sh I h\<^sub>1 l\<^sub>1 sh\<^sub>1 v xa (RI (C\<^sub>0,C\<^sub>0\\<^sub>sclinit([]));Cs \ e) + = (True, frs', + (None, h\<^sub>1, (vs, l, C, M, pc, Called []) # frs, sh\<^sub>1), err)" +shows + "Jcc_pieces P\<^sub>1 E C M h vs l pc (Called Cs) (tl frs') sh I h' l' sh' v xa (C\<^sub>0\\<^sub>sclinit([])) + = (True, create_init_frame P C\<^sub>0#(vs,l,C,M,pc,Called Cs)#tl frs', + (None, h', (vs,l,C,M,pc,Called Cs)#tl frs', sh'(C\<^sub>0\(fst(the(sh' C\<^sub>0)),Done))), + P \ (None,h,create_init_frame P C\<^sub>0#(vs,l,C,M,pc,Called Cs)#tl frs',sh) + -jvm\ (None,h',(vs, l, C, M, pc, Throwing Cs xa) # tl frs',sh'(C\<^sub>0 \ (fst(the(sh' C\<^sub>0)),Error))))" +proof - + have cond: "Jcc_cond P\<^sub>1 E C M vs pc ics I h sh (RI (C\<^sub>0,C\<^sub>0\\<^sub>sclinit([]));Cs \ e)" using assms by simp + then have wtrt: "\T. P\<^sub>1,E,h,sh \\<^sub>1 C\<^sub>0\\<^sub>sclinit([]) : T" using wf + by clarsimp (auto simp: is_class_def intro: wf\<^sub>1_types_clinit) + then show ?thesis using assms by clarsimp +qed + +lemma Jcc_pieces_RInit_Init: +assumes [simp]: "P \ compP\<^sub>2 P\<^sub>1" and wf: "wf_J\<^sub>1_prog P\<^sub>1" + and proc: "\C' \ set Cs. \sfs. sh'' C' = \(sfs,Processing)\" + and "Jcc_pieces P\<^sub>1 E C M h vs l pc ics frs sh I h\<^sub>1 l\<^sub>1 sh\<^sub>1 v xa (RI (C\<^sub>0,C\<^sub>0\\<^sub>sclinit([]));Cs \ e) + = (True, frs', + (None, h\<^sub>1, (vs, l, C, M, pc, Called []) # frs, sh\<^sub>1), err)" +shows + "Jcc_pieces P\<^sub>1 E C M h' vs l pc ics frs sh'' I h\<^sub>1 l\<^sub>1 sh\<^sub>1 v xa (INIT (last (C\<^sub>0#Cs)) (Cs,True) \ e) + = (True, (vs, l, C, M, pc, Called Cs) # frs, + (None, h\<^sub>1, (vs, l, C, M, pc, Called []) # frs, sh\<^sub>1), + \vs'. P \ (None,h',(vs, l, C, M, pc, Called Cs) # frs,sh'') + -jvm\ handle P C M xa h\<^sub>1 (vs'@vs) l pc ics frs sh\<^sub>1)" +proof - + have "Jcc_cond P\<^sub>1 E C M vs pc ics I h sh (RI (C\<^sub>0,C\<^sub>0\\<^sub>sclinit([]));Cs \ e)" using assms by simp + then have "Ex (WTrt2\<^sub>1 P\<^sub>1 E h sh (RI (C\<^sub>0,C\<^sub>0\\<^sub>sclinit([])) ; Cs \ unit))" by simp + then obtain T where riwt: "P\<^sub>1,E,h,sh \\<^sub>1 RI (C\<^sub>0,C\<^sub>0\\<^sub>sclinit([]));Cs \ unit : T" by meson + then have "P\<^sub>1,E,h',sh'' \\<^sub>1 INIT (last (C\<^sub>0#Cs)) (Cs,True) \ unit : T" using proc + proof(cases Cs) qed(auto) + then have wtrt: "Ex (WTrt2\<^sub>1 P\<^sub>1 E h' sh'' (INIT (last (C\<^sub>0#Cs)) (Cs,True) \ unit))" by(simp only: exI) + show ?thesis using assms wtrt + proof(cases Cs) + case (Cons C1 Cs1) + then show ?thesis using assms wtrt + by(case_tac "method P C1 clinit") clarsimp + qed(clarsimp) +qed + +lemma Jcc_pieces_RInit_RInit: +assumes [simp]: "P \ compP\<^sub>2 P\<^sub>1" + and "Jcc_pieces P\<^sub>1 E C M h vs l pc ics frs sh I h\<^sub>1 l\<^sub>1 sh\<^sub>1 v xa (RI (C\<^sub>0,e);D#Cs \ e') + = (True, frs', rhs, err)" + and hd: "hd frs' = (vs1,l1,C1,M1,pc1,ics1)" +shows + "Jcc_pieces P\<^sub>1 E C M h' vs l pc ics frs sh'' I h\<^sub>1 l\<^sub>1 sh\<^sub>1 v xa (RI (D,Throw xa) ; Cs \ e') + = (True, (vs1, l1, C1, M1, pc1, Throwing (D#Cs) xa) # tl frs', + (None, h\<^sub>1, (vs, l, C, M, pc, Called []) # frs, sh\<^sub>1), + \vs'. P \ (None,h',(vs1, l1, C1, M1, pc1, Throwing (D#Cs) xa) # tl frs',sh'') + -jvm\ handle P C M xa h\<^sub>1 (vs'@vs) l pc ics frs sh\<^sub>1)" +using assms by(case_tac "method P D clinit", cases "e = C\<^sub>0\\<^sub>sclinit([])") clarsimp+ + + +subsubsection "JVM stepping lemmas" + +lemma jvm_Invoke: +assumes [simp]: "P \ compP\<^sub>2 P\<^sub>1" + and "P,C,M,pc \ Invoke M' (length Ts)" + and ha: "h\<^sub>2 a = \(Ca, fs)\" and method: "P\<^sub>1 \ Ca sees M', NonStatic : Ts\T = body in D" + and len: "length pvs = length Ts" and "ls\<^sub>2' = Addr a # pvs @ replicate (max_vars body) undefined" +shows "P \ (None, h\<^sub>2, (rev pvs @ Addr a # vs, ls\<^sub>2, C, M, pc, No_ics) # frs, sh\<^sub>2) -jvm\ + (None, h\<^sub>2, ([], ls\<^sub>2', D, M', 0, No_ics) # (rev pvs @ Addr a # vs, ls\<^sub>2, C, M, pc, No_ics) # frs, sh\<^sub>2)" +proof - + have cname: "cname_of h\<^sub>2 (the_Addr ((rev pvs @ Addr a # vs) ! length Ts)) = Ca" + using ha method len by(auto simp: nth_append) + have r: "(rev pvs @ Addr a # vs) ! (length Ts) = Addr a" using len by(auto simp: nth_append) + have exm: "\Ts T m D b. P \ Ca sees M',b:Ts \ T = m in D" + using sees_method_compP[OF method] by fastforce + show ?thesis using assms cname r exm by simp +qed + +lemma jvm_Invokestatic: +assumes [simp]: "P \ compP\<^sub>2 P\<^sub>1" + and "P,C,M,pc \ Invokestatic C' M' (length Ts)" + and sh: "sh\<^sub>2 D = Some(sfs,Done)" + and method: "P\<^sub>1 \ C' sees M', Static : Ts\T = body in D" + and len: "length pvs = length Ts" and "ls\<^sub>2' = pvs @ replicate (max_vars body) undefined" +shows "P \ (None, h\<^sub>2, (rev pvs @ vs, ls\<^sub>2, C, M, pc, No_ics) # frs, sh\<^sub>2) -jvm\ + (None, h\<^sub>2, ([], ls\<^sub>2', D, M', 0, No_ics) # (rev pvs @ vs, ls\<^sub>2, C, M, pc, No_ics) # frs, sh\<^sub>2)" +proof - + have exm: "\Ts T m D b. P \ C' sees M',b:Ts \ T = m in D" + using sees_method_compP[OF method] by fastforce + show ?thesis using assms exm by simp +qed + +lemma jvm_Invokestatic_Called: +assumes [simp]: "P \ compP\<^sub>2 P\<^sub>1" + and "P,C,M,pc \ Invokestatic C' M' (length Ts)" + and sh: "sh\<^sub>2 D = Some(sfs,i)" + and method: "P\<^sub>1 \ C' sees M', Static : Ts\T = body in D" + and len: "length pvs = length Ts" and "ls\<^sub>2' = pvs @ replicate (max_vars body) undefined" +shows "P \ (None, h\<^sub>2, (rev pvs @ vs, ls\<^sub>2, C, M, pc, Called []) # frs, sh\<^sub>2) -jvm\ + (None, h\<^sub>2, ([], ls\<^sub>2', D, M', 0, No_ics) # (rev pvs @ vs, ls\<^sub>2, C, M, pc, No_ics) # frs, sh\<^sub>2)" +proof - + have exm: "\Ts T m D b. P \ C' sees M',b:Ts \ T = m in D" + using sees_method_compP[OF method] by fastforce + show ?thesis using assms exm by simp +qed + +lemma jvm_Return_Init: +"P,D,clinit,0 \ compE\<^sub>2 body @ [Return] + \ P \ (None, h, (vs, ls, D, clinit, size(compE\<^sub>2 body), No_ics) # frs, sh) + -jvm\ (None, h, frs, sh(D\(fst(the(sh D)),Done)))" +apply(simp add: exec_all_def1, rule r_into_rtrancl, rule exec_1I) +apply(cases frs, auto) +done + +lemma jvm_InitNone: + "\ ics_of f = Calling C Cs; + sh C = None \ + \ P \ (None,h,f#frs,sh) -jvm\ (None,h,f#frs,sh(C \ (sblank P C, Prepared)))" +apply(simp add: exec_all_def1, rule r_into_rtrancl, rule exec_1I) +apply(cases f) apply(rename_tac ics, case_tac ics, simp_all) +done + +lemma jvm_InitDP: + "\ ics_of f = Calling C Cs; + sh C = \(sfs,i)\; i = Done \ i = Processing \ + \ P \ (None,h,f#frs,sh) -jvm\ (None,h,(calling_to_scalled f)#frs,sh)" +apply(simp add: exec_all_def1, rule r_into_rtrancl, rule exec_1I) +apply(cases f) +apply(erule_tac P = "i = Done" in disjE) + apply simp_all +done + +lemma jvm_InitError: + "sh C = \(sfs,Error)\ + \ P \ (None,h,(vs,ls,C\<^sub>0,M,pc,Calling C Cs)#frs,sh) + -jvm\ (None,h,(vs,ls,C\<^sub>0,M,pc,Throwing Cs (addr_of_sys_xcpt NoClassDefFoundError))#frs,sh)" + by(clarsimp simp: exec_all_def1 intro!: r_into_rtrancl exec_1I) + +lemma exec_ErrorThrowing: + "sh C = \(sfs,Error)\ + \ exec (P, (None,h,calling_to_throwing (stk,loc,D,M,pc,Calling C Cs) a#frs,sh)) + = Some (None,h,calling_to_sthrowing (stk,loc,D,M,pc,Calling C Cs) a #frs,sh)" + by(clarsimp simp: exec_all_def1 fun_upd_idem_iff intro!: r_into_rtrancl exec_1I) + +lemma jvm_InitObj: + "\ sh C = Some(sfs,Prepared); + C = Object; + sh' = sh(C \ (sfs,Processing)) \ +\ P \ (None, h, (vs,ls,C\<^sub>0,M,pc,Calling C Cs)#frs, sh) -jvm\ + (None, h, (vs,ls,C\<^sub>0,M,pc,Called (C#Cs))#frs,sh')" +apply(simp add: exec_all_def1, rule r_into_rtrancl, rule exec_1I) +apply(case_tac "method P C clinit", simp) +done + +lemma jvm_InitNonObj: + "\ sh C = Some(sfs,Prepared); + C \ Object; + class P C = Some (D,r); + sh' = sh(C \ (sfs,Processing)) \ +\ P \ (None, h, (vs,ls,C\<^sub>0,M,pc,Calling C Cs)#frs, sh) -jvm\ + (None, h, (vs,ls,C\<^sub>0,M,pc,Calling D (C#Cs))#frs, sh')" +apply(simp add: exec_all_def1, rule r_into_rtrancl, rule exec_1I) +apply(case_tac "method P C clinit", simp) +done + +lemma jvm_RInit_throw: + "P \ (None,h,(vs,l,C,M,pc,Throwing [] xa) # frs,sh) + -jvm\ handle P C M xa h vs l pc No_ics frs sh" +apply(simp add: exec_all_def1, rule r_into_rtrancl, rule exec_1I) +apply(simp add: handle_def split: bool.splits) +done + +lemma jvm_RInit_throw': + "P \ (None,h,(vs,l,C,M,pc,Throwing [C'] xa) # frs,sh) + -jvm\ handle P C M xa h vs l pc No_ics frs (sh(C':=Some(fst(the(sh C')), Error)))" +apply(simp add: exec_all_def1) +apply(rule_tac y = "(None,h,(vs,l,C,M,pc,Throwing [] xa) # frs,sh(C':=Some(fst(the(sh C')), Error)))" in rtrancl_trans) + apply(rule r_into_rtrancl, rule exec_1I) + apply(simp add: handle_def) +apply(cut_tac jvm_RInit_throw) +apply(simp add: exec_all_def1) +done + +lemma jvm_Called: + "P \ (None, h, (vs, l, C, M, pc, Called (C\<^sub>0 # Cs)) # frs, sh) -jvm\ + (None, h, create_init_frame P C\<^sub>0 # (vs, l, C, M, pc, Called Cs) # frs, sh)" + by(simp add: exec_all_def1 r_into_rtrancl exec_1I) + +lemma jvm_Throwing: + "P \ (None, h, (vs, l, C, M, pc, Throwing (C\<^sub>0#Cs) xa') # frs, sh) -jvm\ + (None, h, (vs, l, C, M, pc, Throwing Cs xa') # frs, sh(C\<^sub>0 \ (fst (the (sh C\<^sub>0)), Error)))" + by(simp add: exec_all_def1 r_into_rtrancl exec_1I) + +subsubsection "Other lemmas for correctness proof" + +lemma assumes wf:"wf_prog wf_md P" + and ex: "class P C = Some a" +shows create_init_frame_wf_eq: "create_init_frame (compP\<^sub>2 P) C = (stk,loc,D,M,pc,ics) \ D=C" +using wf_sees_clinit[OF wf ex] by(cases "method P C clinit", auto) + +lemma beforex_try: + "\ {pc..2(try e\<^sub>1 catch(Ci i) e\<^sub>2))} \ I; + P,C,M \ compxE\<^sub>2 (try e\<^sub>1 catch(Ci i) e\<^sub>2) pc (size vs) / I,size vs \ + \ P,C,M \ compxE\<^sub>2 e\<^sub>1 pc (size vs) / {pc..2 e\<^sub>1)},size vs" +apply(clarsimp simp:beforex_def split:if_split_asm) +apply(rename_tac xt\<^sub>0 xt\<^sub>1) apply(rule_tac x=xt\<^sub>0 in exI) +apply(auto simp: pcs_subset(1)) +using atLeastLessThan_iff by blast + +\ \ Evaluation of initialization expressions \ + +(* --needs J1 and EConform; version for eval found in Equivalence *) +lemma +shows eval\<^sub>1_init_return: "P \\<^sub>1 \e,s\ \ \e',s'\ + \ iconf (shp\<^sub>1 s) e + \ (\Cs b. e = INIT C' (Cs,b) \ unit) \ (\C e\<^sub>0 Cs e\<^sub>i. e = RI(C,e\<^sub>0);Cs@[C'] \ unit) + \ (\e\<^sub>0. e = RI(C',e\<^sub>0);Nil \ unit) + \ (val_of e' = Some v \ (\sfs i. shp\<^sub>1 s' C' = \(sfs,i)\ \ (i = Done \ i = Processing))) + \ (throw_of e' = Some a \ (\sfs i. shp\<^sub>1 s' C' = \(sfs,Error)\))" +and "P \\<^sub>1 \es,s\ [\] \es',s'\ \ True" +proof(induct rule: eval\<^sub>1_evals\<^sub>1.inducts) + case (InitFinal\<^sub>1 e s e' s' C b) then show ?case + by(auto simp: initPD_def dest: eval\<^sub>1_final_same) +next + case (InitDone\<^sub>1 sh C sfs C' Cs e h l e' s') + then have "final e'" using eval\<^sub>1_final by simp + then show ?case + proof(rule finalE) + fix v assume e': "e' = Val v" then show ?thesis using InitDone\<^sub>1 initPD_def + proof(cases Cs) qed(auto) + next + fix a assume e': "e' = throw a" then show ?thesis using InitDone\<^sub>1 initPD_def + proof(cases Cs) qed(auto) + qed +next + case (InitProcessing\<^sub>1 sh C sfs C' Cs e h l e' s') + then have "final e'" using eval\<^sub>1_final by simp + then show ?case + proof(rule finalE) + fix v assume e': "e' = Val v" then show ?thesis using InitProcessing\<^sub>1 initPD_def + proof(cases Cs) qed(auto) + next + fix a assume e': "e' = throw a" then show ?thesis using InitProcessing\<^sub>1 initPD_def + proof(cases Cs) qed(auto) + qed +next + case (InitError\<^sub>1 sh C sfs Cs e h l e' s' C') show ?case + proof(cases Cs) + case Nil then show ?thesis using InitError\<^sub>1 by simp + next + case (Cons C2 list) + then have "final e'" using InitError\<^sub>1 eval\<^sub>1_final by simp + then show ?thesis + proof(rule finalE) + fix v assume e': "e' = Val v" show ?thesis + using InitError\<^sub>1.hyps(2) e' rinit\<^sub>1_throwE by blast + next + fix a assume e': "e' = throw a" + then show ?thesis using Cons InitError\<^sub>1 cons_to_append[of list] by clarsimp + qed + qed +next + case (InitRInit\<^sub>1 C Cs h l sh e' s' C') show ?case + proof(cases Cs) + case Nil then show ?thesis using InitRInit\<^sub>1 by simp + next + case (Cons C' list) then show ?thesis + using InitRInit\<^sub>1 Cons cons_to_append[of list] by clarsimp + qed +next + case (RInit\<^sub>1 e s v h' l' sh' C sfs i sh'' C' Cs e' e\<^sub>1 s\<^sub>1) + then have final: "final e\<^sub>1" using eval\<^sub>1_final by simp + then show ?case + proof(cases Cs) + case Nil show ?thesis using final + proof(rule finalE) + fix v assume e': "e\<^sub>1 = Val v" show ?thesis + using RInit\<^sub>1 Nil by(clarsimp, meson fun_upd_same initPD_def) + next + fix a assume e': "e\<^sub>1 = throw a" show ?thesis + using RInit\<^sub>1 Nil by(clarsimp, meson fun_upd_same initPD_def) + qed + next + case (Cons a list) show ?thesis using final + proof(rule finalE) + fix v assume e': "e\<^sub>1 = Val v" then show ?thesis + using RInit\<^sub>1 Cons by(clarsimp, metis last.simps last_appendR list.distinct(1)) + next + fix a assume e': "e\<^sub>1 = throw a" then show ?thesis + using RInit\<^sub>1 Cons by(clarsimp, metis last.simps last_appendR list.distinct(1)) + qed + qed +next + case (RInitInitFail\<^sub>1 e s a h' l' sh' C sfs i sh'' D Cs e' e\<^sub>1 s\<^sub>1) + then have final: "final e\<^sub>1" using eval\<^sub>1_final by simp + then show ?case + proof(rule finalE) + fix v assume e': "e\<^sub>1 = Val v" then show ?thesis + using RInitInitFail\<^sub>1 by(clarsimp, meson exp.distinct(101) rinit\<^sub>1_throwE) + next + fix a' assume e': "e\<^sub>1 = Throw a'" + then have "iconf (sh'(C \ (sfs, Error))) a" + using RInitInitFail\<^sub>1.hyps(1) eval\<^sub>1_final by fastforce + then show ?thesis using RInitInitFail\<^sub>1 e' + by(clarsimp, meson Cons_eq_append_conv list.inject) + qed +qed(auto simp: fun_upd_same) + +lemma init\<^sub>1_Val_PD: "P \\<^sub>1 \INIT C' (Cs,b) \ unit,s\ \ \Val v,s'\ + \ iconf (shp\<^sub>1 s) (INIT C' (Cs,b) \ unit) + \ \sfs i. shp\<^sub>1 s' C' = \(sfs,i)\ \ (i = Done \ i = Processing)" + by(drule_tac v = v in eval\<^sub>1_init_return, simp+) + +lemma init\<^sub>1_throw_PD: "P \\<^sub>1 \INIT C' (Cs,b) \ unit,s\ \ \throw a,s'\ + \ iconf (shp\<^sub>1 s) (INIT C' (Cs,b) \ unit) + \ \sfs i. shp\<^sub>1 s' C' = \(sfs,Error)\" + by(drule_tac a = a in eval\<^sub>1_init_return, simp+) + +lemma rinit\<^sub>1_Val_PD: "P \\<^sub>1 \RI(C,e\<^sub>0);Cs \ unit,s\ \ \Val v,s'\ + \ iconf (shp\<^sub>1 s) (RI(C,e\<^sub>0);Cs \ unit) \ last(C#Cs) = C' + \ \sfs i. shp\<^sub>1 s' C' = \(sfs,i)\ \ (i = Done \ i = Processing)" +apply(drule_tac C' = C' and v = v in eval\<^sub>1_init_return, simp_all) +apply (metis append_butlast_last_id) +done + +lemma rinit\<^sub>1_throw_PD: "P \\<^sub>1 \RI(C,e\<^sub>0);Cs \ unit,s\ \ \throw a,s'\ + \ iconf (shp\<^sub>1 s) (RI(C,e\<^sub>0);Cs \ unit) \ last(C#Cs) = C' + \ \sfs i. shp\<^sub>1 s' C' = \(sfs,Error)\" +apply(drule_tac C' = C' and a = a in eval\<^sub>1_init_return, simp_all) +apply (metis append_butlast_last_id) +done + +subsubsection "The proof" + +lemma fixes P\<^sub>1 defines [simp]: "P \ compP\<^sub>2 P\<^sub>1" +assumes wf: "wf_J\<^sub>1_prog P\<^sub>1" +shows Jcc: "P\<^sub>1 \\<^sub>1 \e,(h\<^sub>0,ls\<^sub>0,sh\<^sub>0)\ \ \ef,(h\<^sub>1,ls\<^sub>1,sh\<^sub>1)\ \ + (\E C M pc ics v xa vs frs I. + \ Jcc_cond P\<^sub>1 E C M vs pc ics I h\<^sub>0 sh\<^sub>0 e \ \ + (ef = Val v \ + P \ (None,h\<^sub>0,Jcc_frames P C M vs ls\<^sub>0 pc ics frs e,sh\<^sub>0) + -jvm\ Jcc_rhs P\<^sub>1 E C M vs ls\<^sub>0 pc ics frs h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v e) + \ + (ef = Throw xa \ Jcc_err P C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>1 ls\<^sub>1 sh\<^sub>1 xa e) + )" +(*<*) + (is "_ \ (\E C M pc ics v xa vs frs I. + PROP ?P e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 ef h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics v xa vs frs I)") +(*>*) +and "P\<^sub>1 \\<^sub>1 \es,(h\<^sub>0,ls\<^sub>0,sh\<^sub>0)\ [\] \fs,(h\<^sub>1,ls\<^sub>1,sh\<^sub>1)\ \ + (\C M pc ics ws xa es' vs frs I. + \ P,C,M,pc \ compEs\<^sub>2 es; P,C,M \ compxEs\<^sub>2 es pc (size vs)/I,size vs; + {pc..2 es)} \ I; ics = No_ics; + \sub_RIs es \ \ + (fs = map Val ws \ + P \ (None,h\<^sub>0,(vs,ls\<^sub>0,C,M,pc,ics)#frs,sh\<^sub>0) -jvm\ + (None,h\<^sub>1,(rev ws @ vs,ls\<^sub>1,C,M,pc+size(compEs\<^sub>2 es),ics)#frs,sh\<^sub>1)) + \ + (fs = map Val ws @ Throw xa # es' \ + (\pc\<^sub>1. pc \ pc\<^sub>1 \ pc\<^sub>1 < pc + size(compEs\<^sub>2 es) \ + \ caught P pc\<^sub>1 h\<^sub>1 xa (compxEs\<^sub>2 es pc (size vs)) \ + (\vs'. P \ (None,h\<^sub>0,(vs,ls\<^sub>0,C,M,pc,ics)#frs,sh\<^sub>0) + -jvm\ handle P C M xa h\<^sub>1 (vs'@vs) ls\<^sub>1 pc\<^sub>1 ics frs sh\<^sub>1))))" +(*<*) + (is "_ \ (\C M pc ics ws xa es' vs frs I. + PROP ?Ps es h\<^sub>0 ls\<^sub>0 sh\<^sub>0 fs h\<^sub>1 ls\<^sub>1 sh\<^sub>1 C M pc ics ws xa es' vs frs I)") +proof (induct rule:eval\<^sub>1_evals\<^sub>1_inducts) + case New\<^sub>1 thus ?case by auto +next + case (NewFail\<^sub>1 sh C' sfs h ls) + let ?xa = "addr_of_sys_xcpt OutOfMemory" + have "P \ (None,h,(vs,ls,C,M,pc,ics)#frs,sh) -jvm\ handle P C M ?xa h vs ls pc ics frs sh" + using NewFail\<^sub>1 by(clarsimp simp: handle_def) + then show ?case by(auto intro!: exI[where x="[]"]) +next + case (NewInit\<^sub>1 sh C' h ls v' h' ls' sh' a FDTs h'') + then obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h vs ls pc ics frs sh I h' ls' sh' v xa (new C') + = (True, frs', (None,h',(v#vs,ls',C,M,pc+size(compE\<^sub>2 (new C')),ics)#frs,sh'), err)" + using NewInit\<^sub>1.prems(1) by clarsimp + have "Ex (WTrt2\<^sub>1 P\<^sub>1 E h sh (INIT C' ([C'],False) \ unit))" + using has_fields_is_class[OF NewInit\<^sub>1.hyps(5)] by auto + then obtain err' where pcs': + "Jcc_pieces P\<^sub>1 E C M h vs ls pc ics frs sh I h' ls' sh' v' xa (INIT C' ([C'],False) \ unit) + = (True, (vs,ls,C,M,pc,Calling C' []) # frs, (None,h',(vs,ls,C,M,pc,Called [])#frs,sh'), err')" + using NewInit\<^sub>1.prems(1) by auto + have IH: "PROP ?P (INIT C' ([C'],False) \ unit) h ls sh (Val v') + h' ls' sh' E C M pc ics v' xa vs frs I" by fact + have ls: "ls = ls'" by(rule init\<^sub>1_same_loc[OF NewInit\<^sub>1.hyps(2)]) + obtain sfs i where sh': "sh' C' = Some(sfs,i)" + using init\<^sub>1_Val_PD[OF NewInit\<^sub>1.hyps(2)] by clarsimp + have "P \ (None,h,(vs,ls,C,M,pc,ics)#frs,sh) -jvm\ (None,h,(vs,ls,C,M,pc,Calling C' [])#frs,sh)" + proof(cases "sh C'") + case None then show ?thesis using NewInit\<^sub>1.prems by(cases ics) auto + next + case (Some a) + then obtain sfs i where "a = (sfs,i)" by(cases a) + then show ?thesis using NewInit\<^sub>1.hyps(1) NewInit\<^sub>1.prems Some + by(cases ics; case_tac i) auto + qed + also have "P \ \ -jvm\ (None, h', (vs, ls, C, M, pc, Called []) # frs, sh')" + using IH pcs' by auto + also have "P \ \ -jvm\ (None, h'', (Addr a#vs, ls, C, M, Suc pc, ics) # frs, sh')" + using NewInit\<^sub>1.hyps(1,2,4-6) NewInit\<^sub>1.prems sh' by(cases ics) auto + finally show ?case using pcs ls by clarsimp +next + case (NewInitOOM\<^sub>1 sh C' h ls v' h' ls' sh') + let ?xa = "addr_of_sys_xcpt OutOfMemory" + obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h vs ls pc ics frs sh I h' ls' sh' v xa (new C') + = (True, frs', (None,h',(v#vs,ls',C,M,pc+size(compE\<^sub>2 (new C')),ics)#frs,sh'), err)" + using NewInitOOM\<^sub>1.prems(1) by clarsimp + have "Ex (WTrt2\<^sub>1 P\<^sub>1 E h sh (INIT C' ([C'],False) \ unit))" using NewInitOOM\<^sub>1.hyps(5) by auto + then obtain err' where pcs': + "Jcc_pieces P\<^sub>1 E C M h vs ls pc ics frs sh I h' ls' sh' v' xa (INIT C' ([C'],False) \ unit) + = (True, (vs,ls,C,M,pc,Calling C' []) # frs, (None,h',(vs,ls,C,M,pc,Called [])#frs,sh'), err')" + using NewInitOOM\<^sub>1.prems(1) by auto + have IH: "PROP ?P (INIT C' ([C'],False) \ unit) h ls sh (Val v') + h' ls' sh' E C M pc ics v' xa vs frs I" by fact + have ls: "ls = ls'" by(rule init\<^sub>1_same_loc[OF NewInitOOM\<^sub>1.hyps(2)]) + have "iconf (shp\<^sub>1 (h, ls, sh)) (INIT C' ([C'],False) \ unit)" by simp + then obtain sfs i where sh': "sh' C' = Some(sfs,i)" + using init\<^sub>1_Val_PD[OF NewInitOOM\<^sub>1.hyps(2)] by clarsimp + have "P \ (None,h,(vs,ls,C,M,pc,ics)#frs,sh) -jvm\ (None,h,(vs,ls,C,M,pc,Calling C' [])#frs,sh)" + proof(cases "sh C'") + case None then show ?thesis using NewInitOOM\<^sub>1.prems by(cases ics) auto + next + case (Some a) + then obtain sfs i where "a = (sfs,i)" by(cases a) + then show ?thesis using NewInitOOM\<^sub>1.hyps(1) NewInitOOM\<^sub>1.prems Some + by(cases ics; case_tac i) auto + qed + also have "P \ \ -jvm\ (None, h', (vs, ls, C, M, pc, Called []) # frs, sh')" + using IH pcs' by auto + also have "P \ \ -jvm\ handle P C M ?xa h' vs ls pc ics frs sh'" + using NewInitOOM\<^sub>1.hyps(1,2,4,5) NewInitOOM\<^sub>1.prems sh' by(auto simp: handle_def) + finally show ?case using pcs ls by(simp, metis (no_types) append_Nil le_refl lessI) +next + case (NewInitThrow\<^sub>1 sh C' h ls a h' ls' sh') + obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h vs ls pc ics frs sh I h' ls' sh' v xa (new C') + = (True, frs', (None,h',(v#vs,ls',C,M,pc+size(compE\<^sub>2 (new C')),ics)#frs,sh'), err)" + using NewInitThrow\<^sub>1.prems(1) by clarsimp + obtain a' where throw: "throw a = Throw a'" using eval\<^sub>1_final[OF NewInitThrow\<^sub>1.hyps(2)] by clarsimp + have "Ex (WTrt2\<^sub>1 P\<^sub>1 E h sh (INIT C' ([C'],False) \ unit))" using NewInitThrow\<^sub>1.hyps(4) by auto + then obtain vs' where pcs': + "Jcc_pieces P\<^sub>1 E C M h vs ls pc ics frs sh I h' ls' sh' v a' (INIT C' ([C'],False) \ unit) + = (True, (vs,ls,C,M,pc,Calling C' []) # frs, (None,h',(vs,ls,C,M,pc,Called [])#frs,sh'), + P \ (None,h,(vs,ls,C,M,pc,Calling C' []) # frs,sh) + -jvm\ handle P C M a' h' (vs'@vs) ls pc ics frs sh')" + using NewInitThrow\<^sub>1.prems(1) by simp blast + have IH: "PROP ?P (INIT C' ([C'],False) \ unit) h ls sh (throw a) + h' ls' sh' E C M pc ics v a' vs frs I" by fact + have ls: "ls = ls'" by(rule init\<^sub>1_same_loc[OF NewInitThrow\<^sub>1.hyps(2)]) + then have "P \ (None,h,(vs,ls,C,M,pc,ics)#frs,sh) -jvm\ (None,h,(vs,ls,C,M,pc,Calling C' []) # frs,sh)" + proof(cases "sh C'") + case None then show ?thesis using NewInitThrow\<^sub>1.prems by(cases ics) auto + next + case (Some a) + then obtain sfs i where "a = (sfs,i)" by(cases a) + then show ?thesis using NewInitThrow\<^sub>1.hyps(1) NewInitThrow\<^sub>1.prems Some + by(cases ics; case_tac i) auto + qed + also have "P \ \ -jvm\ handle P C M a' h' (vs'@vs) ls pc ics frs sh'" using IH pcs' throw by auto + finally show ?case using throw ls by auto +next + case (Cast\<^sub>1 e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 a h\<^sub>1 ls\<^sub>1 sh\<^sub>1 D fs C') + let ?pc = "pc + length(compE\<^sub>2 e)" + obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v xa (Cast C' e) + = (True, frs', (None,h\<^sub>1,(v#vs,ls\<^sub>1,C,M,pc+size(compE\<^sub>2 (Cast C' e)),ics)#frs,sh\<^sub>1), err)" + using Cast\<^sub>1.prems(1) by auto + have IH: "PROP ?P e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (addr a) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics (Addr a) xa vs frs I" by fact + then have "P \ (None,h\<^sub>0,(vs,ls\<^sub>0,C,M,pc,ics)#frs,sh\<^sub>0) -jvm\ + (None,h\<^sub>1,(Addr a#vs,ls\<^sub>1,C,M,?pc,ics)#frs,sh\<^sub>1)" + using Jcc_pieces_Cast[OF assms(1) pcs, of "Addr a"] Cast\<^sub>1.prems pcs by auto + also have "P \ \ -jvm\ (None,h\<^sub>1,(Addr a#vs,ls\<^sub>1,C,M,?pc+1,ics)#frs,sh\<^sub>1)" + using Cast\<^sub>1 by (auto simp add:cast_ok_def) + finally show ?case by auto +next + case (CastNull\<^sub>1 e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 h\<^sub>1 ls\<^sub>1 sh\<^sub>1 C') + let ?pc = "pc + length(compE\<^sub>2 e)" + obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v xa (Cast C' e) + = (True, frs', (None,h\<^sub>1,(v#vs,ls\<^sub>1,C,M,pc+size(compE\<^sub>2 (Cast C' e)),ics)#frs,sh\<^sub>1), err)" + using CastNull\<^sub>1.prems(1) by clarsimp + have IH: "PROP ?P e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 null h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics Null xa vs frs I" by fact + then have "P \ (None,h\<^sub>0,(vs,ls\<^sub>0,C,M,pc,ics)#frs,sh\<^sub>0) -jvm\ + (None,h\<^sub>1,(Null#vs,ls\<^sub>1,C,M,?pc,ics)#frs,sh\<^sub>1)" + using Jcc_pieces_Cast[OF assms(1) pcs, of Null] CastNull\<^sub>1.prems pcs by auto + also have "P \ \ -jvm\ (None,h\<^sub>1,(Null#vs,ls\<^sub>1,C,M,?pc+1,ics)#frs,sh\<^sub>1)" + using CastNull\<^sub>1 by (auto simp add:cast_ok_def) + finally show ?case by auto +next + case (CastFail\<^sub>1 e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 a h\<^sub>1 ls\<^sub>1 sh\<^sub>1 D fs C') + let ?pc = "pc + length(compE\<^sub>2 e)" + let ?xa = "addr_of_sys_xcpt ClassCast" + obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v xa (Cast C' e) + = (True, frs', (None,h\<^sub>1,(v#vs,ls\<^sub>1,C,M,pc+size(compE\<^sub>2 (Cast C' e)),ics)#frs,sh\<^sub>1), err)" + using CastFail\<^sub>1.prems(1) by clarsimp + have IH: "PROP ?P e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (addr a) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics (Addr a) xa vs frs I" by fact + then have "P \ (None,h\<^sub>0,(vs,ls\<^sub>0,C,M,pc,ics)#frs,sh\<^sub>0) -jvm\ + (None,h\<^sub>1,(Addr a#vs,ls\<^sub>1,C,M,?pc,ics)#frs,sh\<^sub>1)" + using Jcc_pieces_Cast[OF assms(1) pcs, of "Addr a"] CastFail\<^sub>1.prems pcs by auto + also have "P \ \ -jvm\ handle P C M ?xa h\<^sub>1 (Addr a#vs) ls\<^sub>1 ?pc ics frs sh\<^sub>1" + using CastFail\<^sub>1 by (auto simp add:handle_def cast_ok_def) + finally have exec: "P \ (None,h\<^sub>0,(vs,ls\<^sub>0,C,M,pc,ics)#frs,sh\<^sub>0) -jvm\ \". + show ?case (is "?N \ (?eq \ ?err)") + proof + show ?N by simp + next + { assume ?eq + then have ?err using exec by (auto intro!: exI[where x="?pc"] exI[where x="[Addr a]"]) + } + thus "?eq \ ?err" by simp + qed +next + case (CastThrow\<^sub>1 e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 e' h\<^sub>1 ls\<^sub>1 sh\<^sub>1 C') + obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v xa (Cast C' e) + = (True, frs', (None,h\<^sub>1,(v#vs,ls\<^sub>1,C,M,pc+size(compE\<^sub>2 (Cast C' e)),ics)#frs,sh\<^sub>1), err)" + using CastThrow\<^sub>1.prems(1) by clarsimp + have IH: "PROP ?P e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (throw e') h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics v xa vs frs I" by fact + show ?case using IH Jcc_pieces_Cast[OF assms(1) pcs, of v] CastThrow\<^sub>1.prems pcs less_SucI + by(simp, blast) +next + case Val\<^sub>1 thus ?case by auto +next + case Var\<^sub>1 thus ?case by auto +next + case (BinOp\<^sub>1 e\<^sub>1 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 v\<^sub>1 h\<^sub>1 ls\<^sub>1 sh\<^sub>1 e\<^sub>2 v\<^sub>2 h\<^sub>2 ls\<^sub>2 sh\<^sub>2 bop w) + obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>2 ls\<^sub>2 sh\<^sub>2 v xa (e\<^sub>1 \bop\ e\<^sub>2) + = (True, frs', (None,h\<^sub>2,(v#vs,ls\<^sub>2,C,M,pc+size(compE\<^sub>2 (e\<^sub>1 \bop\ e\<^sub>2)),ics)#frs,sh\<^sub>2), err)" + using BinOp\<^sub>1.prems(1) by clarsimp + let ?pc\<^sub>1 = "pc + length(compE\<^sub>2 e\<^sub>1)" + let ?pc\<^sub>2 = "?pc\<^sub>1 + length(compE\<^sub>2 e\<^sub>2)" + have IH\<^sub>1: "PROP ?P e\<^sub>1 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (Val v\<^sub>1) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics v\<^sub>1 xa vs frs + (I - pcs (compxE\<^sub>2 e\<^sub>2 (pc + length (compE\<^sub>2 e\<^sub>1)) (Suc (length vs))))" by fact + have IH\<^sub>2: "PROP ?P e\<^sub>2 h\<^sub>1 ls\<^sub>1 sh\<^sub>1 (Val v\<^sub>2) h\<^sub>2 ls\<^sub>2 sh\<^sub>2 E C M ?pc\<^sub>1 ics v\<^sub>2 xa (v\<^sub>1#vs) frs + (I - pcs(compxE\<^sub>2 e\<^sub>1 pc (size vs)))" by fact + have "P \ (None,h\<^sub>0,frs',sh\<^sub>0) -jvm\ (None,h\<^sub>1,(v\<^sub>1#vs,ls\<^sub>1,C,M,?pc\<^sub>1,ics)#frs,sh\<^sub>1)" + using IH\<^sub>1 Jcc_pieces_BinOp1[OF pcs, of h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v\<^sub>1] by simp + also have "P \ \ -jvm\ (None,h\<^sub>2,(v\<^sub>2#v\<^sub>1#vs,ls\<^sub>2,C,M,?pc\<^sub>2,ics)#frs,sh\<^sub>2)" + using IH\<^sub>2 Jcc_pieces_BinOp2[OF assms(1) pcs, of h\<^sub>1 v\<^sub>1 ls\<^sub>1 sh\<^sub>1 v\<^sub>2] by (simp add: add.assoc) + also have "P \ \ -jvm\ (None,h\<^sub>2,(w#vs,ls\<^sub>2,C,M,?pc\<^sub>2+1,ics)#frs,sh\<^sub>2)" + using BinOp\<^sub>1 by(cases bop) auto + finally show ?case using pcs by (auto split: bop.splits simp:add.assoc) +next + case (BinOpThrow\<^sub>1\<^sub>1 e\<^sub>1 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 e h\<^sub>1 ls\<^sub>1 sh\<^sub>1 bop e\<^sub>2) + obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v xa (e\<^sub>1 \bop\ e\<^sub>2) + = (True, frs', (None,h\<^sub>1,(v#vs,ls\<^sub>1,C,M,pc+size(compE\<^sub>2 (e\<^sub>1 \bop\ e\<^sub>2)),ics)#frs,sh\<^sub>1), err)" + using BinOpThrow\<^sub>1\<^sub>1.prems(1) by clarsimp + have IH\<^sub>1: "PROP ?P e\<^sub>1 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (throw e) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics v xa vs frs + (I - pcs (compxE\<^sub>2 e\<^sub>2 (pc + length (compE\<^sub>2 e\<^sub>1)) (Suc (length vs))))" by fact + show ?case using IH\<^sub>1 Jcc_pieces_BinOp1[OF pcs, of h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v] BinOpThrow\<^sub>1\<^sub>1.prems nsub_RI_Jcc_pieces + by auto +next + case (BinOpThrow\<^sub>2\<^sub>1 e\<^sub>1 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 v\<^sub>1 h\<^sub>1 ls\<^sub>1 sh\<^sub>1 e\<^sub>2 e h\<^sub>2 ls\<^sub>2 sh\<^sub>2 bop) + obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>2 ls\<^sub>2 sh\<^sub>2 v xa (e\<^sub>1 \bop\ e\<^sub>2) + = (True, frs', (None,h\<^sub>2,(v#vs,ls\<^sub>2,C,M,pc+size(compE\<^sub>2 (e\<^sub>1 \bop\ e\<^sub>2)),ics)#frs,sh\<^sub>2), err)" + using BinOpThrow\<^sub>2\<^sub>1.prems(1) by clarsimp + let ?pc = "pc + length(compE\<^sub>2 e\<^sub>1)" + have IH\<^sub>1: "PROP ?P e\<^sub>1 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (Val v\<^sub>1) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics v\<^sub>1 xa vs frs + (I - pcs (compxE\<^sub>2 e\<^sub>2 (pc + length (compE\<^sub>2 e\<^sub>1)) (Suc (length vs))))" by fact + have IH\<^sub>2: "PROP ?P e\<^sub>2 h\<^sub>1 ls\<^sub>1 sh\<^sub>1 (throw e) h\<^sub>2 ls\<^sub>2 sh\<^sub>2 E C M ?pc ics v xa (v\<^sub>1#vs) frs + (I - pcs(compxE\<^sub>2 e\<^sub>1 pc (size vs)))" by fact + let ?\\<^sub>1 = "(None,h\<^sub>1,(v\<^sub>1#vs,ls\<^sub>1,C,M,?pc,ics)#frs,sh\<^sub>1)" + have 1: "P \ (None,h\<^sub>0,frs',sh\<^sub>0) -jvm\ ?\\<^sub>1" + using IH\<^sub>1 Jcc_pieces_BinOp1[OF pcs, of h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v\<^sub>1] by simp + have "(throw e = Val v \ P \ (None, h\<^sub>0, Jcc_frames P C M vs ls\<^sub>0 pc ics frs (e\<^sub>1 \bop\ e\<^sub>2), sh\<^sub>0) -jvm\ + Jcc_rhs P\<^sub>1 E C M vs ls\<^sub>0 pc ics frs h\<^sub>2 ls\<^sub>2 sh\<^sub>2 v (e\<^sub>1 \bop\ e\<^sub>2)) + \ (throw e = Throw xa \ (\pc\<^sub>1. pc \ pc\<^sub>1 \ pc\<^sub>1 < pc + size(compE\<^sub>2 (e\<^sub>1 \bop\ e\<^sub>2)) \ + \ caught P pc\<^sub>1 h\<^sub>2 xa (compxE\<^sub>2 (e\<^sub>1 \bop\ e\<^sub>2) pc (size vs)) \ + (\vs'. P \ (None,h\<^sub>0,frs',sh\<^sub>0) -jvm\ handle P C M xa h\<^sub>2 (vs'@vs) ls\<^sub>2 pc\<^sub>1 ics frs sh\<^sub>2)))" + (is "?N \ (?eq \ (\pc\<^sub>2. ?H pc\<^sub>2))") + proof + show ?N by simp + next + { assume ?eq + then obtain pc\<^sub>2 vs' where + pc\<^sub>2: "?pc \ pc\<^sub>2 \ pc\<^sub>2 < ?pc + size(compE\<^sub>2 e\<^sub>2) \ + \ caught P pc\<^sub>2 h\<^sub>2 xa (compxE\<^sub>2 e\<^sub>2 ?pc (size vs + 1))" and + 2: "P \ ?\\<^sub>1 -jvm\ handle P C M xa h\<^sub>2 (vs'@v\<^sub>1#vs) ls\<^sub>2 pc\<^sub>2 ics frs sh\<^sub>2" + using IH\<^sub>2 Jcc_pieces_BinOp2[OF assms(1) pcs, of h\<^sub>1 v\<^sub>1 ls\<^sub>1 sh\<^sub>1 v] BinOpThrow\<^sub>2\<^sub>1.prems by clarsimp + then have "?H pc\<^sub>2" using jvm_trans[OF 1 2] by(auto intro!: exI[where x="vs'@[v\<^sub>1]"]) + hence "\pc\<^sub>2. ?H pc\<^sub>2" by iprover + } + thus "?eq \ (\pc\<^sub>2. ?H pc\<^sub>2)" by iprover + qed + then show ?case using pcs by simp blast +next + case (FAcc\<^sub>1 e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 a h\<^sub>1 ls\<^sub>1 sh\<^sub>1 C' fs F T D w) + then obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v xa (e\F{D}) + = (True, frs', (None,h\<^sub>1,(v#vs,ls\<^sub>1,C,M,pc+size(compE\<^sub>2 (e\F{D})),ics)#frs,sh\<^sub>1), err)" + using FAcc\<^sub>1.prems(1) by clarsimp + have "P\<^sub>1 \ D sees F,NonStatic:T in D" by(rule has_field_sees[OF has_field_idemp[OF FAcc\<^sub>1.hyps(4)]]) + then have field: "field P D F = (D,NonStatic,T)" by simp + have IH: "PROP ?P e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (addr a) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics (Addr a) xa vs frs I" by fact + let ?pc = "pc + length(compE\<^sub>2 e)" + have "P \ (None,h\<^sub>0,frs',sh\<^sub>0) -jvm\ (None,h\<^sub>1,(Addr a#vs,ls\<^sub>1,C,M,?pc,ics)#frs,sh\<^sub>1)" + using IH Jcc_pieces_FAcc[OF pcs, of "Addr a"] pcs by simp + also have "P \ \ -jvm\ (None,h\<^sub>1,(w#vs,ls\<^sub>1,C,M,?pc+1,ics)#frs,sh\<^sub>1)" + using FAcc\<^sub>1 field by auto + finally have "P \ (None, h\<^sub>0, frs', sh\<^sub>0) -jvm\ (None,h\<^sub>1,(w#vs,ls\<^sub>1,C,M,?pc+1,ics)#frs,sh\<^sub>1)" + by auto + then show ?case using pcs by auto +next + case (FAccNull\<^sub>1 e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 h\<^sub>1 ls\<^sub>1 sh\<^sub>1 F D) + then obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v xa (e\F{D}) + = (True, frs', (None,h\<^sub>1,(v#vs,ls\<^sub>1,C,M,pc+size(compE\<^sub>2 (e\F{D})),ics)#frs,sh\<^sub>1), err)" + using FAccNull\<^sub>1.prems(1) by clarsimp + have IH: "PROP ?P e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 null h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics Null xa vs frs I" by fact + let ?pc = "pc + length(compE\<^sub>2 e)" + let ?xa = "addr_of_sys_xcpt NullPointer" + have "P \ (None,h\<^sub>0,frs',sh\<^sub>0) -jvm\ (None,h\<^sub>1,(Null#vs,ls\<^sub>1,C,M,?pc,ics)#frs,sh\<^sub>1)" + using IH Jcc_pieces_FAcc[OF pcs, of Null] by simp + also have "P \ \ -jvm\ handle P C M ?xa h\<^sub>1 (Null#vs) ls\<^sub>1 ?pc ics frs sh\<^sub>1" + using FAccNull\<^sub>1.prems + by(fastforce simp:split_beta handle_def simp del: split_paired_Ex) + finally show ?case using pcs by (auto intro!: exI[where x = ?pc] exI[where x="[Null]"]) +next + case (FAccThrow\<^sub>1 e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 e' h\<^sub>1 ls\<^sub>1 sh\<^sub>1 F D) + then obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v xa (e\F{D}) + = (True, frs', (None,h\<^sub>1,(v#vs,ls\<^sub>1,C,M,pc+size(compE\<^sub>2 (e\F{D})),ics)#frs,sh\<^sub>1), err)" + using FAccThrow\<^sub>1.prems(1) by clarsimp + have IH: "PROP ?P e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (throw e') h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics v xa vs frs I" by fact + show ?case using IH Jcc_pieces_FAcc[OF pcs, of v] FAccThrow\<^sub>1.prems nsub_RI_Jcc_pieces + less_Suc_eq by auto +next + case (FAccNone\<^sub>1 e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 a h\<^sub>1 ls\<^sub>1 sh\<^sub>1 C fs F D) + then obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v xa (e\F{D}) + = (True, frs', (None,h\<^sub>1,(v#vs,ls\<^sub>1,C,M,pc+size(compE\<^sub>2 (e\F{D})),ics)#frs,sh\<^sub>1), err)" + using FAccNone\<^sub>1.prems(1) by clarsimp + have IH: "PROP ?P e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (addr a) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics (Addr a) xa vs frs I" by fact + let ?pc = "pc + length(compE\<^sub>2 e)" + let ?xa = "addr_of_sys_xcpt NoSuchFieldError" + have "P \ (None,h\<^sub>0,frs',sh\<^sub>0) -jvm\ (None,h\<^sub>1,(Addr a#vs,ls\<^sub>1,C,M,?pc,ics)#frs,sh\<^sub>1)" + using IH Jcc_pieces_FAcc[OF pcs, of "Addr a"] by simp + also have "P \ \ -jvm\ handle P C M ?xa h\<^sub>1 (Addr a#vs) ls\<^sub>1 ?pc ics frs sh\<^sub>1" + using FAccNone\<^sub>1 + by(cases ics; clarsimp simp:split_beta handle_def simp del: split_paired_Ex) + finally show ?case using pcs by (auto intro!: exI[where x = ?pc] exI[where x="[Addr a]"]) +next + case (FAccStatic\<^sub>1 e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 a h\<^sub>1 ls\<^sub>1 sh\<^sub>1 C' fs F T D) + then obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v xa (e\F{D}) + = (True, frs', (None,h\<^sub>1,(v#vs,ls\<^sub>1,C,M,pc+size(compE\<^sub>2 (e\F{D})),ics)#frs,sh\<^sub>1), err)" + using FAccStatic\<^sub>1.prems(1) by clarsimp + have "P\<^sub>1 \ D sees F,Static:T in D" by(rule has_field_sees[OF has_field_idemp[OF FAccStatic\<^sub>1.hyps(4)]]) + then have field: "field P D F = (D,Static,T)" by simp + have IH: "PROP ?P e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (addr a) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics (Addr a) xa vs frs I" by fact + let ?pc = "pc + length(compE\<^sub>2 e)" + let ?xa = "addr_of_sys_xcpt IncompatibleClassChangeError" + have "P \ (None,h\<^sub>0,frs',sh\<^sub>0) -jvm\ (None,h\<^sub>1,(Addr a#vs,ls\<^sub>1,C,M,?pc,ics)#frs,sh\<^sub>1)" + using IH Jcc_pieces_FAcc[OF pcs, of "Addr a"] by simp + also have "P \ \ -jvm\ handle P C M ?xa h\<^sub>1 (Addr a#vs) ls\<^sub>1 ?pc ics frs sh\<^sub>1" + using FAccStatic\<^sub>1 field by(fastforce simp:split_beta handle_def simp del: split_paired_Ex) + finally show ?case using pcs by (auto intro!: exI[where x = ?pc] exI[where x="[Addr a]"]) +next + case (SFAcc\<^sub>1 C' F t D sh sfs v' h ls) + have has: "P\<^sub>1 \ D has F,Static:t in D" by(rule has_field_idemp[OF SFAcc\<^sub>1.hyps(1)]) + have "P\<^sub>1 \ D sees F,Static:t in D" by(rule has_field_sees[OF has]) + then have field: "field P D F = (D,Static,t)" by simp + then have "P \ (None,h,Jcc_frames P C M vs ls pc ics frs (C'\\<^sub>sF{D}),sh) -jvm\ + (None,h,(v'#vs,ls,C,M,Suc pc,ics)#frs,sh)" + using SFAcc\<^sub>1 has by(cases ics) auto + then show ?case by clarsimp +next + case (SFAccInit\<^sub>1 C' F t D sh h ls v' h' ls' sh' sfs i v'') + then obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h vs ls pc ics frs sh I h' ls' sh' v xa (C'\\<^sub>sF{D}) + = (True, frs', (None,h',(v#vs,ls',C,M,pc+size(compE\<^sub>2 (C'\\<^sub>sF{D})),ics)#frs,sh'), err)" + using SFAccInit\<^sub>1.prems(1) by clarsimp + have "Ex (WTrt2\<^sub>1 P\<^sub>1 E h sh (INIT D ([D],False) \ unit))" + using has_field_is_class'[OF SFAccInit\<^sub>1.hyps(1)] by auto + then obtain err' where pcs': + "Jcc_pieces P\<^sub>1 E C M h vs ls pc ics frs sh I h' ls' sh' v' xa (INIT D ([D],False) \ unit) + = (True, (vs,ls,C,M,pc,Calling D []) # frs, (None,h',(vs,ls,C,M,pc,Called [])#frs,sh'), err')" + using SFAccInit\<^sub>1.prems(1) by auto + have IH: "PROP ?P (INIT D ([D],False) \ unit) h ls sh (Val v') + h' ls' sh' E C M pc ics v' xa vs frs I" by fact + have ls: "ls = ls'" by(rule init\<^sub>1_same_loc[OF SFAccInit\<^sub>1.hyps(3)]) + have has: "P\<^sub>1 \ D has F,Static:t in D" by(rule has_field_idemp[OF SFAccInit\<^sub>1.hyps(1)]) + have "P\<^sub>1 \ D sees F,Static:t in D" by(rule has_field_sees[OF has]) + then have field: "field P D F = (D,Static,t)" by simp + have "P \ (None,h,(vs,ls,C,M,pc,ics)#frs,sh) -jvm\ (None,h,(vs,ls,C,M,pc,Calling D [])#frs,sh)" + proof(cases "sh D") + case None then show ?thesis using SFAccInit\<^sub>1.hyps(1,2,5,6) SFAccInit\<^sub>1.prems field + by(cases ics) auto + next + case (Some a) + then obtain sfs i where "a = (sfs,i)" by(cases a) + then show ?thesis using SFAccInit\<^sub>1.hyps(1,2,5,6) SFAccInit\<^sub>1.prems field Some + by(cases ics; case_tac i) auto + qed + also have "P \ ... -jvm\ (None, h', (vs, ls, C, M, pc, Called []) # frs, sh')" + using IH pcs' by auto + also have "P \ ... -jvm\ (None, h', (v''#vs, ls, C, M, Suc pc, ics) # frs, sh')" + using SFAccInit\<^sub>1.hyps(1,2,5,6) SFAccInit\<^sub>1.prems has field by(cases ics) auto + finally show ?case using pcs ls by clarsimp +next + case (SFAccInitThrow\<^sub>1 C' F t D sh h ls a h' ls' sh') + obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h vs ls pc ics frs sh I h' ls' sh' v xa (C'\\<^sub>sF{D}) + = (True, frs', (None,h',(v#vs,ls',C,M,pc+size(compE\<^sub>2 (C'\\<^sub>sF{D})),ics)#frs,sh'), err)" + using SFAccInitThrow\<^sub>1.prems(1) by clarsimp + obtain a' where throw: "throw a = Throw a'" using eval\<^sub>1_final[OF SFAccInitThrow\<^sub>1.hyps(3)] by clarsimp + have "Ex (WTrt2\<^sub>1 P\<^sub>1 E h sh (INIT D ([D],False) \ unit))" + using has_field_is_class'[OF SFAccInitThrow\<^sub>1.hyps(1)] by auto + then obtain vs' where pcs': + "Jcc_pieces P\<^sub>1 E C M h vs ls pc ics frs sh I h' ls' sh' v a' (INIT D ([D],False) \ unit) + = (True, (vs,ls,C,M,pc,Calling D []) # frs, (None,h',(vs,ls,C,M,pc,Called [])#frs,sh'), + P \ (None,h,(vs,ls,C,M,pc,Calling D []) # frs,sh) + -jvm\ handle P C M a' h' (vs'@vs) ls pc ics frs sh')" + using SFAccInitThrow\<^sub>1.prems(1) by simp blast + have IH: "PROP ?P (INIT D ([D],False) \ unit) h ls sh (throw a) + h' ls' sh' E C M pc ics v a' vs frs I" by fact + have ls: "ls = ls'" by(rule init\<^sub>1_same_loc[OF SFAccInitThrow\<^sub>1.hyps(3)]) + have has: "P\<^sub>1 \ D has F,Static:t in D" by(rule has_field_idemp[OF SFAccInitThrow\<^sub>1.hyps(1)]) + have "P\<^sub>1 \ D sees F,Static:t in D" by(rule has_field_sees[OF has]) + then have field: "field P D F = (D,Static,t)" by simp + then have "P \ (None,h,(vs,ls,C,M,pc,ics)#frs,sh) -jvm\ (None,h,(vs,ls,C,M,pc,Calling D []) # frs,sh)" + proof(cases "sh D") + case None then show ?thesis using SFAccInitThrow\<^sub>1.hyps(1,2) SFAccInitThrow\<^sub>1.prems field + by(cases ics) auto + next + case (Some a) + then obtain sfs i where "a = (sfs,i)" by(cases a) + then show ?thesis using SFAccInitThrow\<^sub>1.hyps(1,2) SFAccInitThrow\<^sub>1.prems field Some + by(cases ics; case_tac i) auto + qed + also have "P \ \ -jvm\ handle P C M a' h' (vs'@vs) ls pc ics frs sh'" + using IH pcs' throw by auto + finally show ?case using throw ls by auto +next + case (SFAccNone\<^sub>1 C' F D h\<^sub>1 ls\<^sub>1 sh\<^sub>1) + then obtain frs' err where pcs: + "Jcc_pieces P\<^sub>1 E C M h\<^sub>1 vs ls\<^sub>1 pc ics frs sh\<^sub>1 I h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v xa (C'\\<^sub>sF{D}) + = (True, frs', (None,h\<^sub>1,(v#vs,ls\<^sub>1,C,M,pc+size(compE\<^sub>2 (C'\\<^sub>sF{D})),ics)#frs,sh\<^sub>1), err)" + by clarsimp + let ?xa = "addr_of_sys_xcpt NoSuchFieldError" + have "P \ (None,h\<^sub>1,frs',sh\<^sub>1) -jvm\ handle P C M ?xa h\<^sub>1 vs ls\<^sub>1 pc ics frs sh\<^sub>1" + using SFAccNone\<^sub>1 pcs + by(cases ics; clarsimp simp:split_beta handle_def simp del: split_paired_Ex) + then show ?case using pcs by(auto intro!: exI[where x = pc] exI[where x="[]"]) +next + case (SFAccNonStatic\<^sub>1 C' F t D h\<^sub>1 ls\<^sub>1 sh\<^sub>1) + let ?frs' = "(vs, ls\<^sub>1, C, M, pc, ics) # frs" + let ?xa = "addr_of_sys_xcpt IncompatibleClassChangeError" + have "P\<^sub>1 \ D sees F,NonStatic:t in D" + by(rule has_field_sees[OF has_field_idemp[OF SFAccNonStatic\<^sub>1.hyps(1)]]) + then have field: "field P D F = (D,NonStatic,t)" by simp + have "P \ (None,h\<^sub>1,?frs',sh\<^sub>1) -jvm\ handle P C M ?xa h\<^sub>1 vs ls\<^sub>1 pc ics frs sh\<^sub>1" + using SFAccNonStatic\<^sub>1 + proof(cases ics) + case No_ics + then show ?thesis using SFAccNonStatic\<^sub>1 field + by (auto simp:split_beta handle_def simp del: split_paired_Ex) + qed(simp_all) + then show ?case by (auto intro!: exI[where x = pc] exI[where x="[]"]) +next + case (LAss\<^sub>1 e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 w h\<^sub>1 ls\<^sub>1 sh\<^sub>1 i ls\<^sub>2) + let ?pc = "pc + length(compE\<^sub>2 e)" + obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v xa (i:=e) + = (True, frs', (None,h\<^sub>1,(v#vs,ls\<^sub>1,C,M,pc+size(compE\<^sub>2 (i:=e)),ics)#frs,sh\<^sub>1), err)" + using LAss\<^sub>1.prems(1) by auto + have IH: "PROP ?P e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (Val w) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics w xa vs frs I" by fact + then have "P \ (None,h\<^sub>0,(vs,ls\<^sub>0,C,M,pc,ics)#frs,sh\<^sub>0) -jvm\ + (None,h\<^sub>1,(w#vs,ls\<^sub>1,C,M,?pc,ics)#frs,sh\<^sub>1)" + using Jcc_pieces_LAss[OF assms(1) pcs, of w] LAss\<^sub>1.prems pcs by auto + also have "P \ \ -jvm\ (None,h\<^sub>1,(Unit#vs,ls\<^sub>2,C,M,?pc+2,ics)#frs,sh\<^sub>1)" + using LAss\<^sub>1 by (auto simp add:cast_ok_def) + finally show ?case by auto +next + case (LAssThrow\<^sub>1 e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 w h\<^sub>1 ls\<^sub>1 sh\<^sub>1 i) + obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v xa (i:=e) + = (True, frs', (None,h\<^sub>1,(v#vs,ls\<^sub>1,C,M,pc+size(compE\<^sub>2 (i:=e)),ics)#frs,sh\<^sub>1), err)" + using LAssThrow\<^sub>1.prems(1) by clarsimp + have IH: "PROP ?P e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (throw w) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics v xa vs frs I" by fact + show ?case using IH Jcc_pieces_LAss[OF assms(1) pcs, of v] LAssThrow\<^sub>1.prems pcs less_SucI + by(simp, blast) +next + case (FAss\<^sub>1 e\<^sub>1 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 a h\<^sub>1 ls\<^sub>1 sh\<^sub>1 e\<^sub>2 w h\<^sub>2 ls\<^sub>2 sh\<^sub>2 C' fs F T D fs' h\<^sub>2') + obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>2 ls\<^sub>2 sh\<^sub>2 v xa (e\<^sub>1\F{D} := e\<^sub>2) + = (True, frs', (None,h\<^sub>2,(v#vs,ls\<^sub>2,C,M,pc+size(compE\<^sub>2 (e\<^sub>1\F{D} := e\<^sub>2)),ics)#frs,sh\<^sub>2), err)" + using FAss\<^sub>1.prems(1) by clarsimp + have "P\<^sub>1 \ D sees F,NonStatic:T in D" by(rule has_field_sees[OF has_field_idemp[OF FAss\<^sub>1.hyps(6)]]) + then have field: "field P D F = (D,NonStatic,T)" by simp + let ?pc\<^sub>1 = "pc + length(compE\<^sub>2 e\<^sub>1)" + let ?pc\<^sub>2 = "?pc\<^sub>1 + length(compE\<^sub>2 e\<^sub>2)" + have IH\<^sub>1: "PROP ?P e\<^sub>1 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (addr a) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics (Addr a) xa vs frs + (I - pcs (compxE\<^sub>2 e\<^sub>2 (pc + length (compE\<^sub>2 e\<^sub>1)) (Suc (length vs))))" by fact + have IH\<^sub>2: "PROP ?P e\<^sub>2 h\<^sub>1 ls\<^sub>1 sh\<^sub>1 (Val w) h\<^sub>2 ls\<^sub>2 sh\<^sub>2 E C M ?pc\<^sub>1 ics w xa (Addr a#vs) frs + (I - pcs(compxE\<^sub>2 e\<^sub>1 pc (size vs)))" by fact + have "P \ (None,h\<^sub>0,frs',sh\<^sub>0) -jvm\ (None,h\<^sub>1,(Addr a#vs,ls\<^sub>1,C,M,?pc\<^sub>1,ics)#frs,sh\<^sub>1)" + using IH\<^sub>1 Jcc_pieces_FAss1[OF pcs, of h\<^sub>1 ls\<^sub>1 sh\<^sub>1 "Addr a"] by simp + also have "P \ \ -jvm\ (None,h\<^sub>2,(w#Addr a#vs,ls\<^sub>2,C,M,?pc\<^sub>2,ics)#frs,sh\<^sub>2)" + using IH\<^sub>2 Jcc_pieces_FAss2[OF pcs, of h\<^sub>1 "Addr a" ls\<^sub>1 sh\<^sub>1 w] by (simp add: add.assoc) + also have "P \ \ -jvm\ (None,h\<^sub>2',(Unit#vs,ls\<^sub>2,C,M,?pc\<^sub>2+2,ics)#frs,sh\<^sub>2)" + using FAss\<^sub>1 field by auto + finally show ?case using pcs by (auto simp:add.assoc) +next + case (FAssNull\<^sub>1 e\<^sub>1 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 h\<^sub>1 ls\<^sub>1 sh\<^sub>1 e\<^sub>2 w h\<^sub>2 ls\<^sub>2 sh\<^sub>2 F D) + obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>2 ls\<^sub>2 sh\<^sub>2 v xa (e\<^sub>1\F{D} := e\<^sub>2) + = (True, frs', (None,h\<^sub>2,(v#vs,ls\<^sub>2,C,M,pc+size(compE\<^sub>2 (e\<^sub>1\F{D} := e\<^sub>2)),ics)#frs,sh\<^sub>2), err)" + using FAssNull\<^sub>1.prems(1) by clarsimp + let ?pc\<^sub>1 = "pc + length(compE\<^sub>2 e\<^sub>1)" + let ?pc\<^sub>2 = "?pc\<^sub>1 + length(compE\<^sub>2 e\<^sub>2)" + let ?xa = "addr_of_sys_xcpt NullPointer" + have IH\<^sub>1: "PROP ?P e\<^sub>1 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 null h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics Null xa vs frs + (I - pcs (compxE\<^sub>2 e\<^sub>2 (pc + length (compE\<^sub>2 e\<^sub>1)) (Suc (length vs))))" by fact + have IH\<^sub>2: "PROP ?P e\<^sub>2 h\<^sub>1 ls\<^sub>1 sh\<^sub>1 (Val w) h\<^sub>2 ls\<^sub>2 sh\<^sub>2 E C M ?pc\<^sub>1 ics w xa (Null#vs) frs + (I - pcs(compxE\<^sub>2 e\<^sub>1 pc (size vs)))" by fact + have "P \ (None,h\<^sub>0,frs',sh\<^sub>0) -jvm\ (None,h\<^sub>1,(Null#vs,ls\<^sub>1,C,M,?pc\<^sub>1,ics)#frs,sh\<^sub>1)" + using IH\<^sub>1 Jcc_pieces_FAss1[OF pcs, of h\<^sub>1 ls\<^sub>1 sh\<^sub>1 Null] by simp + also have "P \ \ -jvm\ (None,h\<^sub>2,(w#Null#vs,ls\<^sub>2,C,M,?pc\<^sub>2,ics)#frs,sh\<^sub>2)" + using IH\<^sub>2 Jcc_pieces_FAss2[OF pcs, of h\<^sub>1 Null ls\<^sub>1 sh\<^sub>1 w] by (simp add: add.assoc) + also have "P \ \ -jvm\ handle P C M ?xa h\<^sub>2 (w#Null#vs) ls\<^sub>2 ?pc\<^sub>2 ics frs sh\<^sub>2" + using FAssNull\<^sub>1 by(fastforce simp:split_beta handle_def simp del: split_paired_Ex) + finally show ?case using pcs by (auto intro!: exI[where x = ?pc\<^sub>2] exI[where x="w#[Null]"]) +next + case (FAssThrow\<^sub>2\<^sub>1 e\<^sub>1 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 w h\<^sub>1 ls\<^sub>1 sh\<^sub>1 e\<^sub>2 e' h\<^sub>2 ls\<^sub>2 sh\<^sub>2 F D) + let ?frs' = "(vs, ls\<^sub>0, C, M, pc, ics) # frs" + obtain err where pcs: "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>2 ls\<^sub>2 sh\<^sub>2 v xa (e\<^sub>1\F{D} := e\<^sub>2) + = (True, ?frs', (None,h\<^sub>2,(v#vs,ls\<^sub>2,C,M,pc+size(compE\<^sub>2 (e\<^sub>1\F{D} := e\<^sub>2)),ics)#frs,sh\<^sub>2), err)" + using FAssThrow\<^sub>2\<^sub>1.prems(1) by clarsimp + let ?pc\<^sub>1 = "pc + length(compE\<^sub>2 e\<^sub>1)" + let ?\\<^sub>1 = "(None,h\<^sub>1,(w#vs,ls\<^sub>1,C,M,?pc\<^sub>1,ics)#frs,sh\<^sub>1)" + have IH\<^sub>1: "PROP ?P e\<^sub>1 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (Val w) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics w xa vs frs + (I - pcs (compxE\<^sub>2 e\<^sub>2 (pc + length (compE\<^sub>2 e\<^sub>1)) (Suc (length vs))))" by fact + have IH\<^sub>2: "PROP ?P e\<^sub>2 h\<^sub>1 ls\<^sub>1 sh\<^sub>1 (throw e') h\<^sub>2 ls\<^sub>2 sh\<^sub>2 E C M ?pc\<^sub>1 ics v xa (w#vs) frs + (I - pcs(compxE\<^sub>2 e\<^sub>1 pc (size vs)))" by fact + have 1: "P \ (None,h\<^sub>0,?frs',sh\<^sub>0) -jvm\ ?\\<^sub>1" + using IH\<^sub>1 Jcc_pieces_FAss1[OF pcs, of h\<^sub>1 ls\<^sub>1 sh\<^sub>1 w] by simp + show ?case (is "?N \ (?eq \ ?err)") + proof + show ?N by simp + next + { assume ?eq + moreover + have "PROP ?P e\<^sub>2 h\<^sub>1 ls\<^sub>1 sh\<^sub>1 (throw e') h\<^sub>2 ls\<^sub>2 sh\<^sub>2 E C M ?pc\<^sub>1 ics v xa (w#vs) frs + (I - pcs (compxE\<^sub>2 e\<^sub>1 pc (length vs)))" by fact + ultimately obtain pc\<^sub>2 vs' where + pc\<^sub>2: "?pc\<^sub>1 \ pc\<^sub>2 \ pc\<^sub>2 < ?pc\<^sub>1 + size(compE\<^sub>2 e\<^sub>2) \ + \ caught P pc\<^sub>2 h\<^sub>2 xa (compxE\<^sub>2 e\<^sub>2 ?pc\<^sub>1 (size vs + 1))" and + 2: "P \ ?\\<^sub>1 -jvm\ handle P C M xa h\<^sub>2 (vs'@w#vs) ls\<^sub>2 pc\<^sub>2 ics frs sh\<^sub>2" + using FAssThrow\<^sub>2\<^sub>1.prems Jcc_pieces_FAss2[OF pcs, of h\<^sub>1 w ls\<^sub>1 sh\<^sub>1] by auto + have ?err using Jcc_pieces_FAss2[OF pcs, of h\<^sub>1 w ls\<^sub>1 sh\<^sub>1] pc\<^sub>2 jvm_trans[OF 1 2] + by(auto intro!: exI[where x=pc\<^sub>2] exI[where x="vs'@[w]"]) + } + thus "?eq \ ?err" by simp + qed +next + case (FAssThrow\<^sub>1\<^sub>1 e\<^sub>1 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 e' h\<^sub>1 ls\<^sub>1 sh\<^sub>1 F D e\<^sub>2) + obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v xa (e\<^sub>1\F{D} := e\<^sub>2) + = (True, frs', (None,h\<^sub>1,(v#vs,ls\<^sub>1,C,M,pc+size(compE\<^sub>2 (e\<^sub>1\F{D} := e\<^sub>2)),ics)#frs,sh\<^sub>1), err)" + using FAssThrow\<^sub>1\<^sub>1.prems(1) by clarsimp + have IH\<^sub>1: "PROP ?P e\<^sub>1 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (throw e') h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics v xa vs frs + (I - pcs (compxE\<^sub>2 e\<^sub>2 (pc + length (compE\<^sub>2 e\<^sub>1)) (Suc (length vs))))" by fact + show ?case using IH\<^sub>1 Jcc_pieces_FAss1[OF pcs, of h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v] FAssThrow\<^sub>1\<^sub>1.prems nsub_RI_Jcc_pieces + by auto +next + case (FAssNone\<^sub>1 e\<^sub>1 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 a h\<^sub>1 ls\<^sub>1 sh\<^sub>1 e\<^sub>2 w h\<^sub>2 ls\<^sub>2 sh\<^sub>2 C' fs F D) + obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>2 ls\<^sub>2 sh\<^sub>2 v xa (e\<^sub>1\F{D} := e\<^sub>2) + = (True, frs', (None,h\<^sub>2,(v#vs,ls\<^sub>2,C,M,pc+size(compE\<^sub>2 (e\<^sub>1\F{D} := e\<^sub>2)),ics)#frs,sh\<^sub>2), err)" + using FAssNone\<^sub>1.prems(1) by clarsimp + let ?pc\<^sub>1 = "pc + length(compE\<^sub>2 e\<^sub>1)" + let ?pc\<^sub>2 = "?pc\<^sub>1 + length(compE\<^sub>2 e\<^sub>2)" + let ?xa = "addr_of_sys_xcpt NoSuchFieldError" + have IH\<^sub>1: "PROP ?P e\<^sub>1 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (addr a) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics (Addr a) xa vs frs + (I - pcs (compxE\<^sub>2 e\<^sub>2 (pc + length (compE\<^sub>2 e\<^sub>1)) (Suc (length vs))))" by fact + have IH\<^sub>2: "PROP ?P e\<^sub>2 h\<^sub>1 ls\<^sub>1 sh\<^sub>1 (Val w) h\<^sub>2 ls\<^sub>2 sh\<^sub>2 E C M ?pc\<^sub>1 ics w xa (Addr a#vs) frs + (I - pcs(compxE\<^sub>2 e\<^sub>1 pc (size vs)))" by fact + have "P \ (None,h\<^sub>0,frs',sh\<^sub>0) -jvm\ (None,h\<^sub>1,(Addr a#vs,ls\<^sub>1,C,M,?pc\<^sub>1,ics)#frs,sh\<^sub>1)" + using IH\<^sub>1 Jcc_pieces_FAss1[OF pcs, of h\<^sub>1 ls\<^sub>1 sh\<^sub>1 "Addr a"] by simp + also have "P \ \ -jvm\ (None,h\<^sub>2,(w#Addr a#vs,ls\<^sub>2,C,M,?pc\<^sub>2,ics)#frs,sh\<^sub>2)" + using IH\<^sub>2 Jcc_pieces_FAss2[OF pcs, of h\<^sub>1 "Addr a" ls\<^sub>1 sh\<^sub>1 w] by (simp add: add.assoc) + also have "P \ \ -jvm\ handle P C M ?xa h\<^sub>2 (w#Addr a#vs) ls\<^sub>2 ?pc\<^sub>2 ics frs sh\<^sub>2" + using FAssNone\<^sub>1 by(fastforce simp:split_beta handle_def simp del: split_paired_Ex) + finally show ?case using pcs by (auto intro!: exI[where x = ?pc\<^sub>2] exI[where x="w#[Addr a]"]) +next + case (FAssStatic\<^sub>1 e\<^sub>1 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 a h\<^sub>1 ls\<^sub>1 sh\<^sub>1 e\<^sub>2 w h\<^sub>2 ls\<^sub>2 sh\<^sub>2 C' fs F T D) + obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>2 ls\<^sub>2 sh\<^sub>2 v xa (e\<^sub>1\F{D} := e\<^sub>2) + = (True, frs', (None,h\<^sub>2,(v#vs,ls\<^sub>2,C,M,pc+size(compE\<^sub>2 (e\<^sub>1\F{D} := e\<^sub>2)),ics)#frs,sh\<^sub>2), err)" + using FAssStatic\<^sub>1.prems(1) by clarsimp + have "P\<^sub>1 \ D sees F,Static:T in D" by(rule has_field_sees[OF has_field_idemp[OF FAssStatic\<^sub>1.hyps(6)]]) + then have field: "field P D F = (D,Static,T)" by simp + let ?pc\<^sub>1 = "pc + length(compE\<^sub>2 e\<^sub>1)" + let ?pc\<^sub>2 = "?pc\<^sub>1 + length(compE\<^sub>2 e\<^sub>2)" + let ?xa = "addr_of_sys_xcpt IncompatibleClassChangeError" + have IH\<^sub>1: "PROP ?P e\<^sub>1 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (addr a) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics (Addr a) xa vs frs + (I - pcs (compxE\<^sub>2 e\<^sub>2 (pc + length (compE\<^sub>2 e\<^sub>1)) (Suc (length vs))))" by fact + have IH\<^sub>2: "PROP ?P e\<^sub>2 h\<^sub>1 ls\<^sub>1 sh\<^sub>1 (Val w) h\<^sub>2 ls\<^sub>2 sh\<^sub>2 E C M ?pc\<^sub>1 ics w xa (Addr a#vs) frs + (I - pcs(compxE\<^sub>2 e\<^sub>1 pc (size vs)))" by fact + have "P \ (None,h\<^sub>0,frs',sh\<^sub>0) -jvm\ (None,h\<^sub>1,(Addr a#vs,ls\<^sub>1,C,M,?pc\<^sub>1,ics)#frs,sh\<^sub>1)" + using IH\<^sub>1 Jcc_pieces_FAss1[OF pcs, of h\<^sub>1 ls\<^sub>1 sh\<^sub>1 "Addr a"] by simp + also have "P \ \ -jvm\ (None,h\<^sub>2,(w#Addr a#vs,ls\<^sub>2,C,M,?pc\<^sub>2,ics)#frs,sh\<^sub>2)" + using IH\<^sub>2 Jcc_pieces_FAss2[OF pcs, of h\<^sub>1 "Addr a" ls\<^sub>1 sh\<^sub>1 w] by (simp add: add.assoc) + also have "P \ \ -jvm\ handle P C M ?xa h\<^sub>2 (w#Addr a#vs) ls\<^sub>2 ?pc\<^sub>2 ics frs sh\<^sub>2" + using FAssStatic\<^sub>1 field by(fastforce simp:split_beta handle_def simp del: split_paired_Ex) + finally show ?case using pcs by (auto intro!: exI[where x = ?pc\<^sub>2] exI[where x="w#[Addr a]"]) +next + case (SFAss\<^sub>1 e\<^sub>2 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 w h\<^sub>1 ls\<^sub>1 sh\<^sub>1 C' F T D sfs sfs' sh\<^sub>1') + then obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v xa (C'\\<^sub>sF{D} := e\<^sub>2) + = (True, frs', (None,h\<^sub>1,(v#vs,ls\<^sub>1,C,M,pc+size(compE\<^sub>2 (C'\\<^sub>sF{D} := e\<^sub>2)),ics)#frs,sh\<^sub>1), err)" + using SFAss\<^sub>1.prems(1) by clarsimp + have "P\<^sub>1 \ D sees F,Static:T in D" by(rule has_field_sees[OF has_field_idemp[OF SFAss\<^sub>1.hyps(3)]]) + then have field: "field P D F = (D,Static,T)" by simp + have IH: "PROP ?P e\<^sub>2 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (Val w) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics w xa vs frs I" by fact + let ?pc = "pc + length(compE\<^sub>2 e\<^sub>2)" + have "P \ (None,h\<^sub>0,frs',sh\<^sub>0) -jvm\ (None,h\<^sub>1,(w#vs,ls\<^sub>1,C,M,?pc,ics)#frs,sh\<^sub>1)" + using IH Jcc_pieces_SFAss[OF pcs, where v'=w] pcs by simp + also have "P \ \ -jvm\ (None,h\<^sub>1,(vs,ls\<^sub>1,C,M,?pc+1,ics)#frs,sh\<^sub>1')" + using SFAss\<^sub>1.hyps(3-6) SFAss\<^sub>1.prems(1) field by auto + also have "P \ ... -jvm\ (None,h\<^sub>1,(Unit#vs,ls\<^sub>1,C,M,?pc+2,ics)#frs,sh\<^sub>1')" + using SFAss\<^sub>1 by auto + finally show ?case using pcs by auto +next + case (SFAssInit\<^sub>1 e\<^sub>2 h ls sh w h\<^sub>1 ls\<^sub>1 sh\<^sub>1 C' F t D v' h' ls' sh' sfs i sfs' sh'') + let ?pc = "pc + length(compE\<^sub>2 e\<^sub>2)" + obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h vs ls pc ics frs sh I h' ls' sh'' v xa (C'\\<^sub>sF{D}:=e\<^sub>2) + = (True, frs', (None,h',(v#vs,ls',C,M,pc+size(compE\<^sub>2 (C'\\<^sub>sF{D}:=e\<^sub>2)),ics)#frs,sh''), err)" + using SFAssInit\<^sub>1.prems(1) by clarsimp + have "Ex (WTrt2\<^sub>1 P\<^sub>1 E h\<^sub>1 sh\<^sub>1 (INIT D ([D],False) \ unit))" + using has_field_is_class'[OF SFAssInit\<^sub>1.hyps(3)] by auto + then obtain err' where pcs': + "Jcc_pieces P\<^sub>1 E C M h\<^sub>1 (w#vs) ls\<^sub>1 ?pc ics frs sh\<^sub>1 I h' ls' sh' v' xa (INIT D ([D],False) \ unit) + = (True, (w#vs,ls\<^sub>1,C,M,?pc,Calling D []) # frs, + (None,h',(w#vs,ls\<^sub>1,C,M,?pc,Called [])#frs,sh'), err')" + using SFAssInit\<^sub>1.prems(1) by simp + have ls: "ls\<^sub>1 = ls'" by(rule init\<^sub>1_same_loc[OF SFAssInit\<^sub>1.hyps(5)]) + have has: "P\<^sub>1 \ D has F,Static:t in D" by(rule has_field_idemp[OF SFAssInit\<^sub>1.hyps(3)]) + have "P\<^sub>1 \ D sees F,Static:t in D" by(rule has_field_sees[OF has]) + then have field: "field P D F = (D,Static,t)" by simp + have IH: "PROP ?P e\<^sub>2 h ls sh (Val w) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics w xa vs frs I" by fact + have IHI: "PROP ?P (INIT D ([D],False) \ unit) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 (Val v') + h' ls' sh' E C M ?pc ics v' xa (w#vs) frs I" by fact + have "P \ (None,h,frs',sh) -jvm\ (None,h\<^sub>1,(w#vs,ls\<^sub>1,C,M,?pc,ics)#frs,sh\<^sub>1)" + using IH Jcc_pieces_SFAss[OF pcs, where v'=w] by simp + also have "P \ \ -jvm\ (None,h\<^sub>1,(w#vs,ls\<^sub>1,C,M,?pc,Calling D [])#frs,sh\<^sub>1)" + proof(cases "sh\<^sub>1 D") + case None then show ?thesis using None SFAssInit\<^sub>1.hyps(1,3-5,7-9) SFAssInit\<^sub>1.prems field + by(cases ics, auto) + next + case (Some a) + then obtain sfs i where "a = (sfs,i)" by(cases a) + then show ?thesis using SFAssInit\<^sub>1.hyps(1,3-5,7-9) SFAssInit\<^sub>1.prems field Some + by(cases ics; case_tac i) auto + qed + also have "P \ ... -jvm\ (None, h', (w#vs, ls\<^sub>1, C, M, ?pc, Called []) # frs, sh')" + using IHI pcs' by clarsimp + also have "P \ ... -jvm\ (None, h', (vs, ls\<^sub>1, C, M, ?pc + 1, ics) # frs, sh'')" + using SFAssInit\<^sub>1.hyps(1,3-5,7-9) SFAssInit\<^sub>1.prems has field by(cases ics) auto + also have "P \ ... -jvm\ (None, h', (Unit#vs, ls\<^sub>1, C, M, ?pc + 2, ics) # frs, sh'')" + using SFAssInit\<^sub>1.hyps(1,3-5,7-9) SFAssInit\<^sub>1.prems has field by(cases ics) auto + finally show ?case using pcs ls by simp blast +next + case (SFAssInitThrow\<^sub>1 e\<^sub>2 h ls sh w h\<^sub>1 ls\<^sub>1 sh\<^sub>1 C' F t D a h' ls' sh') + let ?pc = "pc + length(compE\<^sub>2 e\<^sub>2)" + obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h vs ls pc ics frs sh I h' ls' sh' v xa (C'\\<^sub>sF{D}:=e\<^sub>2) + = (True, frs', (None,h',(v#vs,ls',C,M,pc+size(compE\<^sub>2 (C'\\<^sub>sF{D}:=e\<^sub>2)),ics)#frs,sh'), err)" + using SFAssInitThrow\<^sub>1.prems(1) by clarsimp + obtain a' where throw: "throw a = Throw a'" using eval\<^sub>1_final[OF SFAssInitThrow\<^sub>1.hyps(5)] by clarsimp + have "Ex (WTrt2\<^sub>1 P\<^sub>1 E h\<^sub>1 sh\<^sub>1 (INIT D ([D],False) \ unit))" + using has_field_is_class'[OF SFAssInitThrow\<^sub>1.hyps(3)] by auto + then obtain vs' where pcs': + "Jcc_pieces P\<^sub>1 E C M h\<^sub>1 (w#vs) ls\<^sub>1 ?pc ics frs sh\<^sub>1 I h' ls' sh' v a' (INIT D ([D],False) \ unit) + = (True, (w#vs,ls\<^sub>1,C,M,?pc,Calling D []) # frs, (None,h',(w#vs,ls\<^sub>1,C,M,?pc,Called [])#frs,sh'), + P \ (None,h\<^sub>1,(w#vs,ls\<^sub>1,C,M,?pc,Calling D []) # frs,sh\<^sub>1) + -jvm\ handle P C M a' h' (vs'@w#vs) ls\<^sub>1 ?pc ics frs sh')" + using SFAssInitThrow\<^sub>1.prems(1) by simp blast + have ls: "ls\<^sub>1 = ls'" by(rule init\<^sub>1_same_loc[OF SFAssInitThrow\<^sub>1.hyps(5)]) + have has: "P\<^sub>1 \ D has F,Static:t in D" by(rule has_field_idemp[OF SFAssInitThrow\<^sub>1.hyps(3)]) + have "P\<^sub>1 \ D sees F,Static:t in D" by(rule has_field_sees[OF has]) + then have field: "field P D F = (D,Static,t)" by simp + have IH: "PROP ?P e\<^sub>2 h ls sh (Val w) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics w xa vs frs I" by fact + have IHI: "PROP ?P (INIT D ([D],False) \ unit) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 (throw a) + h' ls' sh' E C M ?pc ics v a' (w#vs) frs I" by fact + have "P \ (None,h,(vs, ls, C, M, pc, ics) # frs,sh) -jvm\ (None,h\<^sub>1,(w#vs,ls\<^sub>1,C,M,?pc,ics)#frs,sh\<^sub>1)" + using IH Jcc_pieces_SFAss[OF pcs, where v'=w] pcs by simp blast + also have "P \ \ -jvm\ (None,h\<^sub>1,(w#vs,ls\<^sub>1,C,M,?pc,Calling D [])#frs,sh\<^sub>1)" + proof(cases "sh\<^sub>1 D") + case None then show ?thesis using SFAssInitThrow\<^sub>1.hyps(1,3,4,5) SFAssInitThrow\<^sub>1.prems field + by(cases ics) auto + next + case (Some a) + then obtain sfs i where "a = (sfs,i)" by(cases a) + then show ?thesis using SFAssInitThrow\<^sub>1.hyps(1,3,4,5) SFAssInitThrow\<^sub>1.prems field Some + by(cases ics; case_tac i) auto + qed + also have "P \ ... -jvm\ handle P C M a' h' (vs'@w#vs) ls\<^sub>1 ?pc ics frs sh'" + using IHI pcs' throw by auto + finally show ?case using throw ls by(auto intro!: exI[where x = ?pc] exI[where x="vs'@[w]"]) +next + case (SFAssThrow\<^sub>1 e\<^sub>2 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 e' h\<^sub>1 ls\<^sub>1 sh\<^sub>1 C' F D) + then obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v xa (C'\\<^sub>sF{D} := e\<^sub>2) + = (True, frs', (None,h\<^sub>1,(v#vs,ls\<^sub>1,C,M,pc+size(compE\<^sub>2 (C'\\<^sub>sF{D} := e\<^sub>2)),ics)#frs,sh\<^sub>1), err)" + using SFAssThrow\<^sub>1.prems(1) by clarsimp + have IH: "PROP ?P e\<^sub>2 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (throw e') h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics v xa vs frs I" by fact + show ?case using IH Jcc_pieces_SFAss[OF pcs, where v'=v] SFAssThrow\<^sub>1.prems nsub_RI_Jcc_pieces + less_Suc_eq by auto +next + case (SFAssNone\<^sub>1 e\<^sub>2 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 w h\<^sub>1 ls\<^sub>1 sh\<^sub>1 C' F D) + then obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v xa (C'\\<^sub>sF{D} := e\<^sub>2) + = (True, frs', (None,h\<^sub>1,(v#vs,ls\<^sub>1,C,M,pc+size(compE\<^sub>2 (C'\\<^sub>sF{D} := e\<^sub>2)),ics)#frs,sh\<^sub>1), err)" + using SFAssNone\<^sub>1.prems(1) by clarsimp + have IH: "PROP ?P e\<^sub>2 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (Val w) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics w xa vs frs I" by fact + let ?pc = "pc + length(compE\<^sub>2 e\<^sub>2)" + let ?xa = "addr_of_sys_xcpt NoSuchFieldError" + have "P \ (None,h\<^sub>0,frs',sh\<^sub>0) -jvm\ (None,h\<^sub>1,(w#vs,ls\<^sub>1,C,M,?pc,ics)#frs,sh\<^sub>1)" + using IH Jcc_pieces_SFAss[OF pcs, where v'=w] pcs by simp + also have "P \ \ -jvm\ handle P C M ?xa h\<^sub>1 (w#vs) ls\<^sub>1 ?pc ics frs sh\<^sub>1" + using SFAssNone\<^sub>1 by(cases ics; clarsimp simp add: handle_def) + finally show ?case using pcs by (auto intro!: exI[where x = ?pc] exI[where x="[w]"]) +next + case (SFAssNonStatic\<^sub>1 e\<^sub>2 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 w h\<^sub>1 ls\<^sub>1 sh\<^sub>1 C' F T D) + then obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>1 ls\<^sub>1 sh\<^sub>1 v xa (C'\\<^sub>sF{D} := e\<^sub>2) + = (True, frs', (None,h\<^sub>1,(v#vs,ls\<^sub>1,C,M,pc+size(compE\<^sub>2 (C'\\<^sub>sF{D} := e\<^sub>2)),ics)#frs,sh\<^sub>1), err)" + using SFAssNonStatic\<^sub>1.prems(1) by clarsimp + have IH: "PROP ?P e\<^sub>2 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (Val w) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics w xa vs frs I" by fact + let ?pc = "pc + length(compE\<^sub>2 e\<^sub>2)" + let ?xa = "addr_of_sys_xcpt IncompatibleClassChangeError" + have "P\<^sub>1 \ D sees F,NonStatic:T in D" + by(rule has_field_sees[OF has_field_idemp[OF SFAssNonStatic\<^sub>1.hyps(3)]]) + then have field: "field P D F = (D,NonStatic,T)" by simp + have "P \ (None,h\<^sub>0,frs',sh\<^sub>0) -jvm\ (None,h\<^sub>1,(w#vs,ls\<^sub>1,C,M,?pc,ics)#frs,sh\<^sub>1)" + using IH Jcc_pieces_SFAss[OF pcs, where v'=w] pcs by simp + also have "P \ \ -jvm\ handle P C M ?xa h\<^sub>1 (w#vs) ls\<^sub>1 ?pc ics frs sh\<^sub>1" + using SFAssNonStatic\<^sub>1 + proof(cases ics) + case No_ics + then show ?thesis using SFAssNonStatic\<^sub>1 field + by (auto simp:split_beta handle_def simp del: split_paired_Ex) + qed(simp_all) + finally show ?case using pcs by (auto intro!: exI[where x = ?pc] exI[where x="[w]"]) +next + case (Call\<^sub>1 e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 a h\<^sub>1 ls\<^sub>1 sh\<^sub>1 es pvs h\<^sub>2 ls\<^sub>2 sh\<^sub>2 Ca fs M' Ts T body D ls\<^sub>2' f h\<^sub>3 ls\<^sub>3 sh\<^sub>3) + let ?frs\<^sub>0 = "(vs, ls\<^sub>0, C,M,pc,ics)#frs" + let ?\\<^sub>0 = "(None,h\<^sub>0,?frs\<^sub>0,sh\<^sub>0)" + let ?pc\<^sub>1 = "pc + length(compE\<^sub>2 e)" + let ?\\<^sub>1 = "(None,h\<^sub>1,(Addr a#vs, ls\<^sub>1, C,M,?pc\<^sub>1,ics)#frs,sh\<^sub>1)" + let ?pc\<^sub>2 = "?pc\<^sub>1 + length(compEs\<^sub>2 es)" + let ?frs\<^sub>2 = "(rev pvs @ Addr a # vs, ls\<^sub>2, C,M,?pc\<^sub>2,ics)#frs" + let ?\\<^sub>2 = "(None,h\<^sub>2,?frs\<^sub>2,sh\<^sub>2)" + let ?frs\<^sub>2' = "([], ls\<^sub>2', D,M',0,No_ics) # ?frs\<^sub>2" + let ?\\<^sub>2' = "(None, h\<^sub>2, ?frs\<^sub>2', sh\<^sub>2)" + have nclinit: "M' \ clinit" using wf_sees_clinit1[OF wf] visible_method_exists[OF Call\<^sub>1.hyps(6)] + sees_method_idemp[OF Call\<^sub>1.hyps(6)] by fastforce + have "P\<^sub>1 \\<^sub>1 \es,(h\<^sub>1, ls\<^sub>1, sh\<^sub>1)\ [\] \map Val pvs,(h\<^sub>2, ls\<^sub>2, sh\<^sub>2)\" by fact + hence [simp]: "length es = length pvs" by(auto dest:evals\<^sub>1_preserves_elen) + have invoke: "P,C,M,?pc\<^sub>2 \ Invoke M' (length Ts)" + using Call\<^sub>1.hyps(7) Call\<^sub>1.prems(1) by clarsimp + have nsub: "\ sub_RI body" by(rule sees_wf\<^sub>1_nsub_RI[OF wf Call\<^sub>1.hyps(6)]) + obtain err where pcs: + "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>3 ls\<^sub>2 sh\<^sub>3 v xa (e\M'(es)) = + (True, ?frs\<^sub>0, (None, h\<^sub>3, (v#vs, ls\<^sub>2, C,M,?pc\<^sub>2+1,ics)#frs,sh\<^sub>3), err)" + using Call\<^sub>1.prems(1) by clarsimp + have IH: "PROP ?P e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (addr a) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics (Addr a) xa vs frs + (I - pcs (compxEs\<^sub>2 es (pc + length (compE\<^sub>2 e)) (Suc (length vs))))" by fact + have IH_es: "PROP ?Ps es h\<^sub>1 ls\<^sub>1 sh\<^sub>1 (map Val pvs) h\<^sub>2 ls\<^sub>2 sh\<^sub>2 C M ?pc\<^sub>1 ics pvs xa + (map Val pvs) (Addr a#vs) frs (I - pcs(compxE\<^sub>2 e pc (size vs)))" by fact + have "P \ ?\\<^sub>0 -jvm\ ?\\<^sub>1" using Jcc_pieces_Call1[OF pcs] IH by clarsimp + also have "P \ \ -jvm\ ?\\<^sub>2" using IH_es Call\<^sub>1.prems by fastforce + also have "P \ \ -jvm\ ?\\<^sub>2'" + using jvm_Invoke[OF assms(1) invoke _ Call\<^sub>1.hyps(6-8)] Call\<^sub>1.hyps(5) Call\<^sub>1.prems(1) by simp + finally have 1: "P \ ?\\<^sub>0 -jvm\ ?\\<^sub>2'". + have "P\<^sub>1 \ Ca sees M',NonStatic: Ts\T = body in D" by fact + then have M'_in_D: "P\<^sub>1 \ D sees M',NonStatic: Ts\T = body in D" + by(rule sees_method_idemp) + have M'_code: "compP\<^sub>2 P\<^sub>1,D,M',0 \ compE\<^sub>2 body @ [Return]" using beforeM M'_in_D by simp + have M'_xtab: "compP\<^sub>2 P\<^sub>1,D,M' \ compxE\<^sub>2 body 0 0/{..2 body)},0" + using M'_in_D by(rule beforexM) + have IH_body: "PROP ?P body h\<^sub>2 ls\<^sub>2' sh\<^sub>2 f h\<^sub>3 ls\<^sub>3 sh\<^sub>3 (Class D # Ts) D M' 0 No_ics v xa [] ?frs\<^sub>2 + ({..2 body)})" by fact + have cond: "Jcc_cond P\<^sub>1 (Class D # Ts) D M' [] 0 No_ics {..2 body)} h\<^sub>2 sh\<^sub>2 body" + using nsub_RI_Jcc_pieces[OF assms(1) nsub] M'_code M'_xtab by clarsimp + show ?case (is "?Norm \ ?Err") + proof + show ?Norm (is "?val \ ?trans") + proof + assume val: ?val + note 1 + also have "P \ ?\\<^sub>2' -jvm\ (None,h\<^sub>3,([v],ls\<^sub>3,D,M',size(compE\<^sub>2 body),No_ics)#?frs\<^sub>2,sh\<^sub>3)" + using val IH_body Call\<^sub>1.prems M'_code cond nsub_RI_Jcc_pieces nsub by auto + also have "P \ \ -jvm\ (None, h\<^sub>3, (v#vs, ls\<^sub>2, C,M,?pc\<^sub>2+1,ics)#frs,sh\<^sub>3)" + using Call\<^sub>1.hyps(7) M'_code M'_in_D nclinit by(cases T, auto) + finally show ?trans by(simp add:add.assoc) + qed + next + show ?Err (is "?throw \ ?err") + proof + assume throw: ?throw + with IH_body obtain pc\<^sub>2 vs' where + pc\<^sub>2: "0 \ pc\<^sub>2 \ pc\<^sub>2 < size(compE\<^sub>2 body) \ + \ caught P pc\<^sub>2 h\<^sub>3 xa (compxE\<^sub>2 body 0 0)" and + 2: "P \ ?\\<^sub>2' -jvm\ handle P D M' xa h\<^sub>3 vs' ls\<^sub>3 pc\<^sub>2 No_ics ?frs\<^sub>2 sh\<^sub>3" + using Call\<^sub>1.prems M'_code M'_xtab cond nsub_RI_Jcc_pieces nsub + by (auto simp del:split_paired_Ex) + have "handle P D M' xa h\<^sub>3 vs' ls\<^sub>3 pc\<^sub>2 No_ics ?frs\<^sub>2 sh\<^sub>3 = + handle P C M xa h\<^sub>3 (rev pvs @ Addr a # vs) ls\<^sub>2 ?pc\<^sub>2 ics frs sh\<^sub>3" + using pc\<^sub>2 M'_in_D nclinit by(auto simp add:handle_def) + then show "?err" using pc\<^sub>2 jvm_trans[OF 1 2] + by(auto intro!:exI[where x="?pc\<^sub>2"] exI[where x="rev pvs@[Addr a]"]) + qed + qed +next + case (CallParamsThrow\<^sub>1 e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 w h\<^sub>1 ls\<^sub>1 sh\<^sub>1 es es' h\<^sub>2 ls\<^sub>2 sh\<^sub>2 pvs ex es'' M') + let ?frs\<^sub>0 = "(vs, ls\<^sub>0, C,M,pc,ics)#frs" + let ?\\<^sub>0 = "(None,h\<^sub>0,(vs, ls\<^sub>0, C,M,pc,ics)#frs,sh\<^sub>0)" + let ?pc\<^sub>1 = "pc + length(compE\<^sub>2 e)" + let ?\\<^sub>1 = "(None,h\<^sub>1,(w # vs, ls\<^sub>1, C,M,?pc\<^sub>1,ics)#frs,sh\<^sub>1)" + let ?pc\<^sub>2 = "?pc\<^sub>1 + length(compEs\<^sub>2 es)" + obtain err where pcs: + "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>2 ls\<^sub>2 sh\<^sub>2 v xa (e\M'(es)) = + (True, ?frs\<^sub>0, (None, h\<^sub>2, (v#vs, ls\<^sub>2, C,M,?pc\<^sub>2+1,ics)#frs,sh\<^sub>2), err)" + using CallParamsThrow\<^sub>1.prems(1) by clarsimp + have IH: "PROP ?P e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (Val w) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics w xa vs frs + (I - pcs (compxEs\<^sub>2 es (pc + length (compE\<^sub>2 e)) (Suc (length vs))))" by fact + have 1: "P \ ?\\<^sub>0 -jvm\ ?\\<^sub>1" using Jcc_pieces_Call1[OF pcs] IH by clarsimp + have Isubs: "{?pc\<^sub>1..2} \ I - pcs (compxE\<^sub>2 e pc (length vs))" + using CallParamsThrow\<^sub>1.prems by clarsimp + show ?case (is "?N \ (?eq \ ?err)") + proof + show ?N by simp + next + { assume ?eq + moreover + have "PROP ?Ps es h\<^sub>1 ls\<^sub>1 sh\<^sub>1 es' h\<^sub>2 ls\<^sub>2 sh\<^sub>2 C M ?pc\<^sub>1 ics pvs xa es'' (w#vs) frs + (I - pcs (compxE\<^sub>2 e pc (length vs)))" by fact + ultimately obtain vs' where "\pc\<^sub>2. + (?pc\<^sub>1 \ pc\<^sub>2 \ pc\<^sub>2 < ?pc\<^sub>1 + size(compEs\<^sub>2 es) \ + \ caught P pc\<^sub>2 h\<^sub>2 xa (compxEs\<^sub>2 es ?pc\<^sub>1 (size vs + 1))) \ + P \ ?\\<^sub>1 -jvm\ handle P C M xa h\<^sub>2 (vs'@w#vs) ls\<^sub>2 pc\<^sub>2 ics frs sh\<^sub>2" + (is "\pc\<^sub>2. ?PC pc\<^sub>2 \ ?Exec pc\<^sub>2") + using CallParamsThrow\<^sub>1 Isubs by auto + then obtain pc\<^sub>2 where pc\<^sub>2: "?PC pc\<^sub>2" and 2: "?Exec pc\<^sub>2" by iprover + then have "?err" using pc\<^sub>2 jvm_trans[OF 1 2] + by(auto intro!: exI[where x="pc\<^sub>2"] exI[where x="vs'@[w]"]) + } + thus "?eq \ ?err" by simp + qed +next + case (CallNull\<^sub>1 e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 h\<^sub>1 ls\<^sub>1 sh\<^sub>1 es pvs h\<^sub>2 ls\<^sub>2 sh\<^sub>2 M') + have "P\<^sub>1 \\<^sub>1 \es,(h\<^sub>1, ls\<^sub>1, sh\<^sub>1)\ [\] \map Val pvs,(h\<^sub>2, ls\<^sub>2, sh\<^sub>2)\" by fact + hence [simp]: "length es = length pvs" by(auto dest:evals\<^sub>1_preserves_elen) + let ?frs\<^sub>0 = "(vs, ls\<^sub>0, C,M,pc,ics)#frs" + let ?pc\<^sub>1 = "pc + length(compE\<^sub>2 e)" + let ?pc\<^sub>2 = "?pc\<^sub>1 + length(compEs\<^sub>2 es)" + let ?xa = "addr_of_sys_xcpt NullPointer" + obtain err where pcs: + "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>2 ls\<^sub>2 sh\<^sub>2 v xa (e\M'(es)) = + (True, ?frs\<^sub>0, (None, h\<^sub>2, (v#vs, ls\<^sub>2, C,M,?pc\<^sub>2+1,ics)#frs,sh\<^sub>2), err)" + using CallNull\<^sub>1.prems(1) by clarsimp + have IH: "PROP ?P e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 null h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics Null xa vs frs + (I - pcs (compxEs\<^sub>2 es (pc + length (compE\<^sub>2 e)) (Suc (length vs))))" by fact + have IH_es: "PROP ?Ps es h\<^sub>1 ls\<^sub>1 sh\<^sub>1 (map Val pvs) h\<^sub>2 ls\<^sub>2 sh\<^sub>2 C M ?pc\<^sub>1 ics pvs xa + (map Val pvs) (Null#vs) frs (I - pcs(compxE\<^sub>2 e pc (size vs)))" by fact + have Isubs: "{pc + length (compE\<^sub>2 e)..2 e) + length (compEs\<^sub>2 es)} + \ I - pcs (compxE\<^sub>2 e pc (length vs))" using CallNull\<^sub>1.prems by clarsimp + have "P \ (None,h\<^sub>0,(vs,ls\<^sub>0,C,M,pc,ics)#frs,sh\<^sub>0) -jvm\ + (None,h\<^sub>1,(Null#vs,ls\<^sub>1,C,M,?pc\<^sub>1,ics)#frs,sh\<^sub>1)" + using Jcc_pieces_Call1[OF pcs] IH by clarsimp + also have "P \ \ -jvm\ (None,h\<^sub>2,(rev pvs@Null#vs,ls\<^sub>2,C,M,?pc\<^sub>2,ics)#frs,sh\<^sub>2)" + using CallNull\<^sub>1 IH_es Isubs by auto + also have "P \ \ -jvm\ handle P C M ?xa h\<^sub>2 (rev pvs@Null#vs) ls\<^sub>2 ?pc\<^sub>2 ics frs sh\<^sub>2" + using CallNull\<^sub>1.prems + by(auto simp:split_beta handle_def nth_append simp del: split_paired_Ex) + finally show ?case by (auto intro!: exI[where x = ?pc\<^sub>2] exI[where x="rev pvs@[Null]"]) +next + case (CallObjThrow\<^sub>1 e h ls sh e' h' ls' sh' M' es) + obtain err where pcs: + "Jcc_pieces P\<^sub>1 E C M h vs ls pc ics frs sh I h' ls' sh' v xa (e\M'(es)) = + (True, (vs, ls, C,M,pc,ics)#frs, + (None, h', (v#vs, ls', C,M,pc+size(compE\<^sub>2 (e\M'(es))),ics)#frs,sh'), err)" + using CallObjThrow\<^sub>1.prems(1) by clarsimp + obtain a' where throw: "throw e' = Throw a'" + using eval\<^sub>1_final[OF CallObjThrow\<^sub>1.hyps(1)] by clarsimp + have IH: "PROP ?P e h ls sh (throw e') h' ls' sh' E C M pc ics v a' vs frs + (I - pcs (compxEs\<^sub>2 es (pc + length (compE\<^sub>2 e)) (Suc (length vs))))" by fact + show ?case using IH Jcc_pieces_Call1[OF pcs] throw CallObjThrow\<^sub>1.prems nsub_RI_Jcc_pieces + by auto +next + case (CallNone\<^sub>1 e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 a h\<^sub>1 ls\<^sub>1 sh\<^sub>1 es pvs h\<^sub>2 ls\<^sub>2 sh\<^sub>2 C' fs M') + let ?frs\<^sub>0 = "(vs, ls\<^sub>0, C,M,pc,ics)#frs" + let ?\\<^sub>0 = "(None,h\<^sub>0,?frs\<^sub>0,sh\<^sub>0)" + let ?pc\<^sub>1 = "pc + length(compE\<^sub>2 e)" + let ?\\<^sub>1 = "(None,h\<^sub>1,(Addr a#vs, ls\<^sub>1, C,M,?pc\<^sub>1,ics)#frs,sh\<^sub>1)" + let ?pc\<^sub>2 = "?pc\<^sub>1 + length(compEs\<^sub>2 es)" + let ?frs\<^sub>2 = "(rev pvs @ Addr a # vs, ls\<^sub>2, C,M,?pc\<^sub>2,ics)#frs" + let ?\\<^sub>2 = "(None,h\<^sub>2,?frs\<^sub>2,sh\<^sub>2)" + let ?xa = "addr_of_sys_xcpt NoSuchMethodError" + have "P\<^sub>1 \\<^sub>1 \es,(h\<^sub>1, ls\<^sub>1, sh\<^sub>1)\ [\] \map Val pvs,(h\<^sub>2, ls\<^sub>2, sh\<^sub>2)\" by fact + hence [simp]: "length es = length pvs" by(auto dest:evals\<^sub>1_preserves_elen) + have aux: "(rev pvs @ Addr a # vs) ! length pvs = Addr a" + by (metis length_rev nth_append_length) + have nmeth: "\(\b Ts T body D. P \ C' sees M', b : Ts\T = body in D)" + using sees_method_compPD CallNone\<^sub>1.hyps(6) by fastforce + obtain err where pcs: + "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>2 ls\<^sub>2 sh\<^sub>2 v xa (e\M'(es)) = + (True, ?frs\<^sub>0, (None, h\<^sub>2, (v#vs, ls\<^sub>2, C,M,?pc\<^sub>2+1,ics)#frs,sh\<^sub>2), err)" + using CallNone\<^sub>1.prems(1) by clarsimp + have IH: "PROP ?P e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (addr a) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics (Addr a) xa vs frs + (I - pcs (compxEs\<^sub>2 es (pc + length (compE\<^sub>2 e)) (Suc (length vs))))" by fact + have IH_es: "PROP ?Ps es h\<^sub>1 ls\<^sub>1 sh\<^sub>1 (map Val pvs) h\<^sub>2 ls\<^sub>2 sh\<^sub>2 C M ?pc\<^sub>1 ics pvs xa + (map Val pvs) (Addr a#vs) frs (I - pcs(compxE\<^sub>2 e pc (size vs)))" by fact + have "P \ ?\\<^sub>0 -jvm\ ?\\<^sub>1" using Jcc_pieces_Call1[OF pcs] IH by clarsimp + also have "P \ \ -jvm\ ?\\<^sub>2" using IH_es CallNone\<^sub>1.prems by fastforce + also have "P \ \ -jvm\ handle P C M ?xa h\<^sub>2 (rev pvs@Addr a#vs) ls\<^sub>2 ?pc\<^sub>2 ics frs sh\<^sub>2" + using CallNone\<^sub>1.hyps(5) CallNone\<^sub>1.prems aux nmeth + by(cases "method P C' M'", cases "find_handler P ?xa h\<^sub>2 frs sh\<^sub>2", auto simp: handle_def) + finally show ?case using pcs by (auto intro!: exI[where x = ?pc\<^sub>2] exI[where x="rev pvs@[Addr a]"]) +next + case (CallStatic\<^sub>1 e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 a h\<^sub>1 ls\<^sub>1 sh\<^sub>1 es pvs h\<^sub>2 ls\<^sub>2 sh\<^sub>2 C' fs M' Ts T body D) + let ?frs\<^sub>0 = "(vs, ls\<^sub>0, C,M,pc,ics)#frs" + let ?\\<^sub>0 = "(None,h\<^sub>0,?frs\<^sub>0,sh\<^sub>0)" + let ?pc\<^sub>1 = "pc + length(compE\<^sub>2 e)" + let ?\\<^sub>1 = "(None,h\<^sub>1,(Addr a#vs, ls\<^sub>1, C,M,?pc\<^sub>1,ics)#frs,sh\<^sub>1)" + let ?pc\<^sub>2 = "?pc\<^sub>1 + length(compEs\<^sub>2 es)" + let ?frs\<^sub>2 = "(rev pvs @ Addr a # vs, ls\<^sub>2, C,M,?pc\<^sub>2,ics)#frs" + let ?\\<^sub>2 = "(None,h\<^sub>2,?frs\<^sub>2,sh\<^sub>2)" + let ?xa = "addr_of_sys_xcpt IncompatibleClassChangeError" + have "P\<^sub>1 \\<^sub>1 \es,(h\<^sub>1, ls\<^sub>1, sh\<^sub>1)\ [\] \map Val pvs,(h\<^sub>2, ls\<^sub>2, sh\<^sub>2)\" by fact + hence [simp]: "length es = length pvs" by(auto dest:evals\<^sub>1_preserves_elen) + have aux: "(rev pvs @ Addr a # vs) ! length pvs = Addr a" + by (metis length_rev nth_append_length) + obtain body' where method: "P \ C' sees M', Static : Ts\T = body' in D" + by (metis CallStatic\<^sub>1.hyps(6) P_def compP\<^sub>2_def sees_method_compP) + obtain err where pcs: + "Jcc_pieces P\<^sub>1 E C M h\<^sub>0 vs ls\<^sub>0 pc ics frs sh\<^sub>0 I h\<^sub>2 ls\<^sub>2 sh\<^sub>2 v xa (e\M'(es)) = + (True, ?frs\<^sub>0, (None, h\<^sub>2, (v#vs, ls\<^sub>2, C,M,?pc\<^sub>2+1,ics)#frs,sh\<^sub>2), err)" + using CallStatic\<^sub>1.prems(1) by clarsimp + have IH: "PROP ?P e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (addr a) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics (Addr a) xa vs frs + (I - pcs (compxEs\<^sub>2 es (pc + length (compE\<^sub>2 e)) (Suc (length vs))))" by fact + have IH_es: "PROP ?Ps es h\<^sub>1 ls\<^sub>1 sh\<^sub>1 (map Val pvs) h\<^sub>2 ls\<^sub>2 sh\<^sub>2 C M ?pc\<^sub>1 ics pvs xa + (map Val pvs) (Addr a#vs) frs (I - pcs(compxE\<^sub>2 e pc (size vs)))" by fact + have "P \ ?\\<^sub>0 -jvm\ ?\\<^sub>1" using Jcc_pieces_Call1[OF pcs] IH by clarsimp + also have "P \ \ -jvm\ ?\\<^sub>2" using IH_es CallStatic\<^sub>1.prems by fastforce + also have "P \ \ -jvm\ handle P C M ?xa h\<^sub>2 (rev pvs@Addr a#vs) ls\<^sub>2 ?pc\<^sub>2 ics frs sh\<^sub>2" + using CallStatic\<^sub>1.hyps(5) CallStatic\<^sub>1.prems aux method + by(cases "method P C' M'", cases "find_handler P ?xa h\<^sub>2 frs sh\<^sub>2") + (auto simp: handle_def; meson frames_of.cases) + finally show ?case using pcs by (auto intro!: exI[where x = ?pc\<^sub>2] exI[where x="rev pvs@[Addr a]"]) +next + case (SCallParamsThrow\<^sub>1 es h\<^sub>1 ls\<^sub>1 sh\<^sub>1 es' h\<^sub>2 ls\<^sub>2 sh\<^sub>2 pvs ex es'' C' M') + show ?case + proof(cases "M' = clinit \ es = []") + case clinit: True then show ?thesis + using SCallParamsThrow\<^sub>1.hyps(1,3) evals\<^sub>1_cases(1) by fastforce + next + case nclinit: False + let ?\\<^sub>1 = "(None,h\<^sub>1,(vs, ls\<^sub>1, C,M,pc,ics)#frs,sh\<^sub>1)" + let ?pc\<^sub>2 = "pc + length(compEs\<^sub>2 es)" + have Isubs: "{pc..2 es)} \ I" using SCallParamsThrow\<^sub>1.prems nclinit by clarsimp + show ?thesis (is "?N \ (?eq \ ?err)") + proof + show ?N by simp + next + { assume ?eq + moreover + have "PROP ?Ps es h\<^sub>1 ls\<^sub>1 sh\<^sub>1 es' h\<^sub>2 ls\<^sub>2 sh\<^sub>2 C M pc ics pvs xa es'' vs frs I" by fact + ultimately have "\pc\<^sub>2. + (pc \ pc\<^sub>2 \ pc\<^sub>2 < pc + size(compEs\<^sub>2 es) \ + \ caught P pc\<^sub>2 h\<^sub>2 xa (compxEs\<^sub>2 es pc (size vs))) \ + (\vs'. P \ ?\\<^sub>1 -jvm\ handle P C M xa h\<^sub>2 (vs'@vs) ls\<^sub>2 pc\<^sub>2 ics frs sh\<^sub>2)" + (is "\pc\<^sub>2. ?PC pc\<^sub>2 \ ?Exec pc\<^sub>2") + using SCallParamsThrow\<^sub>1 Isubs nclinit by auto + then obtain pc\<^sub>2 where pc\<^sub>2: "?PC pc\<^sub>2" and 2: "?Exec pc\<^sub>2" by iprover + then have "?err" using pc\<^sub>2 2 by(auto intro: exI[where x="pc\<^sub>2"]) + } + thus "?eq \ ?err" by iprover + qed + qed +next + case (SCallNone\<^sub>1 es h\<^sub>1 ls\<^sub>1 sh\<^sub>1 pvs h\<^sub>2 ls\<^sub>2 sh\<^sub>2 C' M') + show ?case + proof(cases "M' = clinit \ es = []") + case clinit: True then show ?thesis using SCallNone\<^sub>1.hyps(3) SCallNone\<^sub>1.prems by auto + next + case nclinit: False + let ?\\<^sub>1 = "(None,h\<^sub>1,(vs, ls\<^sub>1, C,M,pc,ics)#frs,sh\<^sub>1)" + let ?pc\<^sub>2 = "pc + length(compEs\<^sub>2 es)" + let ?frs\<^sub>2 = "(rev pvs @ vs, ls\<^sub>2, C,M,?pc\<^sub>2,ics)#frs" + let ?\\<^sub>2 = "(None,h\<^sub>2,?frs\<^sub>2,sh\<^sub>2)" + let ?xa = "addr_of_sys_xcpt NoSuchMethodError" + have "P\<^sub>1 \\<^sub>1 \es,(h\<^sub>1, ls\<^sub>1, sh\<^sub>1)\ [\] \map Val pvs,(h\<^sub>2, ls\<^sub>2, sh\<^sub>2)\" by fact + hence [simp]: "length es = length pvs" by(auto dest:evals\<^sub>1_preserves_elen) + have nmeth: "\(\b Ts T body D. P \ C' sees M', b : Ts\T = body in D)" + using sees_method_compPD SCallNone\<^sub>1.hyps(3) by fastforce + have IH_es: "PROP ?Ps es h\<^sub>1 ls\<^sub>1 sh\<^sub>1 (map Val pvs) h\<^sub>2 ls\<^sub>2 sh\<^sub>2 C M pc ics pvs xa + (map Val pvs) vs frs I" by fact + have "P \ ?\\<^sub>1 -jvm\ ?\\<^sub>2" using IH_es SCallNone\<^sub>1.prems nclinit by auto fastforce+ + also have "P \ \ -jvm\ handle P C M ?xa h\<^sub>2 (rev pvs@vs) ls\<^sub>2 ?pc\<^sub>2 ics frs sh\<^sub>2" + using SCallNone\<^sub>1.prems nmeth nclinit + by(cases "method P C' M'", cases "find_handler P ?xa h\<^sub>2 frs sh\<^sub>2", auto simp: handle_def) + finally show ?thesis using nclinit by (auto intro: exI[where x = ?pc\<^sub>2]) + qed +next + case (SCallNonStatic\<^sub>1 es h\<^sub>1 ls\<^sub>1 sh\<^sub>1 pvs h\<^sub>2 ls\<^sub>2 sh\<^sub>2 C' M' Ts T body D) + show ?case + proof(cases "M' = clinit \ es = []") + case clinit: True then show ?thesis + using SCallNonStatic\<^sub>1.hyps(3) SCallNonStatic\<^sub>1.prems sees_method_fun by fastforce + next + case nclinit: False + let ?\\<^sub>1 = "(None,h\<^sub>1,(vs, ls\<^sub>1, C,M,pc,ics)#frs,sh\<^sub>1)" + let ?pc\<^sub>2 = "pc + length(compEs\<^sub>2 es)" + let ?frs\<^sub>2 = "(rev pvs @ vs, ls\<^sub>2, C,M,?pc\<^sub>2,ics)#frs" + let ?\\<^sub>2 = "(None,h\<^sub>2,?frs\<^sub>2,sh\<^sub>2)" + let ?xa = "addr_of_sys_xcpt IncompatibleClassChangeError" + have "P\<^sub>1 \\<^sub>1 \es,(h\<^sub>1, ls\<^sub>1, sh\<^sub>1)\ [\] \map Val pvs,(h\<^sub>2, ls\<^sub>2, sh\<^sub>2)\" by fact + hence [simp]: "length es = length pvs" by(auto dest:evals\<^sub>1_preserves_elen) + obtain body' where method: "P \ C' sees M', NonStatic : Ts\T = body' in D" + by (metis SCallNonStatic\<^sub>1.hyps(3) P_def compP\<^sub>2_def sees_method_compP) + have IH_es: "PROP ?Ps es h\<^sub>1 ls\<^sub>1 sh\<^sub>1 (map Val pvs) h\<^sub>2 ls\<^sub>2 sh\<^sub>2 C M pc ics pvs xa + (map Val pvs) vs frs I" by fact + have "P \ ?\\<^sub>1 -jvm\ ?\\<^sub>2" using IH_es SCallNonStatic\<^sub>1.prems nclinit by auto fastforce+ + also have "P \ \ -jvm\ handle P C M ?xa h\<^sub>2 (rev pvs@vs) ls\<^sub>2 ?pc\<^sub>2 ics frs sh\<^sub>2" + using SCallNonStatic\<^sub>1.prems method nclinit + by(cases "method P C' M'", cases "find_handler P ?xa h\<^sub>2 frs sh\<^sub>2") + (auto simp: handle_def; meson frames_of.cases) + finally show ?thesis using nclinit by (auto intro: exI[where x = ?pc\<^sub>2]) + qed +next + case (SCallInitThrow\<^sub>1 es h\<^sub>0 ls\<^sub>0 sh\<^sub>0 pvs h\<^sub>1 ls\<^sub>1 sh\<^sub>1 C' M' Ts T body D a h\<^sub>2 ls\<^sub>2 sh\<^sub>2) + show ?case + proof(cases "M' = clinit \ es = []") + case clinit: True then show ?thesis using SCallInitThrow\<^sub>1 by simp + next + case nclinit: False + let ?\\<^sub>0 = "(None,h\<^sub>0,(vs, ls\<^sub>0, C,M,pc,ics)#frs,sh\<^sub>0)" + let ?pc\<^sub>1 = "pc + length(compEs\<^sub>2 es)" + let ?frs\<^sub>1 = "(rev pvs @ vs, ls\<^sub>1, C,M,?pc\<^sub>1,ics)#frs" + let ?\\<^sub>1 = "(None,h\<^sub>1,?frs\<^sub>1,sh\<^sub>1)" + let ?frs\<^sub>1' = "(rev pvs@vs,ls\<^sub>1,C,M,?pc\<^sub>1,Calling D [])#frs" + let ?\\<^sub>1' = "(None,h\<^sub>1,?frs\<^sub>1',sh\<^sub>1)" + let ?frs\<^sub>2 = "(rev pvs@vs,ls\<^sub>1,C,M,?pc\<^sub>1,Called [])#frs" + let ?\\<^sub>2 = "(None,h\<^sub>2,?frs\<^sub>2,sh\<^sub>2)" + have ls: "ls\<^sub>1 = ls\<^sub>2" by(rule init\<^sub>1_same_loc[OF SCallInitThrow\<^sub>1.hyps(6)]) + have method: "\m'. P \ C' sees M',Static:Ts\T = m' in D" using SCallInitThrow\<^sub>1.hyps(3) + by (metis P_def compP\<^sub>2_def sees_method_compP) + obtain a' where throw: "throw a = Throw a'" using eval\<^sub>1_final[OF SCallInitThrow\<^sub>1.hyps(6)] by clarsimp + have "Ex (WTrt2\<^sub>1 P\<^sub>1 E h\<^sub>1 sh\<^sub>1 (INIT D ([D],False) \ unit))" + using sees_method_is_class'[OF SCallInitThrow\<^sub>1.hyps(3)] by auto + then obtain err' where pcs': + "Jcc_pieces P\<^sub>1 E C M h\<^sub>1 (rev pvs@vs) ls\<^sub>1 ?pc\<^sub>1 ics frs sh\<^sub>1 I h\<^sub>2 ls\<^sub>2 sh\<^sub>2 v xa (INIT D ([D],False) \ unit) + = (True, ?frs\<^sub>1', (None,h\<^sub>2,?frs\<^sub>2,sh\<^sub>2), err')" + using SCallInitThrow\<^sub>1.prems(1) nclinit by auto + have IHI: "PROP ?P (INIT D ([D],False) \ unit) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 (throw a) + h\<^sub>2 ls\<^sub>2 sh\<^sub>2 E C M ?pc\<^sub>1 ics v a' (rev pvs@vs) frs I" by fact + have IH_es: "PROP ?Ps es h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (map Val pvs) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 C M pc ics pvs xa + (map Val pvs) vs frs I" by fact + have "P \ ?\\<^sub>0 -jvm\ ?\\<^sub>1" using IH_es SCallInitThrow\<^sub>1.prems nclinit by auto fastforce+ + also have "P \ \ -jvm\ ?\\<^sub>1'" + proof(cases "sh\<^sub>1 D") + case None then show ?thesis using SCallInitThrow\<^sub>1.hyps(1,3-6) SCallInitThrow\<^sub>1.prems method + by(cases ics) auto + next + case (Some a) + then obtain sfs i where "a = (sfs,i)" by(cases a) + then show ?thesis using SCallInitThrow\<^sub>1.hyps(1,3-6) SCallInitThrow\<^sub>1.prems method Some + by(cases ics; case_tac i, auto) + qed + also obtain vs' where "P \ \ -jvm\ handle P C M a' h\<^sub>2 (vs'@rev pvs@vs) ls\<^sub>1 ?pc\<^sub>1 ics frs sh\<^sub>2" + using IHI pcs' throw by auto + finally show ?thesis using nclinit throw ls + by(auto intro!: exI[where x="?pc\<^sub>1"] exI[where x="vs'@rev pvs"]) + qed +next + case (SCallInit\<^sub>1 es h\<^sub>0 ls\<^sub>0 sh\<^sub>0 pvs h\<^sub>1 ls\<^sub>1 sh\<^sub>1 C' M' Ts T body D v' h\<^sub>2 ls\<^sub>2 sh\<^sub>2 ls\<^sub>2' e' h\<^sub>3 ls\<^sub>3 sh\<^sub>3) + show ?case + proof(cases "M' = clinit \ es = []") + case clinit: True then show ?thesis using SCallInit\<^sub>1 by simp + next + case nclinit: False + let ?\\<^sub>0 = "(None,h\<^sub>0,(vs, ls\<^sub>0, C,M,pc,ics)#frs,sh\<^sub>0)" + let ?pc\<^sub>1 = "pc + length(compEs\<^sub>2 es)" + let ?frs\<^sub>1 = "(rev pvs @ vs, ls\<^sub>1, C,M,?pc\<^sub>1,ics)#frs" + let ?\\<^sub>1 = "(None,h\<^sub>1,?frs\<^sub>1,sh\<^sub>1)" + let ?frs\<^sub>1' = "(rev pvs@vs,ls\<^sub>1,C,M,?pc\<^sub>1,Calling D [])#frs" + let ?\\<^sub>1' = "(None,h\<^sub>1,?frs\<^sub>1',sh\<^sub>1)" + let ?frs\<^sub>2 = "(rev pvs@vs,ls\<^sub>1,C,M,?pc\<^sub>1,Called [])#frs" + let ?\\<^sub>2 = "(None,h\<^sub>2,?frs\<^sub>2,sh\<^sub>2)" + let ?frs\<^sub>2' = "([], ls\<^sub>2', D,M',0,No_ics) # ?frs\<^sub>1" + let ?\\<^sub>2' = "(None, h\<^sub>2, ?frs\<^sub>2', sh\<^sub>2)" + have nclinit': "M' \ clinit" by fact + have ics: "ics = No_ics" using SCallInit\<^sub>1.hyps(5) SCallInit\<^sub>1.prems by simp + have "P\<^sub>1 \\<^sub>1 \es,(h\<^sub>0, ls\<^sub>0, sh\<^sub>0)\ [\] \map Val pvs,(h\<^sub>1, ls\<^sub>1, sh\<^sub>1)\" by fact + hence [simp]: "length es = length pvs" by(auto dest:evals\<^sub>1_preserves_elen) + have invoke: "P,C,M,?pc\<^sub>1 \ Invokestatic C' M' (length Ts)" + using SCallInit\<^sub>1.hyps(8) SCallInit\<^sub>1.prems nclinit by(auto simp: add.assoc) + have nsub: "\ sub_RI body" by(rule sees_wf\<^sub>1_nsub_RI[OF wf SCallInit\<^sub>1.hyps(3)]) + have ls: "ls\<^sub>1 = ls\<^sub>2" by(rule init\<^sub>1_same_loc[OF SCallInit\<^sub>1.hyps(6)]) + obtain sfs i where sh\<^sub>2: "sh\<^sub>2 D = Some(sfs,i)" + using init\<^sub>1_Val_PD[OF SCallInit\<^sub>1.hyps(6)] by clarsimp + have method: "\m'. P \ C' sees M',Static:Ts\T = m' in D" using SCallInit\<^sub>1.hyps(3) + by (metis P_def compP\<^sub>2_def sees_method_compP) + have "Ex (WTrt2\<^sub>1 P\<^sub>1 E h\<^sub>1 sh\<^sub>1 (INIT D ([D],False) \ unit))" + using sees_method_is_class'[OF SCallInit\<^sub>1.hyps(3)] by auto + then obtain err' where pcs': + "Jcc_pieces P\<^sub>1 E C M h\<^sub>1 (rev pvs@vs) ls\<^sub>1 ?pc\<^sub>1 ics frs sh\<^sub>1 I h\<^sub>2 ls\<^sub>2 sh\<^sub>2 v' xa (INIT D ([D],False) \ unit) + = (True, ?frs\<^sub>1', (None,h\<^sub>2,?frs\<^sub>2,sh\<^sub>2), err')" + using SCallInit\<^sub>1.prems(1) nclinit by auto + have IHI: "PROP ?P (INIT D ([D],False) \ unit) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 (Val v') + h\<^sub>2 ls\<^sub>2 sh\<^sub>2 E C M ?pc\<^sub>1 ics v' xa (rev pvs@vs) frs I" by fact + have IH_es: "PROP ?Ps es h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (map Val pvs) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 C M pc ics pvs xa + (map Val pvs) vs frs I" by fact + have "P \ ?\\<^sub>0 -jvm\ ?\\<^sub>1" using IH_es SCallInit\<^sub>1.prems nclinit by auto fastforce+ + also have "P \ \ -jvm\ ?\\<^sub>1'" + proof(cases "sh\<^sub>1 D") + case None then show ?thesis using SCallInit\<^sub>1.hyps(1,3-6,8-10) SCallInit\<^sub>1.prems method + by(cases ics) auto + next + case (Some a) + then obtain sfs i where "a = (sfs,i)" by(cases a) + then show ?thesis using SCallInit\<^sub>1.hyps(1,3-6,8-10) SCallInit\<^sub>1.prems method Some + by(cases ics; case_tac i, auto) + qed + also have "P \ \ -jvm\ ?\\<^sub>2" using IHI pcs' by auto + also have "P \ \ -jvm\ ?\\<^sub>2'" + using jvm_Invokestatic_Called[OF assms(1) invoke _ SCallInit\<^sub>1.hyps(3,8,9)] sh\<^sub>2 ics by auto + finally have 1: "P \ ?\\<^sub>0 -jvm\ ?\\<^sub>2'". + have "P\<^sub>1 \ C' sees M',Static: Ts\T = body in D" by fact + then have M'_in_D: "P\<^sub>1 \ D sees M',Static: Ts\T = body in D" + by(rule sees_method_idemp) + have M'_code: "compP\<^sub>2 P\<^sub>1,D,M',0 \ compE\<^sub>2 body @ [Return]" using beforeM M'_in_D by simp + have M'_xtab: "compP\<^sub>2 P\<^sub>1,D,M' \ compxE\<^sub>2 body 0 0/{..2 body)},0" + using M'_in_D by(rule beforexM) + have IH_body: "PROP ?P body h\<^sub>2 ls\<^sub>2' sh\<^sub>2 e' h\<^sub>3 ls\<^sub>3 sh\<^sub>3 (Class D # Ts) D M' 0 No_ics v xa [] ?frs\<^sub>1 + ({..2 body)})" by fact + have cond: "Jcc_cond P\<^sub>1 (Class D # Ts) D M' [] 0 No_ics {..2 body)} h\<^sub>2 sh\<^sub>2 body" + using nsub_RI_Jcc_pieces[OF assms(1) nsub] M'_code M'_xtab by clarsimp + show ?thesis (is "?Norm \ ?Err") + proof + show ?Norm (is "?val \ ?trans") + proof + assume val: ?val + note 1 + also have "P \ ?\\<^sub>2' -jvm\ (None,h\<^sub>3,([v],ls\<^sub>3,D,M',size(compE\<^sub>2 body),No_ics)#?frs\<^sub>1,sh\<^sub>3)" + using val IH_body SCallInit\<^sub>1.prems M'_code cond nsub_RI_Jcc_pieces nsub by auto + also have "P \ \ -jvm\ (None, h\<^sub>3, (v#vs, ls\<^sub>2, C,M,?pc\<^sub>1+1,ics)#frs,sh\<^sub>3)" + using SCallInit\<^sub>1.hyps(8) M'_code M'_in_D ls nclinit' by(cases T, auto) + finally show ?trans using nclinit by(auto simp:add.assoc) + qed + next + show ?Err (is "?throw \ ?err") + proof + assume throw: ?throw + with IH_body obtain pc\<^sub>2 vs' where + pc\<^sub>2: "0 \ pc\<^sub>2 \ pc\<^sub>2 < size(compE\<^sub>2 body) \ + \ caught P pc\<^sub>2 h\<^sub>3 xa (compxE\<^sub>2 body 0 0)" and + 2: "P \ ?\\<^sub>2' -jvm\ handle P D M' xa h\<^sub>3 vs' ls\<^sub>3 pc\<^sub>2 No_ics ?frs\<^sub>1 sh\<^sub>3" + using SCallInit\<^sub>1.prems M'_code M'_xtab cond nsub_RI_Jcc_pieces nsub + by (auto simp del:split_paired_Ex) + have "handle P D M' xa h\<^sub>3 vs' ls\<^sub>3 pc\<^sub>2 No_ics ?frs\<^sub>1 sh\<^sub>3 = + handle P C M xa h\<^sub>3 (rev pvs @ vs) ls\<^sub>2 ?pc\<^sub>1 ics frs sh\<^sub>3" + using pc\<^sub>2 M'_in_D ls nclinit' by(auto simp add:handle_def) + then show "?err" using pc\<^sub>2 jvm_trans[OF 1 2] nclinit + by(auto intro!:exI[where x="?pc\<^sub>1"] exI[where x="rev pvs"]) + qed + qed + qed +next + case (SCall\<^sub>1 es h\<^sub>1 ls\<^sub>1 sh\<^sub>1 pvs h\<^sub>2 ls\<^sub>2 sh\<^sub>2 C' M' Ts T body D sfs ls\<^sub>2' e' h\<^sub>3 ls\<^sub>3 sh\<^sub>3) + show ?case + proof(cases "M' = clinit \ es = []") + case clinit: True + then have s1: "pvs = []" "h\<^sub>1 = h\<^sub>2" "ls\<^sub>1 = ls\<^sub>2" "sh\<^sub>1 = sh\<^sub>2" + using SCall\<^sub>1.hyps(1) evals\<^sub>1_cases(1) by blast+ + then have ls\<^sub>2': "ls\<^sub>2' = replicate (max_vars body) undefined" using SCall\<^sub>1.hyps(6) clinit by simp + let ?frs = "create_init_frame P C' # (vs, ls\<^sub>1, C,M,pc,ics)#frs" + let ?\\<^sub>1 = "(None,h\<^sub>1,?frs,sh\<^sub>1)" + have method: "P\<^sub>1 \ C' sees clinit,Static: []\Void = body in C'" + using SCall\<^sub>1.hyps(3) clinit s1(1) wf_sees_clinit[OF wf] + by (metis is_class_def option.collapse sees_method_fun sees_method_is_class) + then have M_code: "compP\<^sub>2 P\<^sub>1,C',clinit,0 \ compE\<^sub>2 body @ [Return]" by(rule beforeM) + have pcs: "Jcc_pieces P\<^sub>1 E C M h\<^sub>1 vs ls\<^sub>1 pc ics frs sh\<^sub>1 I h\<^sub>3 ls\<^sub>2 sh\<^sub>3 v xa (C'\\<^sub>sclinit([])) + = (True, ?frs, (None, h\<^sub>3, tl ?frs, sh\<^sub>3(C'\(fst(the(sh\<^sub>3 C')),Done))), + P \ (None, h\<^sub>1, ?frs, sh\<^sub>1) -jvm\ + (case ics of + Called Cs \ (None, h\<^sub>3, (vs, ls\<^sub>1, C, M, pc, Throwing Cs xa) # frs, sh\<^sub>3(C' \ (fst (the (sh\<^sub>3 C')), Error)))))" + using Jcc_pieces_clinit[OF assms(1),of E C M vs pc ics I h\<^sub>1 sh\<^sub>1 C' ls\<^sub>1 frs h\<^sub>3 ls\<^sub>2 sh\<^sub>3 v xa] + SCall\<^sub>1.prems(1) clinit s1(1) by clarsimp + have IH_body: "PROP ?P body h\<^sub>2 ls\<^sub>2' sh\<^sub>2 e' h\<^sub>3 ls\<^sub>3 sh\<^sub>3 [] C' clinit 0 No_ics v xa [] (tl ?frs) + ({..2 body)})" by fact + show ?thesis (is "?Norm \ ?Err") + proof + show ?Norm (is "?val \ ?trans") + proof + assume val: ?val + then have "P \ ?\\<^sub>1 + -jvm\ (None, h\<^sub>3, ([v], ls\<^sub>3, C', clinit, size(compE\<^sub>2 body), No_ics) # tl ?frs,sh\<^sub>3)" + using IH_body Jcc_pieces_SCall_clinit_body[OF assms(1) wf pcs method] s1 ls\<^sub>2' by clarsimp + also have "P \ \ -jvm\ (None, h\<^sub>3, tl ?frs, sh\<^sub>3(C'\(fst(the(sh\<^sub>3 C')),Done)))" + using jvm_Return_Init[OF M_code] by simp + finally show ?trans using pcs s1 clinit by simp + qed + next + show ?Err (is "?throw \ ?err") + proof + assume throw: ?throw + with IH_body obtain pc\<^sub>2 vs2 where + pc\<^sub>2: "0 \ pc\<^sub>2 \ pc\<^sub>2 < size(compE\<^sub>2 body) \ + \ caught P pc\<^sub>2 h\<^sub>3 xa (compxE\<^sub>2 body 0 0)" and + 2: "P \ ?\\<^sub>1 -jvm\ handle P C' clinit xa h\<^sub>3 vs2 ls\<^sub>3 pc\<^sub>2 No_ics (tl ?frs) sh\<^sub>3" + using SCall\<^sub>1.prems Jcc_pieces_SCall_clinit_body[OF assms(1) wf pcs method] s1 ls\<^sub>2' by clarsimp + show ?err using SCall\<^sub>1.prems(1) clinit + proof(cases ics) + case (Called Cs) + note 2 + also have "handle P C' clinit xa h\<^sub>3 vs2 ls\<^sub>3 pc\<^sub>2 No_ics (tl ?frs) sh\<^sub>3 + = (None, h\<^sub>3, (vs, ls\<^sub>1, C, M, pc, Throwing (C'#Cs) xa) # frs, sh\<^sub>3)" + using Called pc\<^sub>2 method by(simp add: handle_def) + also have "P \ \ -jvm\ (None, h\<^sub>3, (vs, ls\<^sub>1, C, M, pc, Throwing Cs xa) # frs, + sh\<^sub>3(C' \ (fst (the (sh\<^sub>3 C')), Error)))" using Called jvm_Throwing by simp + finally show ?thesis using pcs clinit Called by(clarsimp intro!: exI[where x="[]"]) + qed(auto) + qed + qed + next + case nclinit: False + let ?\\<^sub>1 = "(None,h\<^sub>1,(vs, ls\<^sub>1, C,M,pc,ics)#frs,sh\<^sub>1)" + let ?pc\<^sub>2 = "pc + length(compEs\<^sub>2 es)" + let ?frs\<^sub>2 = "(rev pvs @ vs, ls\<^sub>2, C,M,?pc\<^sub>2,ics)#frs" + let ?\\<^sub>2 = "(None,h\<^sub>2,?frs\<^sub>2,sh\<^sub>2)" + let ?frs\<^sub>2' = "([], ls\<^sub>2', D,M',0,No_ics) # ?frs\<^sub>2" + let ?\\<^sub>2' = "(None, h\<^sub>2, ?frs\<^sub>2', sh\<^sub>2)" + have nclinit': "M' \ clinit" + using wf_sees_clinit1[OF wf] visible_method_exists[OF SCall\<^sub>1.hyps(3)] + sees_method_idemp[OF SCall\<^sub>1.hyps(3)] nclinit SCall\<^sub>1.hyps(5) + evals\<^sub>1_preserves_elen[OF SCall\<^sub>1.hyps(1)] by fastforce + have "P\<^sub>1 \\<^sub>1 \es,(h\<^sub>1, ls\<^sub>1, sh\<^sub>1)\ [\] \map Val pvs,(h\<^sub>2, ls\<^sub>2, sh\<^sub>2)\" by fact + hence [simp]: "length es = length pvs" by(auto dest:evals\<^sub>1_preserves_elen) + have invoke: "P,C,M,?pc\<^sub>2 \ Invokestatic C' M' (length Ts)" + using SCall\<^sub>1.hyps(5) SCall\<^sub>1.prems nclinit by(auto simp: add.assoc) + have nsub: "\ sub_RI body" by(rule sees_wf\<^sub>1_nsub_RI[OF wf SCall\<^sub>1.hyps(3)]) + have IH_es: "PROP ?Ps es h\<^sub>1 ls\<^sub>1 sh\<^sub>1 (map Val pvs) h\<^sub>2 ls\<^sub>2 sh\<^sub>2 C M pc ics pvs xa + (map Val pvs) vs frs I" by fact + have "P \ ?\\<^sub>1 -jvm\ ?\\<^sub>2" using IH_es SCall\<^sub>1.prems nclinit by auto fastforce+ + also have "P \ \ -jvm\ ?\\<^sub>2'" using jvm_Invokestatic[OF assms(1) invoke _ SCall\<^sub>1.hyps(3,5,6)] + SCall\<^sub>1.hyps(4) SCall\<^sub>1.prems nclinit by auto + finally have 1: "P \ ?\\<^sub>1 -jvm\ ?\\<^sub>2'". + have "P\<^sub>1 \ C' sees M',Static: Ts\T = body in D" by fact + then have M'_in_D: "P\<^sub>1 \ D sees M',Static: Ts\T = body in D" + by(rule sees_method_idemp) + have M'_code: "compP\<^sub>2 P\<^sub>1,D,M',0 \ compE\<^sub>2 body @ [Return]" using beforeM M'_in_D by simp + have M'_xtab: "compP\<^sub>2 P\<^sub>1,D,M' \ compxE\<^sub>2 body 0 0/{..2 body)},0" + using M'_in_D by(rule beforexM) + have IH_body: "PROP ?P body h\<^sub>2 ls\<^sub>2' sh\<^sub>2 e' h\<^sub>3 ls\<^sub>3 sh\<^sub>3 (Class D # Ts) D M' 0 No_ics v xa [] ?frs\<^sub>2 + ({..2 body)})" by fact + have cond: "Jcc_cond P\<^sub>1 (Class D # Ts) D M' [] 0 No_ics {..2 body)} h\<^sub>2 sh\<^sub>2 body" + using nsub_RI_Jcc_pieces[OF assms(1) nsub] M'_code M'_xtab by clarsimp + show ?thesis (is "?Norm \ ?Err") + proof + show ?Norm (is "?val \ ?trans") + proof + assume val: ?val + note 1 + also have "P \ ?\\<^sub>2' -jvm\ (None,h\<^sub>3,([v],ls\<^sub>3,D,M',size(compE\<^sub>2 body),No_ics)#?frs\<^sub>2,sh\<^sub>3)" + using val IH_body SCall\<^sub>1.prems M'_code cond nsub_RI_Jcc_pieces nsub by auto + also have "P \ \ -jvm\ (None, h\<^sub>3, (v#vs, ls\<^sub>2, C,M,?pc\<^sub>2+1,ics)#frs,sh\<^sub>3)" + using SCall\<^sub>1.hyps(5) M'_code M'_in_D nclinit' by(cases T, auto) + finally show ?trans using nclinit by(auto simp:add.assoc) + qed + next + show ?Err (is "?throw \ ?err") + proof + assume throw: ?throw + with IH_body obtain pc\<^sub>2 vs' where + pc\<^sub>2: "0 \ pc\<^sub>2 \ pc\<^sub>2 < size(compE\<^sub>2 body) \ + \ caught P pc\<^sub>2 h\<^sub>3 xa (compxE\<^sub>2 body 0 0)" and + 2: "P \ ?\\<^sub>2' -jvm\ handle P D M' xa h\<^sub>3 vs' ls\<^sub>3 pc\<^sub>2 No_ics ?frs\<^sub>2 sh\<^sub>3" + using SCall\<^sub>1.prems M'_code M'_xtab cond nsub_RI_Jcc_pieces nsub + by (auto simp del:split_paired_Ex) + have "handle P D M' xa h\<^sub>3 vs' ls\<^sub>3 pc\<^sub>2 No_ics ?frs\<^sub>2 sh\<^sub>3 = + handle P C M xa h\<^sub>3 (rev pvs @ vs) ls\<^sub>2 ?pc\<^sub>2 ics frs sh\<^sub>3" + using pc\<^sub>2 M'_in_D nclinit' by(auto simp add:handle_def) + then show "?err" using pc\<^sub>2 jvm_trans[OF 1 2] nclinit by(auto intro:exI[where x="?pc\<^sub>2"]) + qed + qed + qed +next + case Block\<^sub>1 then show ?case using nsub_RI_Jcc_pieces by auto +next + case (Seq\<^sub>1 e\<^sub>1 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 w h\<^sub>1 ls\<^sub>1 sh\<^sub>1 e\<^sub>2 e\<^sub>2' h\<^sub>2 ls\<^sub>2 sh\<^sub>2) + let ?pc\<^sub>1 = "pc + length(compE\<^sub>2 e\<^sub>1)" + let ?\\<^sub>0 = "(None,h\<^sub>0,(vs,ls\<^sub>0,C,M,pc,ics)#frs,sh\<^sub>0)" + let ?\\<^sub>1 = "(None,h\<^sub>1,(vs,ls\<^sub>1,C,M,?pc\<^sub>1+1,ics)#frs,sh\<^sub>1)" + let ?I = "I - pcs (compxE\<^sub>2 e\<^sub>2 (Suc ?pc\<^sub>1) (length vs))" + have Isub: "{pc..2 e\<^sub>1)} \ ?I" using Seq\<^sub>1.prems by clarsimp + have IH: "PROP ?P e\<^sub>1 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (Val w) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics w xa vs frs ?I" by fact + have "P \ ?\\<^sub>0 -jvm\ (None,h\<^sub>1,(w#vs,ls\<^sub>1,C,M,?pc\<^sub>1,ics)#frs,sh\<^sub>1)" + using Seq\<^sub>1.prems nsub_RI_Jcc_pieces IH Isub by auto + also have "P \ \ -jvm\ ?\\<^sub>1" using Seq\<^sub>1 by auto + finally have eval\<^sub>1: "P \ ?\\<^sub>0 -jvm\ ?\\<^sub>1". + let ?pc\<^sub>2 = "?pc\<^sub>1 + 1 + length(compE\<^sub>2 e\<^sub>2)" + let ?I' = "I - pcs(compxE\<^sub>2 e\<^sub>1 pc (size vs))" + have IH\<^sub>2: "PROP ?P e\<^sub>2 h\<^sub>1 ls\<^sub>1 sh\<^sub>1 e\<^sub>2' h\<^sub>2 ls\<^sub>2 sh\<^sub>2 E C M (?pc\<^sub>1+1) ics v xa vs frs + ?I'" by fact + have Isub2: "{Suc (pc + length (compE\<^sub>2 e\<^sub>1))..2 e\<^sub>1) + length (compE\<^sub>2 e\<^sub>2))} + \ ?I'" using Seq\<^sub>1.prems by clarsimp + show ?case (is "?Norm \ ?Err") + proof + show ?Norm (is "?val \ ?trans") + proof + assume val: ?val + note eval\<^sub>1 + also have "P \ ?\\<^sub>1 -jvm\ (None,h\<^sub>2,(v#vs,ls\<^sub>2,C,M,?pc\<^sub>2,ics)#frs,sh\<^sub>2)" + using val Seq\<^sub>1.prems nsub_RI_Jcc_pieces IH\<^sub>2 Isub2 by auto + finally show ?trans by(simp add:add.assoc) + qed + next + show ?Err (is "?throw \ ?err") + proof + assume throw: ?throw + then obtain pc\<^sub>2 vs' where + pc\<^sub>2: "?pc\<^sub>1+1 \ pc\<^sub>2 \ pc\<^sub>2 < ?pc\<^sub>2 \ + \ caught P pc\<^sub>2 h\<^sub>2 xa (compxE\<^sub>2 e\<^sub>2 (?pc\<^sub>1+1) (size vs))" and + eval\<^sub>2: "P \ ?\\<^sub>1 -jvm\ handle P C M xa h\<^sub>2 (vs'@vs) ls\<^sub>2 pc\<^sub>2 ics frs sh\<^sub>2" + using IH\<^sub>2 Seq\<^sub>1.prems nsub_RI_Jcc_pieces Isub2 by auto + show "?err" using pc\<^sub>2 jvm_trans[OF eval\<^sub>1 eval\<^sub>2] by(auto intro: exI[where x=pc\<^sub>2]) + qed + qed +next + case (SeqThrow\<^sub>1 e\<^sub>0 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 e h\<^sub>1 ls\<^sub>1 sh\<^sub>1 e\<^sub>1) + let ?I = "I - pcs (compxE\<^sub>2 e\<^sub>1 (Suc (pc + length (compE\<^sub>2 e\<^sub>0))) (length vs))" + obtain a' where throw: "throw e = Throw a'" using eval\<^sub>1_final[OF SeqThrow\<^sub>1.hyps(1)] by clarsimp + have Isub: "{pc..2 e\<^sub>0)} \ ?I" using SeqThrow\<^sub>1.prems by clarsimp + have "PROP ?P e\<^sub>0 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (throw e) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics v a' vs frs ?I" by fact + then show ?case using SeqThrow\<^sub>1.prems throw nsub_RI_Jcc_pieces Isub by auto +next + case (CondT\<^sub>1 e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 h\<^sub>1 ls\<^sub>1 sh\<^sub>1 e\<^sub>1 e' h\<^sub>2 ls\<^sub>2 sh\<^sub>2 e\<^sub>2) + let ?pc\<^sub>1 = "pc + length(compE\<^sub>2 e)" + let ?\\<^sub>0 = "(None,h\<^sub>0,(vs,ls\<^sub>0,C,M,pc,ics)#frs,sh\<^sub>0)" + let ?\\<^sub>1 = "(None,h\<^sub>1,(vs,ls\<^sub>1,C,M,?pc\<^sub>1+1,ics)#frs,sh\<^sub>1)" + let ?d = "size vs" + let ?xt\<^sub>1 = "compxE\<^sub>2 e\<^sub>1 (pc+size(compE\<^sub>2 e)+1) ?d" + let ?xt\<^sub>2 = "compxE\<^sub>2 e\<^sub>2 (pc+size(compE\<^sub>2 e)+size(compE\<^sub>2 e\<^sub>1)+2) ?d" + let ?I = "I - (pcs ?xt\<^sub>1 \ pcs ?xt\<^sub>2)" + have Isub: "{pc..2 e)} \ ?I" using CondT\<^sub>1.prems by clarsimp + have IH: "PROP ?P e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 true h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics (Bool True) xa vs frs ?I" by fact + have "P \ ?\\<^sub>0 -jvm\ (None,h\<^sub>1,(Bool(True)#vs,ls\<^sub>1,C,M,?pc\<^sub>1,ics)#frs,sh\<^sub>1)" + using CondT\<^sub>1.prems nsub_RI_Jcc_pieces IH Isub by(auto simp: Int_Un_distrib) + also have "P \ \ -jvm\ ?\\<^sub>1" using CondT\<^sub>1 by auto + finally have eval\<^sub>1: "P \ ?\\<^sub>0 -jvm\ ?\\<^sub>1". + let ?pc\<^sub>1' = "?pc\<^sub>1 + 1 + length(compE\<^sub>2 e\<^sub>1)" + let ?pc\<^sub>2' = "?pc\<^sub>1' + 1 + length(compE\<^sub>2 e\<^sub>2)" + let ?I' = "I - pcs(compxE\<^sub>2 e pc ?d) - pcs(compxE\<^sub>2 e\<^sub>2 (?pc\<^sub>1'+1) ?d)" + have IH2: "PROP ?P e\<^sub>1 h\<^sub>1 ls\<^sub>1 sh\<^sub>1 e' h\<^sub>2 ls\<^sub>2 sh\<^sub>2 E C M (?pc\<^sub>1+1) ics v xa vs frs ?I'" by fact + show ?case (is "?Norm \ ?Err") + proof + show ?Norm (is "?val \ ?trans") + proof + assume val: ?val + note eval\<^sub>1 + also have "P \ ?\\<^sub>1 -jvm\ (None,h\<^sub>2,(v#vs,ls\<^sub>2,C,M,?pc\<^sub>1',ics)#frs,sh\<^sub>2)" + using val CondT\<^sub>1.prems nsub_RI_Jcc_pieces IH2 by(fastforce simp:Int_Un_distrib) + also have "P \ \ -jvm\ (None,h\<^sub>2,(v#vs,ls\<^sub>2,C,M,?pc\<^sub>2',ics)#frs,sh\<^sub>2)" + using CondT\<^sub>1 nsub_RI_Jcc_pieces by(auto simp:add.assoc) + finally show ?trans by(simp add:add.assoc) + qed + next + show ?Err (is "?throw \ ?err") + proof + assume throw: ?throw + moreover + note IH2 + ultimately obtain pc\<^sub>2 vs' where + pc\<^sub>2: "?pc\<^sub>1+1 \ pc\<^sub>2 \ pc\<^sub>2 < ?pc\<^sub>1' \ + \ caught P pc\<^sub>2 h\<^sub>2 xa (compxE\<^sub>2 e\<^sub>1 (?pc\<^sub>1+1) (size vs))" and + eval\<^sub>2: "P \ ?\\<^sub>1 -jvm\ handle P C M xa h\<^sub>2 (vs'@vs) ls\<^sub>2 pc\<^sub>2 ics frs sh\<^sub>2" + using CondT\<^sub>1.prems nsub_RI_Jcc_pieces by (fastforce simp:Int_Un_distrib) + show "?err" using pc\<^sub>2 jvm_trans[OF eval\<^sub>1 eval\<^sub>2] by(auto intro: exI[where x=pc\<^sub>2]) + qed + qed +next + case (CondF\<^sub>1 e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 h\<^sub>1 ls\<^sub>1 sh\<^sub>1 e\<^sub>2 e' h\<^sub>2 ls\<^sub>2 sh\<^sub>2 e\<^sub>1) + let ?pc\<^sub>1 = "pc + length(compE\<^sub>2 e)" + let ?pc\<^sub>2 = "?pc\<^sub>1 + 1 + length(compE\<^sub>2 e\<^sub>1)+ 1" + let ?pc\<^sub>2' = "?pc\<^sub>2 + length(compE\<^sub>2 e\<^sub>2)" + let ?\\<^sub>0 = "(None,h\<^sub>0,(vs,ls\<^sub>0,C,M,pc,ics)#frs,sh\<^sub>0)" + let ?\\<^sub>1 = "(None,h\<^sub>1,(vs,ls\<^sub>1,C,M,?pc\<^sub>2,ics)#frs,sh\<^sub>1)" + let ?d = "size vs" + let ?xt\<^sub>1 = "compxE\<^sub>2 e\<^sub>1 (pc+size(compE\<^sub>2 e)+1) ?d" + let ?xt\<^sub>2 = "compxE\<^sub>2 e\<^sub>2 (pc+size(compE\<^sub>2 e)+size(compE\<^sub>2 e\<^sub>1)+2) ?d" + let ?I = "I - (pcs ?xt\<^sub>1 \ pcs ?xt\<^sub>2)" + let ?I' = "I - pcs(compxE\<^sub>2 e pc ?d) - pcs(compxE\<^sub>2 e\<^sub>1 (?pc\<^sub>1+1) ?d)" + have pcs: "pcs(compxE\<^sub>2 e pc ?d) \ pcs(?xt\<^sub>1 @ ?xt\<^sub>2) = {}" + using CondF\<^sub>1.prems by (simp add:Int_Un_distrib) + have Isub: "{pc..2 e)} \ ?I" using CondF\<^sub>1.prems by clarsimp + have IH: "PROP ?P e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 false h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics (Bool False) xa vs frs ?I" by fact + have IH2: "PROP ?P e\<^sub>2 h\<^sub>1 ls\<^sub>1 sh\<^sub>1 e' h\<^sub>2 ls\<^sub>2 sh\<^sub>2 E C M ?pc\<^sub>2 ics v xa vs frs ?I'" by fact + have "P \ ?\\<^sub>0 -jvm\ (None,h\<^sub>1,(Bool(False)#vs,ls\<^sub>1,C,M,?pc\<^sub>1,ics)#frs,sh\<^sub>1)" + using CondF\<^sub>1.prems nsub_RI_Jcc_pieces IH Isub pcs by auto + also have "P \ \ -jvm\ ?\\<^sub>1" using CondF\<^sub>1 by auto + finally have eval\<^sub>1: "P \ ?\\<^sub>0 -jvm\ ?\\<^sub>1". + show ?case (is "?Norm \ ?Err") + proof + show ?Norm (is "?val \ ?trans") + proof + assume val: ?val + note eval\<^sub>1 + also have "P \ ?\\<^sub>1 -jvm\ (None,h\<^sub>2,(v#vs,ls\<^sub>2,C,M,?pc\<^sub>2',ics)#frs,sh\<^sub>2)" + using val CondF\<^sub>1.prems nsub_RI_Jcc_pieces IH2 by(fastforce simp:Int_Un_distrib) + finally show ?trans by(simp add:add.assoc) + qed + next + show ?Err (is "?throw \ ?err") + proof + let ?I' = "I - pcs(compxE\<^sub>2 e pc ?d) - pcs(compxE\<^sub>2 e\<^sub>1 (?pc\<^sub>1+1) ?d)" + assume throw: ?throw + then obtain pc\<^sub>2 vs' where + pc\<^sub>2: "?pc\<^sub>2 \ pc\<^sub>2 \ pc\<^sub>2 < ?pc\<^sub>2' \ + \ caught P pc\<^sub>2 h\<^sub>2 xa (compxE\<^sub>2 e\<^sub>2 ?pc\<^sub>2 ?d)" and + eval\<^sub>2: "P \ ?\\<^sub>1 -jvm\ handle P C M xa h\<^sub>2 (vs'@vs) ls\<^sub>2 pc\<^sub>2 ics frs sh\<^sub>2" + using CondF\<^sub>1.prems nsub_RI_Jcc_pieces IH2 by(fastforce simp:Int_Un_distrib) + show "?err" using pc\<^sub>2 jvm_trans[OF eval\<^sub>1 eval\<^sub>2] by(auto intro: exI[where x=pc\<^sub>2]) + qed + qed +next + case (CondThrow\<^sub>1 e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 f h\<^sub>1 ls\<^sub>1 sh\<^sub>1 e\<^sub>1 e\<^sub>2) + let ?d = "size vs" + let ?xt\<^sub>1 = "compxE\<^sub>2 e\<^sub>1 (pc+size(compE\<^sub>2 e)+1) ?d" + let ?xt\<^sub>2 = "compxE\<^sub>2 e\<^sub>2 (pc+size(compE\<^sub>2 e)+size(compE\<^sub>2 e\<^sub>1)+2) ?d" + let ?I = "I - (pcs ?xt\<^sub>1 \ pcs ?xt\<^sub>2)" + have Isub: "{pc..2 e)} \ ?I" using CondThrow\<^sub>1.prems by clarsimp + have "pcs(compxE\<^sub>2 e pc ?d) \ pcs(?xt\<^sub>1 @ ?xt\<^sub>2) = {}" + using CondThrow\<^sub>1.prems by (simp add:Int_Un_distrib) + moreover have "PROP ?P e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (throw f) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics v xa vs frs ?I" by fact + ultimately show ?case using CondThrow\<^sub>1.prems nsub_RI_Jcc_pieces Isub by auto +next + case (WhileF\<^sub>1 e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 h\<^sub>1 ls\<^sub>1 sh\<^sub>1 c) + let ?pc = "pc + length(compE\<^sub>2 e)" + let ?pc' = "?pc + length(compE\<^sub>2 c) + 3" + have Isub: "{pc..2 e)} \ I - pcs (compxE\<^sub>2 c (Suc (pc + length (compE\<^sub>2 e))) (length vs))" + using WhileF\<^sub>1.prems by clarsimp + have Isub2: "{Suc (pc + length (compE\<^sub>2 e))..2 e) + length (compE\<^sub>2 c))} + \ I - pcs (compxE\<^sub>2 e pc (length vs))" using WhileF\<^sub>1.prems by clarsimp + have IH: "PROP ?P e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 false h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics (Bool False) xa vs frs + (I - pcs (compxE\<^sub>2 c (Suc (pc + length (compE\<^sub>2 e))) (length vs)))" by fact + have "P \ (None,h\<^sub>0,(vs,ls\<^sub>0,C,M,pc,ics)#frs,sh\<^sub>0) -jvm\ + (None,h\<^sub>1,(Bool False#vs,ls\<^sub>1,C,M,?pc,ics)#frs,sh\<^sub>1)" + using WhileF\<^sub>1.prems nsub_RI_Jcc_pieces IH Isub by auto + also have "P \ \ -jvm\ (None,h\<^sub>1,(vs,ls\<^sub>1,C,M,?pc',ics)#frs,sh\<^sub>1)" + using WhileF\<^sub>1 by (auto simp:add.assoc) + also have "P \ \ -jvm\ (None,h\<^sub>1,(Unit#vs,ls\<^sub>1,C,M,?pc'+1,ics)#frs,sh\<^sub>1)" + using WhileF\<^sub>1.prems by (auto simp:eval_nat_numeral) + finally show ?case by (simp add:add.assoc eval_nat_numeral) +next + case (WhileT\<^sub>1 e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 h\<^sub>1 ls\<^sub>1 sh\<^sub>1 c v\<^sub>1 h\<^sub>2 ls\<^sub>2 sh\<^sub>2 e\<^sub>3 h\<^sub>3 ls\<^sub>3 sh\<^sub>3) + let ?pc = "pc + length(compE\<^sub>2 e)" + let ?pc' = "?pc + length(compE\<^sub>2 c) + 1" + let ?\\<^sub>0 = "(None,h\<^sub>0,(vs,ls\<^sub>0,C,M,pc,ics)#frs,sh\<^sub>0)" + let ?\\<^sub>2 = "(None,h\<^sub>2,(vs,ls\<^sub>2,C,M,pc,ics)#frs,sh\<^sub>2)" + have Isub: "{pc..2 e)} \ I - pcs (compxE\<^sub>2 c (Suc (pc + length (compE\<^sub>2 e))) (length vs))" + using WhileT\<^sub>1.prems by clarsimp + have Isub2: "{Suc (pc + length (compE\<^sub>2 e))..2 e) + length (compE\<^sub>2 c))} + \ I - pcs (compxE\<^sub>2 e pc (length vs))" using WhileT\<^sub>1.prems by clarsimp + have IH: "PROP ?P e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 true h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics (Bool True) xa vs frs + (I - pcs (compxE\<^sub>2 c (Suc (pc + length (compE\<^sub>2 e))) (length vs)))" by fact + have IH2: "PROP ?P c h\<^sub>1 ls\<^sub>1 sh\<^sub>1 (Val v\<^sub>1) h\<^sub>2 ls\<^sub>2 sh\<^sub>2 E C M (Suc ?pc) ics v\<^sub>1 xa vs frs + (I - pcs (compxE\<^sub>2 e pc (length vs)))" by fact + have "P \ ?\\<^sub>0 -jvm\ (None,h\<^sub>1,(Bool True#vs,ls\<^sub>1,C,M,?pc,ics)#frs,sh\<^sub>1)" + using WhileT\<^sub>1.prems nsub_RI_Jcc_pieces IH Isub by auto + also have "P \ \ -jvm\ (None,h\<^sub>1,(vs,ls\<^sub>1,C,M,?pc+1,ics)#frs,sh\<^sub>1)" + using WhileT\<^sub>1.prems by auto + also have "P \ \ -jvm\ (None,h\<^sub>2,(v\<^sub>1#vs,ls\<^sub>2,C,M,?pc',ics)#frs,sh\<^sub>2)" + using WhileT\<^sub>1.prems nsub_RI_Jcc_pieces IH2 Isub2 by auto + also have "P \ \ -jvm\ ?\\<^sub>2" using WhileT\<^sub>1.prems by auto + finally have 1: "P \ ?\\<^sub>0 -jvm\ ?\\<^sub>2". + show ?case (is "?Norm \ ?Err") + proof + show ?Norm (is "?val \ ?trans") + proof + assume val: ?val + note 1 + also have "P \ ?\\<^sub>2 -jvm\ (None,h\<^sub>3,(v#vs,ls\<^sub>3,C,M,?pc'+3,ics)#frs,sh\<^sub>3)" + using val WhileT\<^sub>1 by (auto simp add:add.assoc eval_nat_numeral) + finally show ?trans by(simp add:add.assoc eval_nat_numeral) + qed + next + show ?Err (is "?throw \ ?err") + proof + assume throw: ?throw + moreover + have "PROP ?P (while (e) c) h\<^sub>2 ls\<^sub>2 sh\<^sub>2 e\<^sub>3 h\<^sub>3 ls\<^sub>3 sh\<^sub>3 E C M pc ics v xa vs frs I" by fact + ultimately obtain pc\<^sub>2 vs' where + pc\<^sub>2: "pc \ pc\<^sub>2 \ pc\<^sub>2 < ?pc'+3 \ + \ caught P pc\<^sub>2 h\<^sub>3 xa (compxE\<^sub>2 (while (e) c) pc (size vs))" and + 2: "P \ ?\\<^sub>2 -jvm\ handle P C M xa h\<^sub>3 (vs'@vs) ls\<^sub>3 pc\<^sub>2 ics frs sh\<^sub>3" + using WhileT\<^sub>1.prems by (auto simp:add.assoc eval_nat_numeral) + show "?err" using pc\<^sub>2 jvm_trans[OF 1 2] by(auto intro: exI[where x=pc\<^sub>2]) + qed + qed +next + case (WhileCondThrow\<^sub>1 e h ls sh e' h' ls' sh' c) + let ?I = "I - pcs (compxE\<^sub>2 c (Suc (pc + length (compE\<^sub>2 e))) (length vs))" + obtain a' where throw: "throw e' = Throw a'" using eval\<^sub>1_final[OF WhileCondThrow\<^sub>1.hyps(1)] by clarsimp + have Isub: "{pc..2 e)} \ ?I" using WhileCondThrow\<^sub>1.prems by clarsimp + have "PROP ?P e h ls sh (throw e') h' ls' sh' E C M pc ics v a' vs frs ?I" by fact + then show ?case using WhileCondThrow\<^sub>1.prems throw nsub_RI_Jcc_pieces Isub by auto +next + case (WhileBodyThrow\<^sub>1 e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 h\<^sub>1 ls\<^sub>1 sh\<^sub>1 c e' h\<^sub>2 ls\<^sub>2 sh\<^sub>2) + let ?pc\<^sub>1 = "pc + length(compE\<^sub>2 e)" + let ?\\<^sub>0 = "(None,h\<^sub>0,(vs,ls\<^sub>0,C,M,pc,ics)#frs,sh\<^sub>0)" + let ?\\<^sub>1 = "(None,h\<^sub>1,(vs,ls\<^sub>1,C,M,?pc\<^sub>1+1,ics)#frs,sh\<^sub>1)" + let ?I = "I - pcs (compxE\<^sub>2 c (Suc (pc + length (compE\<^sub>2 e))) (length vs))" + have Isub: "{pc..2 e)} \ ?I" + using WhileBodyThrow\<^sub>1.prems by clarsimp + have IH: "PROP ?P e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 true h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics (Bool True) xa vs frs ?I" by fact + then have "P \ ?\\<^sub>0 -jvm\ (None,h\<^sub>1,(Bool(True)#vs,ls\<^sub>1,C,M,?pc\<^sub>1,ics)#frs,sh\<^sub>1)" + using WhileBodyThrow\<^sub>1.prems nsub_RI_Jcc_pieces Isub by auto + also have "P \ \ -jvm\ ?\\<^sub>1" using WhileBodyThrow\<^sub>1 by auto + finally have eval\<^sub>1: "P \ ?\\<^sub>0 -jvm\ ?\\<^sub>1". + let ?pc\<^sub>1' = "?pc\<^sub>1 + 1 + length(compE\<^sub>2 c)" + show ?case (is "?Norm \ ?Err") + proof + show ?Norm by simp + next + show ?Err (is "?throw \ ?err") + proof + assume throw: ?throw + moreover + have "PROP ?P c h\<^sub>1 ls\<^sub>1 sh\<^sub>1 (throw e') h\<^sub>2 ls\<^sub>2 sh\<^sub>2 E C M (?pc\<^sub>1+1) ics v xa vs frs + (I - pcs (compxE\<^sub>2 e pc (size vs)))" by fact + ultimately obtain pc\<^sub>2 vs' where + pc\<^sub>2: "?pc\<^sub>1+1 \ pc\<^sub>2 \ pc\<^sub>2 < ?pc\<^sub>1' \ + \ caught P pc\<^sub>2 h\<^sub>2 xa (compxE\<^sub>2 c (?pc\<^sub>1+1) (size vs))" and + eval\<^sub>2: "P \ ?\\<^sub>1 -jvm\ handle P C M xa h\<^sub>2 (vs'@vs) ls\<^sub>2 pc\<^sub>2 ics frs sh\<^sub>2" + using WhileBodyThrow\<^sub>1.prems nsub_RI_Jcc_pieces by (fastforce simp:Int_Un_distrib) + show "?err" using pc\<^sub>2 jvm_trans[OF eval\<^sub>1 eval\<^sub>2] by(auto intro: exI[where x=pc\<^sub>2]) + qed + qed +next + case (Throw\<^sub>1 e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 a h\<^sub>1 ls\<^sub>1 sh\<^sub>1) + let ?pc = "pc + size(compE\<^sub>2 e)" + have Isub: "{pc..2 e)} \ I" using Throw\<^sub>1.prems by clarsimp + show ?case (is "?Norm \ ?Err") + proof + show ?Norm by simp + next + show ?Err (is "?throw \ ?err") + proof + assume throw:?throw + have "PROP ?P e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (addr a) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics (Addr a) a vs frs I" by fact + then have "P \ (None, h\<^sub>0, (vs, ls\<^sub>0, C, M, pc, ics) # frs, sh\<^sub>0) -jvm\ + (None, h\<^sub>1, (Addr xa#vs, ls\<^sub>1, C, M, ?pc, ics) # frs, sh\<^sub>1)" + using Throw\<^sub>1 nsub_RI_Jcc_pieces Isub throw by auto + also have "P \ \ -jvm\ handle P C M xa h\<^sub>1 (Addr xa#vs) ls\<^sub>1 ?pc ics frs sh\<^sub>1" + using Throw\<^sub>1.prems by(auto simp add:handle_def) + finally show "?err" by(auto intro!: exI[where x="?pc"] exI[where x="[Addr xa]"]) + qed + qed +next + case (ThrowNull\<^sub>1 e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 h\<^sub>1 ls\<^sub>1 sh\<^sub>1) + let ?pc = "pc + size(compE\<^sub>2 e)" + let ?xa = "addr_of_sys_xcpt NullPointer" + have Isub: "{pc..2 e)} \ I" using ThrowNull\<^sub>1.prems by clarsimp + show ?case (is "?Norm \ ?Err") + proof + show ?Norm by simp + next + show ?Err (is "?throw \ ?err") + proof + assume throw: ?throw + have "PROP ?P e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 null h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics Null xa vs frs I" by fact + then have "P \ (None, h\<^sub>0, (vs, ls\<^sub>0, C, M, pc, ics) # frs, sh\<^sub>0) -jvm\ + (None, h\<^sub>1, (Null#vs, ls\<^sub>1, C, M, ?pc, ics) # frs, sh\<^sub>1)" + using ThrowNull\<^sub>1.prems nsub_RI_Jcc_pieces Isub by auto + also have "P \ \ -jvm\ handle P C M ?xa h\<^sub>1 (Null#vs) ls\<^sub>1 ?pc ics frs sh\<^sub>1" + using ThrowNull\<^sub>1.prems by(auto simp add:handle_def) + finally show "?err" using throw by(auto intro!: exI[where x="?pc"] exI[where x="[Null]"]) + qed + qed +next + case (ThrowThrow\<^sub>1 e h ls sh e' h' ls' sh') + obtain a' where throw: "throw e' = Throw a'" using eval\<^sub>1_final[OF ThrowThrow\<^sub>1.hyps(1)] by clarsimp + have Isub: "{pc..2 e)} \ I" using ThrowThrow\<^sub>1.prems by clarsimp + have "PROP ?P e h ls sh (throw e') h' ls' sh' E C M pc ics v a' vs frs I" by fact + then show ?case using ThrowThrow\<^sub>1.prems throw nsub_RI_Jcc_pieces Isub by auto +next + case (Try\<^sub>1 e\<^sub>1 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 v\<^sub>1 h\<^sub>1 ls\<^sub>1 sh\<^sub>1 Ci i e\<^sub>2) + let ?pc\<^sub>1 = "pc + length(compE\<^sub>2 e\<^sub>1)" + let ?pc\<^sub>1' = "?pc\<^sub>1 + 2 + length(compE\<^sub>2 e\<^sub>2)" + have "{pc..2 (try e\<^sub>1 catch(Ci i) e\<^sub>2))} \ I" using Try\<^sub>1.prems by simp + also have "P,C,M \ compxE\<^sub>2 (try e\<^sub>1 catch(Ci i) e\<^sub>2) pc (size vs) / I,size vs" + using Try\<^sub>1.prems by simp + ultimately have "P,C,M \ compxE\<^sub>2 e\<^sub>1 pc (size vs) / {pc..2 e\<^sub>1)},size vs" + by(rule beforex_try) + hence "P \ (None,h\<^sub>0,(vs,ls\<^sub>0,C,M,pc,ics)#frs,sh\<^sub>0) -jvm\ + (None,h\<^sub>1,(v\<^sub>1#vs,ls\<^sub>1,C,M,?pc\<^sub>1,ics)#frs,sh\<^sub>1)" + using Try\<^sub>1 nsub_RI_Jcc_pieces by auto blast + also have "P \ \ -jvm\ (None,h\<^sub>1,(v\<^sub>1#vs,ls\<^sub>1,C,M,?pc\<^sub>1',ics)#frs,sh\<^sub>1)" + using Try\<^sub>1.prems by auto + finally show ?case by (auto simp:add.assoc) +next + case (TryCatch\<^sub>1 e\<^sub>1 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 a h\<^sub>1 ls\<^sub>1 sh\<^sub>1 D fs Ci i e\<^sub>2 e\<^sub>2' h\<^sub>2 ls\<^sub>2 sh\<^sub>2) + let ?e = "try e\<^sub>1 catch(Ci i) e\<^sub>2" + let ?xt = "compxE\<^sub>2 ?e pc (size vs)" + let ?\\<^sub>0 = "(None,h\<^sub>0,(vs,ls\<^sub>0,C,M,pc,ics)#frs,sh\<^sub>0)" + let ?ls\<^sub>1 = "ls\<^sub>1[i := Addr a]" + let ?pc\<^sub>1 = "pc + length(compE\<^sub>2 e\<^sub>1)" + let ?pc\<^sub>1' = "?pc\<^sub>1 + 2" + let ?\\<^sub>1 = "(None,h\<^sub>1,(vs,?ls\<^sub>1,C,M, ?pc\<^sub>1',ics) # frs,sh\<^sub>1)" + have I: "{pc..2 (try e\<^sub>1 catch(Ci i) e\<^sub>2))} \ I" + and beforex: "P,C,M \ ?xt/I,size vs" using TryCatch\<^sub>1.prems by simp+ + have "P \ ?\\<^sub>0 -jvm\ (None,h\<^sub>1,((Addr a)#vs,ls\<^sub>1,C,M, ?pc\<^sub>1+1,ics) # frs,sh\<^sub>1)" + proof - + have ics: "ics = No_ics" using TryCatch\<^sub>1.prems by auto + have "PROP ?P e\<^sub>1 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (Throw a) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics v a vs frs {pc..2 e\<^sub>1)}" + by fact + moreover have "P,C,M \ compxE\<^sub>2 e\<^sub>1 pc (size vs)/{pc..1},size vs" + using beforex I pcs_subset by(force elim!: beforex_appendD1) + ultimately have + "\pc\<^sub>1. pc \ pc\<^sub>1 \ pc\<^sub>1 < ?pc\<^sub>1 \ + \ caught P pc\<^sub>1 h\<^sub>1 a (compxE\<^sub>2 e\<^sub>1 pc (size vs)) \ + (\vs'. P \ ?\\<^sub>0 -jvm\ handle P C M a h\<^sub>1 (vs'@vs) ls\<^sub>1 pc\<^sub>1 ics frs sh\<^sub>1)" + using TryCatch\<^sub>1.prems nsub_RI_Jcc_pieces by auto + then obtain pc\<^sub>1 vs' where + pc\<^sub>1_in_e\<^sub>1: "pc \ pc\<^sub>1" "pc\<^sub>1 < ?pc\<^sub>1" and + pc\<^sub>1_not_caught: "\ caught P pc\<^sub>1 h\<^sub>1 a (compxE\<^sub>2 e\<^sub>1 pc (size vs))" and + 0: "P \ ?\\<^sub>0 -jvm\ handle P C M a h\<^sub>1 (vs'@vs) ls\<^sub>1 pc\<^sub>1 ics frs sh\<^sub>1" by iprover + from beforex obtain xt\<^sub>0 xt\<^sub>1 + where ex_tab: "ex_table_of P C M = xt\<^sub>0 @ ?xt @ xt\<^sub>1" + and disj: "pcs xt\<^sub>0 \ I = {}" by(auto simp:beforex_def) + have hp: "h\<^sub>1 a = Some (D, fs)" "P\<^sub>1 \ D \\<^sup>* Ci" by fact+ + have "pc\<^sub>1 \ pcs xt\<^sub>0" using pc\<^sub>1_in_e\<^sub>1 I disj by auto + with pc\<^sub>1_in_e\<^sub>1 pc\<^sub>1_not_caught hp + show ?thesis using ex_tab 0 ics by(simp add:handle_def matches_ex_entry_def) + qed + also have "P \ \ -jvm\ ?\\<^sub>1" using TryCatch\<^sub>1 by auto + finally have 1: "P \ ?\\<^sub>0 -jvm\ ?\\<^sub>1" . + let ?pc\<^sub>2 = "?pc\<^sub>1' + length(compE\<^sub>2 e\<^sub>2)" + let ?I\<^sub>2 = "{?pc\<^sub>1' ..< ?pc\<^sub>2}" + have "P,C,M \ compxE\<^sub>2 ?e pc (size vs) / I,size vs" by fact + hence beforex\<^sub>2: "P,C,M \ compxE\<^sub>2 e\<^sub>2 ?pc\<^sub>1' (size vs) / ?I\<^sub>2, size vs" + using I pcs_subset[of _ ?pc\<^sub>1'] by(auto elim!:beforex_appendD2) + have IH\<^sub>2: "PROP ?P e\<^sub>2 h\<^sub>1 ?ls\<^sub>1 sh\<^sub>1 e\<^sub>2' h\<^sub>2 ls\<^sub>2 sh\<^sub>2 E C M ?pc\<^sub>1' ics v xa vs frs ?I\<^sub>2" by fact + show ?case (is "?Norm \ ?Err") + proof + show ?Norm (is "?val \ ?trans") + proof + assume val: ?val + note 1 also have "P \ ?\\<^sub>1 -jvm\ (None,h\<^sub>2,(v#vs,ls\<^sub>2,C,M,?pc\<^sub>2,ics)#frs,sh\<^sub>2)" + using val beforex\<^sub>2 IH\<^sub>2 TryCatch\<^sub>1.prems nsub_RI_Jcc_pieces by auto + finally show ?trans by(simp add:add.assoc) + qed + next + show ?Err (is "?throw \ ?err") + proof + assume throw: ?throw + then obtain pc\<^sub>2 vs' where + pc\<^sub>2: "?pc\<^sub>1+2 \ pc\<^sub>2 \ pc\<^sub>2 < ?pc\<^sub>2 \ + \ caught P pc\<^sub>2 h\<^sub>2 xa (compxE\<^sub>2 e\<^sub>2 ?pc\<^sub>1' (size vs))" and + 2: "P \ ?\\<^sub>1 -jvm\ handle P C M xa h\<^sub>2 (vs'@vs) ls\<^sub>2 pc\<^sub>2 ics frs sh\<^sub>2" + using IH\<^sub>2 beforex\<^sub>2 TryCatch\<^sub>1.prems nsub_RI_Jcc_pieces by auto + show ?err using pc\<^sub>2 jvm_trans[OF 1 2] + by (simp add:match_ex_entry) (auto intro: exI[where x=pc\<^sub>2]) + qed + qed +next + case (TryThrow\<^sub>1 e\<^sub>1 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 a h\<^sub>1 ls\<^sub>1 sh\<^sub>1 D fs Ci i e\<^sub>2) + let ?\\<^sub>0 = "(None,h\<^sub>0,(vs,ls\<^sub>0,C,M,pc,ics)#frs,sh\<^sub>0)" + let ?pc\<^sub>1 = "pc + length(compE\<^sub>2 e\<^sub>1)" + let ?e = "try e\<^sub>1 catch(Ci i) e\<^sub>2" + let ?xt = "compxE\<^sub>2 ?e pc (size vs)" + have I: "{pc..2 (try e\<^sub>1 catch(Ci i) e\<^sub>2))} \ I" + and beforex: "P,C,M \ ?xt/I,size vs" using TryThrow\<^sub>1.prems by simp+ + have "PROP ?P e\<^sub>1 h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (Throw a) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 E C M pc ics v a vs frs + {pc..2 e\<^sub>1)}" by fact + moreover have "P,C,M \ compxE\<^sub>2 e\<^sub>1 pc (size vs)/{pc..1},size vs" + using beforex I pcs_subset by(force elim!: beforex_appendD1) + ultimately have + "\pc\<^sub>1. pc \ pc\<^sub>1 \ pc\<^sub>1 < ?pc\<^sub>1 \ + \ caught P pc\<^sub>1 h\<^sub>1 a (compxE\<^sub>2 e\<^sub>1 pc (size vs)) \ + (\vs'. P \ ?\\<^sub>0 -jvm\ handle P C M a h\<^sub>1 (vs'@vs) ls\<^sub>1 pc\<^sub>1 ics frs sh\<^sub>1)" + using TryThrow\<^sub>1.prems nsub_RI_Jcc_pieces by auto + then obtain pc\<^sub>1 vs' where + pc\<^sub>1_in_e\<^sub>1: "pc \ pc\<^sub>1" "pc\<^sub>1 < ?pc\<^sub>1" and + pc\<^sub>1_not_caught: "\ caught P pc\<^sub>1 h\<^sub>1 a (compxE\<^sub>2 e\<^sub>1 pc (size vs))" and + 0: "P \ ?\\<^sub>0 -jvm\ handle P C M a h\<^sub>1 (vs'@vs) ls\<^sub>1 pc\<^sub>1 ics frs sh\<^sub>1" by iprover + show ?case (is "?N \ (?eq \ ?err)") + proof + show ?N by simp + next + { assume ?eq + with TryThrow\<^sub>1 pc\<^sub>1_in_e\<^sub>1 pc\<^sub>1_not_caught 0 + have "?err" by (simp add:match_ex_entry) auto + } + thus "?eq \ ?err" by iprover + qed +next + case Nil\<^sub>1 thus ?case by simp +next + case (Cons\<^sub>1 e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 v h\<^sub>1 ls\<^sub>1 sh\<^sub>1 es fs h\<^sub>2 ls\<^sub>2 sh\<^sub>2) + let ?pc\<^sub>1 = "pc + length(compE\<^sub>2 e)" + let ?\\<^sub>0 = "(None,h\<^sub>0,(vs,ls\<^sub>0,C,M,pc,ics)#frs,sh\<^sub>0)" + let ?\\<^sub>1 = "(None,h\<^sub>1,(v#vs,ls\<^sub>1,C,M,?pc\<^sub>1,ics)#frs,sh\<^sub>1)" + have IH: "PROP ?P e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 (Val v) h\<^sub>1 ls\<^sub>1 sh\<^sub>1 [] C M pc ics v xa vs frs + (I - pcs (compxEs\<^sub>2 es ?pc\<^sub>1 (Suc (length vs))))" by fact + then have 1: "P \ ?\\<^sub>0 -jvm\ ?\\<^sub>1" using Jcc_pieces_Cons[OF _ Cons\<^sub>1.prems(1-5)] by auto + let ?pc\<^sub>2 = "?pc\<^sub>1 + length(compEs\<^sub>2 es)" + have IHs: "PROP ?Ps es h\<^sub>1 ls\<^sub>1 sh\<^sub>1 fs h\<^sub>2 ls\<^sub>2 sh\<^sub>2 C M ?pc\<^sub>1 ics (tl ws) xa es' (v#vs) frs + (I - pcs (compxE\<^sub>2 e pc (length vs)))" by fact + show ?case (is "?Norm \ ?Err") + proof + show ?Norm (is "?val \ ?trans") + proof + assume val: ?val + note 1 + also have "P \ ?\\<^sub>1 -jvm\ (None,h\<^sub>2,(rev(ws) @ vs,ls\<^sub>2,C,M,?pc\<^sub>2,ics)#frs,sh\<^sub>2)" + using val IHs Cons\<^sub>1.prems by fastforce + finally show ?trans by(simp add:add.assoc) + qed + next + show ?Err (is "?throw \ (\pc\<^sub>2. ?H pc\<^sub>2)") + proof + assume throw: ?throw + then obtain pc\<^sub>2 vs' where + pc\<^sub>2: "?pc\<^sub>1 \ pc\<^sub>2 \ pc\<^sub>2 < ?pc\<^sub>2 \ + \ caught P pc\<^sub>2 h\<^sub>2 xa (compxEs\<^sub>2 es ?pc\<^sub>1 (size vs + 1))" and + 2: "P \ ?\\<^sub>1 -jvm\ handle P C M xa h\<^sub>2 (vs'@v#vs) ls\<^sub>2 pc\<^sub>2 ics frs sh\<^sub>2" + using IHs Cons\<^sub>1.prems by(fastforce simp:Cons_eq_append_conv neq_Nil_conv) + have "?H pc\<^sub>2" using Cons\<^sub>1.prems pc\<^sub>2 jvm_trans[OF 1 2] by(auto intro!: exI[where x="vs'@[v]"]) + thus "\pc\<^sub>2. ?H pc\<^sub>2" by iprover + qed + qed +next + case (ConsThrow\<^sub>1 e h\<^sub>0 ls\<^sub>0 sh\<^sub>0 a h\<^sub>1 ls\<^sub>1 sh\<^sub>1 es) + then show ?case using Jcc_pieces_Cons[OF _ ConsThrow\<^sub>1.prems(1-5)] + by (fastforce simp:Cons_eq_append_conv) +next + case InitFinal\<^sub>1 then show ?case using eval\<^sub>1_final_same[OF InitFinal\<^sub>1.hyps(1)] by clarsimp +next + case (InitNone\<^sub>1 sh C\<^sub>0 C' Cs e h l e' h' l' sh') + then obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h vs l pc ics frs sh I h' l' sh' v xa + (INIT C' (C\<^sub>0 # Cs,False) \ e) + = (True, frs', (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), err)" + using InitNone\<^sub>1.prems(1) by clarsimp + let ?sh = "(sh(C\<^sub>0 \ (sblank P\<^sub>1 C\<^sub>0, Prepared)))" + obtain ics: "ics_of(hd frs') = Calling C\<^sub>0 Cs" + and frs\<^sub>1: "frs' \ Nil" using pcs by clarsimp + then have 1: "P \ (None,h,frs',sh) -jvm\ (None,h,frs',?sh)" + using InitNone\<^sub>1 jvm_InitNone[where P = P] by(cases frs', simp+) + show ?case (is "(?e1 \ ?jvm1) \ (?e2 \ ?err)") + proof(rule conjI) + { assume val: ?e1 + note 1 + also have "P \ (None,h,frs',?sh) -jvm\ (None,h',(vs,l,C,M,pc,Called [])#frs,sh')" + using InitNone\<^sub>1.hyps(3)[of E] Jcc_pieces_InitNone[OF assms(1) pcs] InitNone\<^sub>1.prems val + by clarsimp + finally have ?jvm1 using pcs by simp + } + thus "?e1 \ ?jvm1" by simp + next + { assume throw: ?e2 + note 1 + also obtain vs' where "P \ (None,h,frs',?sh) + -jvm\ handle P C M xa h' (vs'@vs) l pc ics frs sh'" + using InitNone\<^sub>1.hyps(3)[of E] Jcc_pieces_InitNone[OF assms(1) pcs] throw + by clarsimp presburger + finally have ?err using pcs by auto + } + thus "?e2 \ ?err" by simp + qed +next + case (InitDone\<^sub>1 sh C\<^sub>0 sfs C' Cs e h l e' h' l' sh') + then obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h vs l pc ics frs sh I h' l' sh' v xa + (INIT C' (C\<^sub>0 # Cs,False) \ e) + = (True, frs', (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), err)" + using InitDone\<^sub>1.prems(1) by clarsimp + let ?frs' = "(calling_to_scalled (hd frs'))#(tl frs')" + have IH: "PROP ?P (INIT C' (Cs,True) \ e) h l sh e' h' l' sh' E C M pc ics v xa vs frs I" + by fact + obtain ics: "ics_of(hd frs') = Calling C\<^sub>0 Cs" + and frs\<^sub>1: "frs' \ Nil" using pcs by clarsimp + then have 1: "P \ (None,h,frs',sh) -jvm\ (None,h,?frs',sh)" + using InitDone\<^sub>1 jvm_InitDP[where P = P] by(cases frs', simp+) + show ?case (is "(?e1 \ ?jvm1) \ (?e2 \ ?err)") + proof(rule conjI) + { assume val: ?e1 + note 1 + also have "P \ (None,h,?frs',sh) -jvm\ (None,h',(vs,l,C,M,pc,Called [])#frs,sh')" + using IH Jcc_pieces_InitDP[OF assms(1) pcs] InitDone\<^sub>1.prems val by clarsimp + finally have ?jvm1 using pcs by simp + } + thus "?e1 \ ?jvm1" by simp + next + { assume throw: ?e2 + note 1 + also obtain vs' where "P \ (None,h,?frs',sh) + -jvm\ handle P C M xa h' (vs'@vs) l pc ics frs sh'" + using IH Jcc_pieces_InitDP[OF assms(1) pcs] InitDone\<^sub>1.prems throw by clarsimp + finally have ?err using pcs by auto + } + thus "?e2 \ ?err" by simp + qed +next + case (InitProcessing\<^sub>1 sh C\<^sub>0 sfs C' Cs e h l e' h' l' sh') + then obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h vs l pc ics frs sh I h' l' sh' v xa + (INIT C' (C\<^sub>0 # Cs,False) \ e) + = (True, frs', (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), err)" + using InitProcessing\<^sub>1.prems(1) by clarsimp + let ?frs' = "(calling_to_scalled (hd frs'))#(tl frs')" + have IH: "PROP ?P (INIT C' (Cs,True) \ e) h l sh e' h' l' sh' E C M pc ics v xa vs frs I" + by fact + obtain ics: "ics_of(hd frs') = Calling C\<^sub>0 Cs" + and frs\<^sub>1: "frs' \ Nil" using pcs by clarsimp + then have 1: "P \ (None,h,frs',sh) -jvm\ (None,h,?frs',sh)" + using InitProcessing\<^sub>1 jvm_InitDP[where P = P] by(cases frs', simp+) + show ?case (is "(?e1 \ ?jvm1) \ (?e2 \ ?err)") + proof(rule conjI) + { assume val: ?e1 + note 1 + also have "P \ (None,h,?frs',sh) -jvm\ (None,h',(vs,l,C,M,pc,Called [])#frs,sh')" + using IH Jcc_pieces_InitDP[OF assms(1) pcs] InitProcessing\<^sub>1.prems val by clarsimp + finally have ?jvm1 using pcs by simp + } + thus "?e1 \ ?jvm1" by simp + next + { assume throw: ?e2 + note 1 + also obtain vs' where "P \ (None,h,?frs',sh) + -jvm\ handle P C M xa h' (vs'@vs) l pc ics frs sh'" + using IH Jcc_pieces_InitDP[OF assms(1) pcs] InitProcessing\<^sub>1.prems throw by clarsimp + finally have ?err using pcs by auto + } + thus "?e2 \ ?err" by simp + qed +next + case (InitError\<^sub>1 sh C\<^sub>0 sfs Cs e h l e' h' l' sh' C') + then obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h vs l pc ics frs sh I h' l' sh' v xa + (INIT C' (C\<^sub>0 # Cs,False) \ e) + = (True, frs', (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), err)" + using InitError\<^sub>1.prems(1) by clarsimp + let ?e\<^sub>0 = "THROW NoClassDefFoundError" + let ?frs' = "(calling_to_sthrowing (hd frs') (addr_of_sys_xcpt NoClassDefFoundError))#(tl frs')" + have IH: "PROP ?P (RI (C\<^sub>0,?e\<^sub>0) ; Cs \ e) h l sh e' h' l' sh' E C M pc ics v xa vs frs I" by fact + obtain ics: "ics_of(hd frs') = Calling C\<^sub>0 Cs" + and frs\<^sub>1: "frs' \ Nil" + and tl: "tl frs' = frs" using pcs by clarsimp + then have 1: "P \ (None,h,frs',sh) -jvm\ (None,h,?frs',sh)" + proof(cases frs') + case (Cons a list) + obtain vs' l' C' M' pc' ics' where a: "a = (vs',l',C',M',pc',ics')" by(cases a) + then have "ics' = Calling C\<^sub>0 Cs" using Cons ics by simp + then show ?thesis + using Cons a IH InitError\<^sub>1.prems jvm_InitError[where P = P] InitError\<^sub>1.hyps(1) by simp + qed(simp) + show ?case (is "(?e1 \ ?jvm1) \ (?e2 \ ?err)") + proof(rule conjI) + { assume val: ?e1 + then have False using val rinit\<^sub>1_throw[OF InitError\<^sub>1.hyps(2)] by blast + then have ?jvm1 using pcs by simp + } + thus "?e1 \ ?jvm1" by simp + next + { assume throw: ?e2 + let ?frs = "(calling_to_throwing (hd frs') (addr_of_sys_xcpt NoClassDefFoundError))#(tl frs')" + have exec: "exec (P, (None,h,?frs,sh)) = Some (None,h,?frs',sh)" + using exec_ErrorThrowing[where sh=sh, OF InitError\<^sub>1.hyps(1)] ics by(cases "hd frs'", simp) + obtain vs' where 2: "P \ (None,h,?frs,sh) -jvm\ handle P C M xa h' (vs'@vs) l pc ics frs sh'" + using IH Jcc_pieces_InitError[OF assms(1) pcs InitError\<^sub>1.hyps(1)] throw by clarsimp + have neq: "(None, h, ?frs, sh) \ handle P C M xa h' (vs' @ vs) l pc ics frs sh'" + using tl ics by(cases "hd frs'", simp add: handle_frs_tl_neq) + + note 1 + also have "P \ (None,h,?frs',sh) -jvm\ handle P C M xa h' (vs'@vs) l pc ics frs sh'" + using exec_1_exec_all_conf[OF exec 2] neq by simp + finally have ?err using pcs by auto + } + thus "?e2 \ ?err" by simp + qed +next + case (InitObject\<^sub>1 sh C\<^sub>0 sfs sh' C' Cs e h l e' h' l' sh'') + then obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h vs l pc ics frs sh I h' l' + (sh(C\<^sub>0 \ (sfs, Processing))) v xa (INIT C' (C\<^sub>0 # Cs,False) \ e) + = (True, frs', (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), err)" + using InitObject\<^sub>1.prems(1) by clarsimp + let ?frs' = "(calling_to_called (hd frs'))#(tl frs')" + have IH: "PROP ?P (INIT C' (C\<^sub>0#Cs,True) \ e) h l sh' e' h' l' sh'' E C M pc ics v xa vs frs I" + by fact + obtain ics: "ics_of(hd frs') = Calling C\<^sub>0 Cs" + and frs\<^sub>1: "frs' \ Nil" using pcs by clarsimp + then have 1: "P \ (None,h,frs',sh) -jvm\ (None,h,?frs',sh')" + proof(cases frs') + case (Cons a list) + obtain vs' l' C' M' pc' ics' where a: "a = (vs',l',C',M',pc',ics')" by(cases a) + then have "ics' = Calling C\<^sub>0 Cs" using Cons ics by simp + then show ?thesis + using Cons Nil a IH InitObject\<^sub>1 jvm_InitObj[where P = P] by simp + qed(simp) + show ?case (is "(?e1 \ ?jvm1) \ (?e2 \ ?err)") + proof(rule conjI) + { assume val: ?e1 + note 1 + also have "P \ (None,h,?frs',sh') -jvm\ (None,h',(vs,l,C,M,pc,Called [])#frs,sh'')" + using IH Jcc_pieces_InitObj[OF assms(1) pcs] InitObject\<^sub>1 val by simp + finally have ?jvm1 using pcs by simp + } + thus "?e1 \ ?jvm1" by simp + next + { assume throw: ?e2 + note 1 + also obtain vs' where "P \ (None,h,?frs',sh') + -jvm\ handle P C M xa h' (vs'@vs) l pc ics frs sh''" + using IH Jcc_pieces_InitObj[OF assms(1) pcs] InitObject\<^sub>1 throw by clarsimp + finally have ?err using pcs by auto + } + thus "?e2 \ ?err" by simp + qed +next + case (InitNonObject\<^sub>1 sh C\<^sub>0 sfs D a b sh' C' Cs e h l e' h' l' sh'') + then obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h vs l pc ics frs sh I h' l' + (sh(C\<^sub>0 \ (sfs,Processing))) v xa (INIT C' (C\<^sub>0 # Cs,False) \ e) + = (True, frs', (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), err)" + using InitNonObject\<^sub>1.prems(1) by clarsimp + let ?frs' = "(calling_to_calling (hd frs') D)#(tl frs')" + have cls1: "is_class P\<^sub>1 D" using InitNonObject\<^sub>1.hyps(2,3) class_wf wf wf_cdecl_supD by blast + have cls_aux: "distinct (C\<^sub>0#Cs) \ supercls_lst P\<^sub>1 (C\<^sub>0#Cs)" using InitNonObject\<^sub>1.prems(1) by auto + then have cls2: "D \ set (C\<^sub>0 # Cs)" + proof - + have "distinct (D # C\<^sub>0 # Cs)" + using InitNonObject\<^sub>1.hyps(2,3) cls_aux wf wf_supercls_distinct_app by blast + then show "D \ set (C\<^sub>0 # Cs)" + by (metis distinct.simps(2)) + qed + have cls3: "\C\set (C\<^sub>0 # Cs). P\<^sub>1 \ C \\<^sup>* D" using InitNonObject\<^sub>1.hyps(2,3) cls_aux + by (metis r_into_rtrancl rtrancl_into_rtrancl set_ConsD subcls1.subcls1I supercls_lst.simps(1)) + have IH: "PROP ?P (INIT C' (D # C\<^sub>0 # Cs,False) \ e) h l sh' e' h' l' sh'' E C M pc ics v xa vs frs I" + by fact + obtain r where cls: "class P C\<^sub>0 = \(D, r)\" using InitNonObject\<^sub>1.hyps(3) + by (metis assms class_compP compP\<^sub>2_def) + obtain ics: "ics_of(hd frs') = Calling C\<^sub>0 Cs" + and frs\<^sub>1: "frs' \ Nil" using pcs by clarsimp + then have 1: "P \ (None,h,frs',sh) -jvm\ (None,h,?frs',sh')" + proof(cases frs') + case (Cons a list) + obtain vs' l' C' M' pc' ics' where a: "a = (vs',l',C',M',pc',ics')" by(cases a) + then have "ics' = Calling C\<^sub>0 Cs" using Cons ics by simp + then show ?thesis + using Cons a IH InitNonObject\<^sub>1 jvm_InitNonObj[OF _ _ cls] by simp + qed(simp) + show ?case (is "(?e1 \ ?jvm1) \ (?e2 \ ?err)") + proof(rule conjI) + { assume val: ?e1 + note 1 + also have "P \ (None,h,?frs',sh') -jvm\ (None,h',(vs,l,C,M,pc,Called [])#frs,sh'')" + using IH Jcc_pieces_InitNonObj[OF assms(1) cls1 cls2 cls3 pcs] InitNonObject\<^sub>1 val by simp + finally have ?jvm1 using pcs by simp + } + thus "?e1 \ ?jvm1" by simp + next + { assume throw: ?e2 + note 1 + also obtain vs' where "P \ (None,h,?frs',sh') + -jvm\ handle P C M xa h' (vs'@vs) l pc ics frs sh''" + using IH Jcc_pieces_InitNonObj[OF assms(1) cls1 cls2 cls3 pcs] InitNonObject\<^sub>1 throw by clarsimp + finally have ?err using pcs by auto + } + thus "?e2 \ ?err" by simp + qed +next + case (InitRInit\<^sub>1 C\<^sub>0 Cs e h l sh e' h' l' sh' C') + then obtain frs' err where pcs: "Jcc_pieces P\<^sub>1 E C M h vs l pc ics frs sh I h' l' sh' v xa + (INIT C' (C\<^sub>0 # Cs,True) \ e) + = (True, frs', (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), err)" + using InitRInit\<^sub>1.prems(1) by clarsimp + have IH: "PROP ?P (RI (C\<^sub>0,C\<^sub>0\\<^sub>sclinit([])) ; Cs \ e) h l sh e' h' l' sh' E C M pc ics v xa vs frs I" + by fact + show ?case (is "(?e1 \ ?jvm1) \ (?e2 \ ?err)") + proof(rule conjI) + { assume val: ?e1 + have "P \ (None,h,frs',sh) -jvm\ (None,h',(vs,l,C,M,pc,Called [])#frs,sh')" + using IH Jcc_pieces_InitRInit[OF assms(1,2) pcs] InitRInit\<^sub>1.prems val by simp + then have ?jvm1 using pcs by simp + } + thus "?e1 \ ?jvm1" by simp + next + { assume throw: ?e2 + obtain vs' where "P \ (None,h,frs',sh) + -jvm\ handle P C M xa h' (vs'@vs) l pc ics frs sh'" + using IH Jcc_pieces_InitRInit[OF assms(1,2) pcs] InitRInit\<^sub>1 throw by clarsimp + then have ?err using pcs by auto + } + thus "?e2 \ ?err" by simp + qed +next + case (RInit\<^sub>1 e h l sh v1 h' l' sh' C\<^sub>0 sfs i sh'' C' Cs e' e\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1) + let ?frs = "(vs,l,C,M,pc,Called (C\<^sub>0#Cs)) # frs" + let ?frs' = "(vs,l,C,M,pc,Called Cs) # frs" + have clinit: "e = C\<^sub>0\\<^sub>sclinit([])" using RInit\<^sub>1 + by (metis Jcc_cond.simps(2) eval\<^sub>1_final_same exp.distinct(101) final_def) + then obtain err where pcs: "Jcc_pieces P\<^sub>1 E C M h vs l pc ics frs sh I h\<^sub>1 l\<^sub>1 sh\<^sub>1 v xa + (RI (C\<^sub>0,C\<^sub>0\\<^sub>sclinit([])) ; Cs \ e') + = (True, ?frs, (None, h\<^sub>1, (vs, l, C, M, pc, Called []) # frs, sh\<^sub>1), err)" + using RInit\<^sub>1.prems(1) by simp + have shC: "\C'\set Cs. \sfs. sh C' = \(sfs, Processing)\" using RInit\<^sub>1.prems(1) clinit by clarsimp + then have shC'': "\C'\set Cs. \sfs. sh'' C' = \(sfs, Processing)\" + using clinit\<^sub>1_proc_pres[OF wf] RInit\<^sub>1.hyps(1) clinit RInit\<^sub>1.hyps(4) RInit\<^sub>1.prems(1) + by (auto simp: fun_upd_apply) + have loc: "l = l'" using clinit\<^sub>1_loc_pres RInit\<^sub>1.hyps(1) clinit by simp + have IH: "PROP ?P e h l sh (Val v1) h' l' sh' E C M pc (Called Cs) v1 xa vs (tl ?frs') I" by fact + then have IH': + "PROP ?P (C\<^sub>0\\<^sub>sclinit([])) h l sh (Val v1) h' l' sh' E C M pc (Called Cs) v1 xa vs (tl ?frs') I" + using clinit by simp + have IH2: "PROP ?P (INIT C' (Cs,True) \ e') h' l' sh'' e\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1 E C M + pc ics v xa vs frs I" by fact + have "P \ (None,h,?frs,sh) -jvm\ (None,h,create_init_frame P C\<^sub>0 # ?frs',sh)" by(rule jvm_Called) + also have "P \ \ -jvm\ (None,h',?frs',sh'')" + using IH' Jcc_pieces_RInit_clinit[OF assms(1-2) pcs,of h' l' sh'] RInit\<^sub>1.hyps(3,4) by simp + finally have jvm1: "P \ (None,h,?frs,sh) -jvm\ (None,h',?frs',sh'')" . + show ?case (is "(?e1 \ ?jvm1) \ (?e2 \ ?err)") + proof(rule conjI) + { assume val: ?e1 + note jvm1 + also have "P \ (None,h',?frs',sh'') -jvm\ (None,h\<^sub>1,(vs,l,C,M,pc,Called [])#frs,sh\<^sub>1)" + using IH2 Jcc_pieces_RInit_Init[OF assms(1-2) shC'' pcs,of h'] RInit\<^sub>1.hyps(5) loc val by auto + finally have ?jvm1 using pcs clinit by simp + } + thus "?e1 \ ?jvm1" by simp + next + { assume throw: ?e2 + note jvm1 + also obtain vs' where "P \ (None,h',?frs',sh'') + -jvm\ handle P C M xa h\<^sub>1 (vs'@vs) l pc ics frs sh\<^sub>1" + using IH2 Jcc_pieces_RInit_Init[OF assms(1-2) shC'' pcs,of h'] RInit\<^sub>1.hyps(5) loc throw by auto + finally have ?err using pcs clinit by auto + } + thus "?e2 \ ?err" by simp + qed +next + case (RInitInitFail\<^sub>1 e h l sh a h' l' sh' C\<^sub>0 sfs i sh'' D Cs e' e\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1) + let ?frs = "(vs,l,C,M,pc,Called (C\<^sub>0#D#Cs)) # frs" + let ?frs' = "(vs,l,C,M,pc,Called (D#Cs)) # frs" + let "?frsT" = "\xa1. (vs,l,C,M,pc,Throwing (C\<^sub>0#D#Cs) xa1) # frs" + let "?frsT'" = "\xa1. (vs,l,C,M,pc,Throwing (D#Cs) xa1) # frs" + obtain xa' where xa': "throw a = Throw xa'" + by (metis RInitInitFail\<^sub>1.hyps(1) eval\<^sub>1_final exp.distinct(101) final_def) + have e\<^sub>1: "e\<^sub>1 = Throw xa'" using xa' rinit\<^sub>1_throw RInitInitFail\<^sub>1.hyps(5) by simp + show ?case + proof(cases "e = C\<^sub>0\\<^sub>sclinit([])") + case clinit: True + then obtain err where pcs: "Jcc_pieces P\<^sub>1 E C M h vs l pc ics frs sh I h\<^sub>1 l\<^sub>1 sh\<^sub>1 v xa' + (RI (C\<^sub>0,C\<^sub>0\\<^sub>sclinit([])) ; D # Cs \ e') + = (True, ?frs, (None, h\<^sub>1, (vs, l, C, M, pc, Called []) # frs, sh\<^sub>1), err)" + using RInitInitFail\<^sub>1.prems(1) by simp + have loc: "l = l'" using clinit\<^sub>1_loc_pres RInitInitFail\<^sub>1.hyps(1) clinit by simp + have IH: "PROP ?P e h l sh (throw a) h' l' sh' E C M pc (Called (D#Cs)) v xa' vs frs I" + by fact + then have IH': + "PROP ?P (C\<^sub>0\\<^sub>sclinit([])) h l sh (Throw xa') h' l' sh' E C M pc (Called (D#Cs)) v xa' vs + frs I" using clinit xa' by simp + have IH2: "PROP ?P (RI (D,throw a) ; Cs \ e') h' l' sh'' e\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1 E C M + pc ics v xa' vs frs I" by fact + have "P \ (None,h,?frs,sh) -jvm\ (None,h,create_init_frame P C\<^sub>0 # ?frs',sh)" by(rule jvm_Called) + also have "P \ \ -jvm\ (None,h',(vs, l, C, M, pc, Throwing (D#Cs) xa') # frs,sh'')" + using IH' Jcc_pieces_RInit_clinit[OF assms(1-2) pcs,of h' l' sh'] RInitInitFail\<^sub>1.hyps(3,4) + by simp + also obtain vs'' where "P \ \ -jvm\ handle P C M xa' h\<^sub>1 (vs''@vs) l pc ics frs sh\<^sub>1" + using IH2 pcs Jcc_pieces_RInit_RInit[OF assms(1) pcs] RInitInitFail\<^sub>1.hyps(3,4) + xa' loc e\<^sub>1 xa' by clarsimp + finally show ?thesis using pcs e\<^sub>1 clinit by auto + next + case throw: False + then have eT: "e = Throw xa'" "h = h'" "l = l'" "sh = sh'" using xa' RInitInitFail\<^sub>1.prems(1) + eval\<^sub>1_final_same[OF RInitInitFail\<^sub>1.hyps(1)] by clarsimp+ + obtain a' where "class P\<^sub>1 C\<^sub>0 = \a'\" using RInitInitFail\<^sub>1.prems by(auto simp: is_class_def) + then obtain stk' loc' M' pc' ics' where "create_init_frame P C\<^sub>0 = (stk',loc',C\<^sub>0,M',pc',ics')" + using create_init_frame_wf_eq[OF wf] by(cases "create_init_frame P C\<^sub>0", simp) + then obtain rhs err where pcs: "Jcc_pieces P\<^sub>1 E C M h vs l pc ics frs sh I h' l' sh'' v xa' + (RI (C\<^sub>0,e) ; D#Cs \ e') = (True, ?frsT xa', rhs, err)" + using RInitInitFail\<^sub>1.prems(1) eT by clarsimp + have IH2: "PROP ?P (RI (D,throw a) ; Cs \ e') h' l' sh'' e\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1 E C M + pc ics v xa' vs frs I" by fact + have "P \ (None,h,?frsT xa',sh') -jvm\ (None,h,?frsT' xa',sh'(C\<^sub>0 \ (fst (the (sh' C\<^sub>0)), Error)))" + by(rule jvm_Throwing) + also obtain vs' where "P \ ... -jvm\ handle P C M xa' h\<^sub>1 (vs'@vs) l pc ics frs sh\<^sub>1" + using IH2 Jcc_pieces_RInit_RInit[OF assms(1) pcs] RInitInitFail\<^sub>1.hyps(3,4) + eT e\<^sub>1 xa' by clarsimp + finally show ?thesis using pcs e\<^sub>1 throw eT by auto + qed +next + case (RInitFailFinal\<^sub>1 e h l sh a h' l' sh' C\<^sub>0 sfs i sh'' e'') + let ?frs = "(vs,l,C,M,pc,Called [C\<^sub>0]) # frs" + let ?frs' = "(vs,l,C,M,pc,Called []) # frs" + let "?frsT" = "\xa1. (vs,l,C,M,pc,Throwing [C\<^sub>0] xa1) # frs" + let "?frsT'" = "\xa1. (vs,l,C,M,pc,Throwing [] xa1) # frs" + obtain xa' where xa': "throw a = Throw xa'" + by (metis RInitFailFinal\<^sub>1.hyps(1) eval\<^sub>1_final exp.distinct(101) final_def) + show ?case + proof(cases "e = C\<^sub>0\\<^sub>sclinit([])") + case clinit: True + then obtain err where pcs: "Jcc_pieces P\<^sub>1 E C M h vs l pc ics frs sh I h' l' sh'' v xa' + (RI (C\<^sub>0,C\<^sub>0\\<^sub>sclinit([])) ; [] \ unit) = (True, ?frs, (None, h', ?frs', sh''), err)" + using RInitFailFinal\<^sub>1.prems(1) by clarsimp + have IH: "PROP ?P e h l sh (throw a) h' l' sh' E C M pc (Called []) v xa' vs frs I" by fact + then have IH': + "PROP ?P (C\<^sub>0\\<^sub>sclinit([])) h l sh (throw a) h' l' sh' E C M pc (Called []) v xa' vs frs I" + using clinit by simp + have "P \ (None,h,?frs,sh) -jvm\ (None,h,create_init_frame P C\<^sub>0 # ?frs',sh)" + by(rule jvm_Called) + also have "P \ \ -jvm\ (None,h',?frsT' xa',sh'')" + using IH' Jcc_pieces_RInit_clinit[OF assms(1-2) pcs,of h' l' sh'] xa' + RInitFailFinal\<^sub>1.hyps(3,4) by simp + also have + "P \ \ -jvm\ handle (compP compMb\<^sub>2 P\<^sub>1) C M xa' h' vs l pc No_ics frs sh''" + using RInitFailFinal\<^sub>1.hyps(3,4) jvm_RInit_throw[where h=h' and sh=sh''] by simp + finally show ?thesis using xa' pcs clinit by(clarsimp intro!: exI[where x="[]"]) + next + case throw: False + then have eT: "e = Throw xa'" "h = h'" "sh = sh'" using xa' RInitFailFinal\<^sub>1.prems(1) + eval\<^sub>1_final_same[OF RInitFailFinal\<^sub>1.hyps(1)] by clarsimp+ + obtain a where "class P\<^sub>1 C\<^sub>0 = \a\" using RInitFailFinal\<^sub>1.prems by(auto simp: is_class_def) + then obtain stk' loc' M' pc' ics' where "create_init_frame P C\<^sub>0 = (stk',loc',C\<^sub>0,M',pc',ics')" + using create_init_frame_wf_eq[OF wf] by(cases "create_init_frame P C\<^sub>0", simp) + then obtain rhs err where pcs: "Jcc_pieces P\<^sub>1 E C M h vs l pc ics frs sh I h' l' sh'' v xa' + (RI (C\<^sub>0,e) ; [] \ unit) = (True, ?frsT xa', rhs, err)" + using RInitFailFinal\<^sub>1.prems(1) eT by clarsimp + have "P \ (None,h,?frsT xa',sh) -jvm\ (None,h,?frsT' xa',sh(C\<^sub>0 \ (fst (the (sh C\<^sub>0)), Error)))" + by(rule jvm_Throwing) + also have "P \ \ -jvm\ handle P C M xa' h' vs l pc No_ics frs sh''" + using RInitFailFinal\<^sub>1.hyps(3,4) jvm_RInit_throw[where h=h and sh=sh''] eT by simp + finally show ?thesis using pcs xa' by(clarsimp intro!: exI[where x="[]"]) + qed +qed +(*>*) + +(*FIXME move! *) +lemma atLeast0AtMost[simp]: "{0::nat..n} = {..n}" +by auto + +lemma atLeast0LessThan[simp]: "{0::nat.. addr option" where + "exception (Throw a) = Some a" +| "exception e = None" + +lemma comp\<^sub>2_correct: +assumes wf: "wf_J\<^sub>1_prog P\<^sub>1" + and "method": "P\<^sub>1 \ C sees M,b:Ts\T = body in C" + and eval: "P\<^sub>1 \\<^sub>1 \body,(h,ls,sh)\ \ \e',(h',ls',sh')\" + and nclinit: "M \ clinit" +shows "compP\<^sub>2 P\<^sub>1 \ (None,h,[([],ls,C,M,0,No_ics)],sh) -jvm\ (exception e',h',[],sh')" +(*<*) + (is "_ \ ?\\<^sub>0 -jvm\ ?\\<^sub>1") +proof - + let ?P = "compP\<^sub>2 P\<^sub>1" + let ?E = "case b of Static \ Ts | NonStatic \ Class C#Ts" + have nsub: "\sub_RI body" using sees_wf\<^sub>1_nsub_RI[OF wf method] by simp + have code: "?P,C,M,0 \ compE\<^sub>2 body" using beforeM[OF "method"] by auto + have xtab: "?P,C,M \ compxE\<^sub>2 body 0 (size[])/{..2 body)},size[]" + using beforexM[OF "method"] by auto + have cond: "Jcc_cond P\<^sub>1 ?E C M [] 0 No_ics {..2 body)} h sh body" + using nsub_RI_Jcc_pieces nsub code xtab by auto + \ \Distinguish if e' is a value or an exception\ + { fix v assume [simp]: "e' = Val v" + have "?P \ ?\\<^sub>0 -jvm\ (None,h',[([v],ls',C,M,size(compE\<^sub>2 body),No_ics)],sh')" + using Jcc[OF wf eval cond] nsub_RI_Jcc_pieces[OF _ nsub] by auto + also have "?P \ \ -jvm\ ?\\<^sub>1" using beforeM[OF "method"] nclinit by auto + finally have ?thesis . + } + moreover + { fix a assume [simp]: "e' = Throw a" + obtain pc vs' where pc: "0 \ pc \ pc < size(compE\<^sub>2 body) \ + \ caught ?P pc h' a (compxE\<^sub>2 body 0 0)" + and 1: "?P \ ?\\<^sub>0 -jvm\ handle ?P C M a h' vs' ls' pc No_ics [] sh'" + using Jcc[OF wf eval cond] nsub_RI_Jcc_pieces[OF _ nsub] by auto meson + from pc have "handle ?P C M a h' vs' ls' pc No_ics [] sh' = ?\\<^sub>1" using xtab "method" nclinit + by(auto simp:handle_def compMb\<^sub>2_def) + with 1 have ?thesis by simp + } + ultimately show ?thesis using eval\<^sub>1_final[OF eval] by(auto simp:final_def) +qed +(*>*) + +end diff --git a/thys/JinjaDCI/Compiler/Hidden.thy b/thys/JinjaDCI/Compiler/Hidden.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/Compiler/Hidden.thy @@ -0,0 +1,49 @@ +theory Hidden +imports "List-Index.List_Index" +begin + +definition hidden :: "'a list \ nat \ bool" where +"hidden xs i \ i < size xs \ xs!i \ set(drop (i+1) xs)" + + +lemma hidden_last_index: "x \ set xs \ hidden (xs @ [x]) (last_index xs x)" +apply(auto simp add: hidden_def nth_append rev_nth[symmetric]) +apply(drule last_index_less[OF _ le_refl]) +apply simp +done + +lemma hidden_inacc: "hidden xs i \ last_index xs x \ i" +by(auto simp add: hidden_def last_index_drop last_index_less_size_conv) + + +lemma [simp]: "hidden xs i \ hidden (xs@[x]) i" +by(auto simp add:hidden_def nth_append) + + +lemma fun_upds_apply: + "(m(xs[\]ys)) x = + (let xs' = take (size ys) xs + in if x \ set xs' then Some(ys ! last_index xs' x) else m x)" +apply(induct xs arbitrary: m ys) + apply (simp add: Let_def) +apply(case_tac ys) + apply (simp add:Let_def) +apply (simp add: Let_def last_index_Cons) +done + + +lemma map_upds_apply_eq_Some: + "((m(xs[\]ys)) x = Some y) = + (let xs' = take (size ys) xs + in if x \ set xs' then ys ! last_index xs' x = y else m x = Some y)" +by(simp add:fun_upds_apply Let_def) + + +lemma map_upds_upd_conv_last_index: + "\x \ set xs; size xs \ size ys \ + \ m(xs[\]ys)(x\y) = m(xs[\]ys[last_index xs x := y])" +apply(rule ext) +apply(simp add:fun_upds_apply eq_sym_conv Let_def) +done + +end diff --git a/thys/JinjaDCI/Compiler/J1.thy b/thys/JinjaDCI/Compiler/J1.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/Compiler/J1.thy @@ -0,0 +1,535 @@ +(* Title: JinjaDCI/Compiler/J1.thy + Author: Tobias Nipkow, Susannah Mansky + Copyright 2003 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory Compiler/J1.thy by Tobias Nipkow +*) + +chapter \ Compilation \label{cha:comp} \ + +section \ An Intermediate Language \ + +theory J1 imports "../J/BigStep" begin + +type_synonym expr\<^sub>1 = "nat exp" +type_synonym J\<^sub>1_prog = "expr\<^sub>1 prog" +type_synonym state\<^sub>1 = "heap \ (val list) \ sheap" + +definition hp\<^sub>1 :: "state\<^sub>1 \ heap" +where + "hp\<^sub>1 \ fst" +definition lcl\<^sub>1 :: "state\<^sub>1 \ val list" +where + "lcl\<^sub>1 \ fst \ snd" +definition shp\<^sub>1 :: "state\<^sub>1 \ sheap" +where + "shp\<^sub>1 \ snd \ snd" + +(*<*) +declare hp\<^sub>1_def[simp] lcl\<^sub>1_def[simp] shp\<^sub>1_def[simp] +(*>*) + +primrec + max_vars :: "'a exp \ nat" + and max_varss :: "'a exp list \ nat" +where + "max_vars(new C) = 0" +| "max_vars(Cast C e) = max_vars e" +| "max_vars(Val v) = 0" +| "max_vars(e\<^sub>1 \bop\ e\<^sub>2) = max (max_vars e\<^sub>1) (max_vars e\<^sub>2)" +| "max_vars(Var V) = 0" +| "max_vars(V:=e) = max_vars e" +| "max_vars(e\F{D}) = max_vars e" +| "max_vars(C\\<^sub>sF{D}) = 0" +| "max_vars(FAss e\<^sub>1 F D e\<^sub>2) = max (max_vars e\<^sub>1) (max_vars e\<^sub>2)" +| "max_vars(SFAss C F D e\<^sub>2) = max_vars e\<^sub>2" +| "max_vars(e\M(es)) = max (max_vars e) (max_varss es)" +| "max_vars(C\\<^sub>sM(es)) = max_varss es" +| "max_vars({V:T; e}) = max_vars e + 1" +| "max_vars(e\<^sub>1;;e\<^sub>2) = max (max_vars e\<^sub>1) (max_vars e\<^sub>2)" +| "max_vars(if (e) e\<^sub>1 else e\<^sub>2) = + max (max_vars e) (max (max_vars e\<^sub>1) (max_vars e\<^sub>2))" +| "max_vars(while (b) e) = max (max_vars b) (max_vars e)" +| "max_vars(throw e) = max_vars e" +| "max_vars(try e\<^sub>1 catch(C V) e\<^sub>2) = max (max_vars e\<^sub>1) (max_vars e\<^sub>2 + 1)" +| "max_vars(INIT C (Cs,b) \ e) = max_vars e" +| "max_vars(RI(C,e);Cs \ e') = max (max_vars e) (max_vars e')" + +| "max_varss [] = 0" +| "max_varss (e#es) = max (max_vars e) (max_varss es)" + +inductive + eval\<^sub>1 :: "J\<^sub>1_prog \ expr\<^sub>1 \ state\<^sub>1 \ expr\<^sub>1 \ state\<^sub>1 \ bool" + ("_ \\<^sub>1 ((1\_,/_\) \/ (1\_,/_\))" [51,0,0,0,0] 81) + and evals\<^sub>1 :: "J\<^sub>1_prog \ expr\<^sub>1 list \ state\<^sub>1 \ expr\<^sub>1 list \ state\<^sub>1 \ bool" + ("_ \\<^sub>1 ((1\_,/_\) [\]/ (1\_,/_\))" [51,0,0,0,0] 81) + for P :: J\<^sub>1_prog +where + + New\<^sub>1: + "\ sh C = Some (sfs, Done); new_Addr h = Some a; + P \ C has_fields FDTs; h' = h(a\blank P C) \ + \ P \\<^sub>1 \new C,(h,l,sh)\ \ \addr a,(h',l,sh)\" +| NewFail\<^sub>1: + "\ sh C = Some (sfs, Done); new_Addr h = None \ \ + P \\<^sub>1 \new C, (h,l,sh)\ \ \THROW OutOfMemory,(h,l,sh)\" +| NewInit\<^sub>1: + "\ \sfs. sh C = Some (sfs, Done); P \\<^sub>1 \INIT C ([C],False) \ unit,(h,l,sh)\ \ \Val v',(h',l',sh')\; + new_Addr h' = Some a; P \ C has_fields FDTs; h'' = h'(a\blank P C) \ + \ P \\<^sub>1 \new C,(h,l,sh)\ \ \addr a,(h'',l',sh')\" +| NewInitOOM\<^sub>1: + "\ \sfs. sh C = Some (sfs, Done); P \\<^sub>1 \INIT C ([C],False) \ unit,(h,l,sh)\ \ \Val v',(h',l',sh')\; + new_Addr h' = None; is_class P C \ + \ P \\<^sub>1 \new C,(h,l,sh)\ \ \THROW OutOfMemory,(h',l',sh')\" +| NewInitThrow\<^sub>1: + "\ \sfs. sh C = Some (sfs, Done); P \\<^sub>1 \INIT C ([C],False) \ unit,(h,l,sh)\ \ \throw a,s'\; + is_class P C \ + \ P \\<^sub>1 \new C,(h,l,sh)\ \ \throw a,s'\" + +| Cast\<^sub>1: + "\ P \\<^sub>1 \e,s\<^sub>0\ \ \addr a,(h,l,sh)\; h a = Some(D,fs); P \ D \\<^sup>* C \ + \ P \\<^sub>1 \Cast C e,s\<^sub>0\ \ \addr a,(h,l,sh)\" +| CastNull\<^sub>1: + "P \\<^sub>1 \e,s\<^sub>0\ \ \null,s\<^sub>1\ \ + P \\<^sub>1 \Cast C e,s\<^sub>0\ \ \null,s\<^sub>1\" +| CastFail\<^sub>1: + "\ P \\<^sub>1 \e,s\<^sub>0\ \ \addr a,(h,l,sh)\; h a = Some(D,fs); \ P \ D \\<^sup>* C \ + \ P \\<^sub>1 \Cast C e,s\<^sub>0\ \ \THROW ClassCast,(h,l,sh)\" +| CastThrow\<^sub>1: + "P \\<^sub>1 \e,s\<^sub>0\ \ \throw e',s\<^sub>1\ \ + P \\<^sub>1 \Cast C e,s\<^sub>0\ \ \throw e',s\<^sub>1\" + +| Val\<^sub>1: + "P \\<^sub>1 \Val v,s\ \ \Val v,s\" + +| BinOp\<^sub>1: + "\ P \\<^sub>1 \e\<^sub>1,s\<^sub>0\ \ \Val v\<^sub>1,s\<^sub>1\; P \\<^sub>1 \e\<^sub>2,s\<^sub>1\ \ \Val v\<^sub>2,s\<^sub>2\; binop(bop,v\<^sub>1,v\<^sub>2) = Some v \ + \ P \\<^sub>1 \e\<^sub>1 \bop\ e\<^sub>2,s\<^sub>0\ \ \Val v,s\<^sub>2\" +| BinOpThrow\<^sub>1\<^sub>1: + "P \\<^sub>1 \e\<^sub>1,s\<^sub>0\ \ \throw e,s\<^sub>1\ \ + P \\<^sub>1 \e\<^sub>1 \bop\ e\<^sub>2, s\<^sub>0\ \ \throw e,s\<^sub>1\" +| BinOpThrow\<^sub>2\<^sub>1: + "\ P \\<^sub>1 \e\<^sub>1,s\<^sub>0\ \ \Val v\<^sub>1,s\<^sub>1\; P \\<^sub>1 \e\<^sub>2,s\<^sub>1\ \ \throw e,s\<^sub>2\ \ + \ P \\<^sub>1 \e\<^sub>1 \bop\ e\<^sub>2,s\<^sub>0\ \ \throw e,s\<^sub>2\" + +| Var\<^sub>1: + "\ ls!i = v; i < size ls \ \ + P \\<^sub>1 \Var i,(h,ls,sh)\ \ \Val v,(h,ls,sh)\" + +| LAss\<^sub>1: + "\ P \\<^sub>1 \e,s\<^sub>0\ \ \Val v,(h,ls,sh)\; i < size ls; ls' = ls[i := v] \ + \ P \\<^sub>1 \i:= e,s\<^sub>0\ \ \unit,(h,ls',sh)\" +| LAssThrow\<^sub>1: + "P \\<^sub>1 \e,s\<^sub>0\ \ \throw e',s\<^sub>1\ \ + P \\<^sub>1 \i:= e,s\<^sub>0\ \ \throw e',s\<^sub>1\" + +| FAcc\<^sub>1: + "\ P \\<^sub>1 \e,s\<^sub>0\ \ \addr a,(h,ls,sh)\; h a = Some(C,fs); + P \ C has F,NonStatic:t in D; + fs(F,D) = Some v \ + \ P \\<^sub>1 \e\F{D},s\<^sub>0\ \ \Val v,(h,ls,sh)\" +| FAccNull\<^sub>1: + "P \\<^sub>1 \e,s\<^sub>0\ \ \null,s\<^sub>1\ \ + P \\<^sub>1 \e\F{D},s\<^sub>0\ \ \THROW NullPointer,s\<^sub>1\" +| FAccThrow\<^sub>1: + "P \\<^sub>1 \e,s\<^sub>0\ \ \throw e',s\<^sub>1\ \ + P \\<^sub>1 \e\F{D},s\<^sub>0\ \ \throw e',s\<^sub>1\" +| FAccNone\<^sub>1: + "\ P \\<^sub>1 \e,s\<^sub>0\ \ \addr a,(h,ls,sh)\; h a = Some(C,fs); + \(\b t. P \ C has F,b:t in D) \ + \ P \\<^sub>1 \e\F{D},s\<^sub>0\ \ \THROW NoSuchFieldError,(h,ls,sh)\" +| FAccStatic\<^sub>1: + "\ P \\<^sub>1 \e,s\<^sub>0\ \ \addr a,(h,ls,sh)\; h a = Some(C,fs); + P \ C has F,Static:t in D \ + \ P \\<^sub>1 \e\F{D},s\<^sub>0\ \ \THROW IncompatibleClassChangeError,(h,ls,sh)\" + +| SFAcc\<^sub>1: + "\ P \ C has F,Static:t in D; + sh D = Some (sfs,Done); + sfs F = Some v \ + \ P \\<^sub>1 \C\\<^sub>sF{D},(h,ls,sh)\ \ \Val v,(h,ls,sh)\" +| SFAccInit\<^sub>1: + "\ P \ C has F,Static:t in D; + \sfs. sh D = Some (sfs,Done); P \\<^sub>1 \INIT D ([D],False) \ unit,(h,ls,sh)\ \ \Val v',(h',ls',sh')\; + sh' D = Some (sfs,i); + sfs F = Some v \ + \ P \\<^sub>1 \C\\<^sub>sF{D},(h,ls,sh)\ \ \Val v,(h',ls',sh')\" +| SFAccInitThrow\<^sub>1: + "\ P \ C has F,Static:t in D; + \sfs. sh D = Some (sfs,Done); P \\<^sub>1 \INIT D ([D],False) \ unit,(h,ls,sh)\ \ \throw a,s'\ \ + \ P \\<^sub>1 \C\\<^sub>sF{D},(h,ls,sh)\ \ \throw a,s'\" +| SFAccNone\<^sub>1: + "\ \(\b t. P \ C has F,b:t in D) \ + \ P \\<^sub>1 \C\\<^sub>sF{D},s\ \ \THROW NoSuchFieldError,s\" +| SFAccNonStatic\<^sub>1: + "\ P \ C has F,NonStatic:t in D \ + \ P \\<^sub>1 \C\\<^sub>sF{D},s\ \ \THROW IncompatibleClassChangeError,s\" + + +| FAss\<^sub>1: + "\ P \\<^sub>1 \e\<^sub>1,s\<^sub>0\ \ \addr a,s\<^sub>1\; P \\<^sub>1 \e\<^sub>2,s\<^sub>1\ \ \Val v,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\; + h\<^sub>2 a = Some(C,fs); P \ C has F,NonStatic:t in D; + fs' = fs((F,D)\v); h\<^sub>2' = h\<^sub>2(a\(C,fs')) \ + \ P \\<^sub>1 \e\<^sub>1\F{D}:=e\<^sub>2,s\<^sub>0\ \ \unit,(h\<^sub>2',l\<^sub>2,sh\<^sub>2)\" +| FAssNull\<^sub>1: + "\ P \\<^sub>1 \e\<^sub>1,s\<^sub>0\ \ \null,s\<^sub>1\; P \\<^sub>1 \e\<^sub>2,s\<^sub>1\ \ \Val v,s\<^sub>2\ \ \ + P \\<^sub>1 \e\<^sub>1\F{D}:=e\<^sub>2,s\<^sub>0\ \ \THROW NullPointer,s\<^sub>2\" +| FAssThrow\<^sub>1\<^sub>1: + "P \\<^sub>1 \e\<^sub>1,s\<^sub>0\ \ \throw e',s\<^sub>1\ \ + P \\<^sub>1 \e\<^sub>1\F{D}:=e\<^sub>2,s\<^sub>0\ \ \throw e',s\<^sub>1\" +| FAssThrow\<^sub>2\<^sub>1: + "\ P \\<^sub>1 \e\<^sub>1,s\<^sub>0\ \ \Val v,s\<^sub>1\; P \\<^sub>1 \e\<^sub>2,s\<^sub>1\ \ \throw e',s\<^sub>2\ \ + \ P \\<^sub>1 \e\<^sub>1\F{D}:=e\<^sub>2,s\<^sub>0\ \ \throw e',s\<^sub>2\" +| FAssNone\<^sub>1: + "\ P \\<^sub>1 \e\<^sub>1,s\<^sub>0\ \ \addr a,s\<^sub>1\; P \\<^sub>1 \e\<^sub>2,s\<^sub>1\ \ \Val v,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\; + h\<^sub>2 a = Some(C,fs); \(\b t. P \ C has F,b:t in D) \ + \ P \\<^sub>1 \e\<^sub>1\F{D}:=e\<^sub>2,s\<^sub>0\ \ \THROW NoSuchFieldError,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\" +| FAssStatic\<^sub>1: + "\ P \\<^sub>1 \e\<^sub>1,s\<^sub>0\ \ \addr a,s\<^sub>1\; P \\<^sub>1 \e\<^sub>2,s\<^sub>1\ \ \Val v,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\; + h\<^sub>2 a = Some(C,fs); P \ C has F,Static:t in D \ + \ P \\<^sub>1 \e\<^sub>1\F{D}:=e\<^sub>2,s\<^sub>0\ \ \THROW IncompatibleClassChangeError,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\" + +| SFAss\<^sub>1: + "\ P \\<^sub>1 \e\<^sub>2,s\<^sub>0\ \ \Val v,(h\<^sub>1,l\<^sub>1,sh\<^sub>1)\; + P \ C has F,Static:t in D; + sh\<^sub>1 D = Some(sfs,Done); sfs' = sfs(F\v); sh\<^sub>1' = sh\<^sub>1(D\(sfs',Done)) \ + \ P \\<^sub>1 \C\\<^sub>sF{D}:=e\<^sub>2,s\<^sub>0\ \ \unit,(h\<^sub>1,l\<^sub>1,sh\<^sub>1')\" +| SFAssInit\<^sub>1: + "\ P \\<^sub>1 \e\<^sub>2,s\<^sub>0\ \ \Val v,(h\<^sub>1,l\<^sub>1,sh\<^sub>1)\; + P \ C has F,Static:t in D; + \sfs. sh\<^sub>1 D = Some(sfs,Done); P \\<^sub>1 \INIT D ([D],False) \ unit,(h\<^sub>1,l\<^sub>1,sh\<^sub>1)\ \ \Val v',(h',l',sh')\; + sh' D = Some(sfs,i); + sfs' = sfs(F\v); sh'' = sh'(D\(sfs',i)) \ + \ P \\<^sub>1 \C\\<^sub>sF{D}:=e\<^sub>2,s\<^sub>0\ \ \unit,(h',l',sh'')\" +| SFAssInitThrow\<^sub>1: + "\ P \\<^sub>1 \e\<^sub>2,s\<^sub>0\ \ \Val v,(h\<^sub>1,l\<^sub>1,sh\<^sub>1)\; + P \ C has F,Static:t in D; + \sfs. sh\<^sub>1 D = Some(sfs,Done); P \\<^sub>1 \INIT D ([D],False) \ unit,(h\<^sub>1,l\<^sub>1,sh\<^sub>1)\ \ \throw a,s'\ \ + \ P \\<^sub>1 \C\\<^sub>sF{D}:=e\<^sub>2,s\<^sub>0\ \ \throw a,s'\" +| SFAssThrow\<^sub>1: + "P \\<^sub>1 \e\<^sub>2,s\<^sub>0\ \ \throw e',s\<^sub>2\ + \ P \\<^sub>1 \C\\<^sub>sF{D}:=e\<^sub>2,s\<^sub>0\ \ \throw e',s\<^sub>2\" +| SFAssNone\<^sub>1: + "\ P \\<^sub>1 \e\<^sub>2,s\<^sub>0\ \ \Val v,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\; + \(\b t. P \ C has F,b:t in D) \ + \ P \\<^sub>1 \C\\<^sub>sF{D}:=e\<^sub>2,s\<^sub>0\ \ \THROW NoSuchFieldError,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\" +| SFAssNonStatic\<^sub>1: + "\ P \\<^sub>1 \e\<^sub>2,s\<^sub>0\ \ \Val v,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\; + P \ C has F,NonStatic:t in D \ + \ P \\<^sub>1 \C\\<^sub>sF{D}:=e\<^sub>2,s\<^sub>0\ \ \THROW IncompatibleClassChangeError,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\" + +| CallObjThrow\<^sub>1: + "P \\<^sub>1 \e,s\<^sub>0\ \ \throw e',s\<^sub>1\ \ + P \\<^sub>1 \e\M(es),s\<^sub>0\ \ \throw e',s\<^sub>1\" +| CallNull\<^sub>1: + "\ P \\<^sub>1 \e,s\<^sub>0\ \ \null,s\<^sub>1\; P \\<^sub>1 \es,s\<^sub>1\ [\] \map Val vs,s\<^sub>2\ \ + \ P \\<^sub>1 \e\M(es),s\<^sub>0\ \ \THROW NullPointer,s\<^sub>2\" +| Call\<^sub>1: + "\ P \\<^sub>1 \e,s\<^sub>0\ \ \addr a,s\<^sub>1\; P \\<^sub>1 \es,s\<^sub>1\ [\] \map Val vs,(h\<^sub>2,ls\<^sub>2,sh\<^sub>2)\; + h\<^sub>2 a = Some(C,fs); P \ C sees M,NonStatic:Ts\T = body in D; + size vs = size Ts; ls\<^sub>2' = (Addr a) # vs @ replicate (max_vars body) undefined; + P \\<^sub>1 \body,(h\<^sub>2,ls\<^sub>2',sh\<^sub>2)\ \ \e',(h\<^sub>3,ls\<^sub>3,sh\<^sub>3)\ \ + \ P \\<^sub>1 \e\M(es),s\<^sub>0\ \ \e',(h\<^sub>3,ls\<^sub>2,sh\<^sub>3)\" +| CallParamsThrow\<^sub>1: + "\ P \\<^sub>1 \e,s\<^sub>0\ \ \Val v,s\<^sub>1\; P \\<^sub>1 \es,s\<^sub>1\ [\] \es',s\<^sub>2\; + es' = map Val vs @ throw ex # es\<^sub>2 \ + \ P \\<^sub>1 \e\M(es),s\<^sub>0\ \ \throw ex,s\<^sub>2\" +| CallNone\<^sub>1: + "\ P \\<^sub>1 \e,s\<^sub>0\ \ \addr a,s\<^sub>1\; P \\<^sub>1 \ps,s\<^sub>1\ [\] \map Val vs,(h\<^sub>2,ls\<^sub>2,sh\<^sub>2)\; + h\<^sub>2 a = Some(C,fs); \(\b Ts T body D. P \ C sees M,b:Ts\T = body in D) \ + \ P \\<^sub>1 \e\M(ps),s\<^sub>0\ \ \THROW NoSuchMethodError,(h\<^sub>2,ls\<^sub>2,sh\<^sub>2)\" +| CallStatic\<^sub>1: + "\ P \\<^sub>1 \e,s\<^sub>0\ \ \addr a,s\<^sub>1\; P \\<^sub>1 \ps,s\<^sub>1\ [\] \map Val vs,(h\<^sub>2,ls\<^sub>2,sh\<^sub>2)\; + h\<^sub>2 a = Some(C,fs); P \ C sees M,Static:Ts\T = body in D \ + \ P \\<^sub>1 \e\M(ps),s\<^sub>0\ \ \THROW IncompatibleClassChangeError,(h\<^sub>2,ls\<^sub>2,sh\<^sub>2)\" + +| SCallParamsThrow\<^sub>1: + "\ P \\<^sub>1 \es,s\<^sub>0\ [\] \es',s\<^sub>2\; es' = map Val vs @ throw ex # es\<^sub>2 \ + \ P \\<^sub>1 \C\\<^sub>sM(es),s\<^sub>0\ \ \throw ex,s\<^sub>2\" +| SCallNone\<^sub>1: + "\ P \\<^sub>1 \ps,s\<^sub>0\ [\] \map Val vs,s\<^sub>2\; + \(\b Ts T body D. P \ C sees M,b:Ts\T = body in D) \ + \ P \\<^sub>1 \C\\<^sub>sM(ps),s\<^sub>0\ \ \THROW NoSuchMethodError,s\<^sub>2\" +| SCallNonStatic\<^sub>1: + "\ P \\<^sub>1 \ps,s\<^sub>0\ [\] \map Val vs,s\<^sub>2\; + P \ C sees M,NonStatic:Ts\T = body in D \ + \ P \\<^sub>1 \C\\<^sub>sM(ps),s\<^sub>0\ \ \THROW IncompatibleClassChangeError,s\<^sub>2\" +| SCallInitThrow\<^sub>1: + "\ P \\<^sub>1 \ps,s\<^sub>0\ [\] \map Val vs,(h\<^sub>1,ls\<^sub>1,sh\<^sub>1)\; + P \ C sees M,Static:Ts\T = body in D; + \sfs. sh\<^sub>1 D = Some(sfs,Done); M \ clinit; + P \\<^sub>1 \INIT D ([D],False) \ unit,(h\<^sub>1,ls\<^sub>1,sh\<^sub>1)\ \ \throw a,s'\ \ + \ P \\<^sub>1 \C\\<^sub>sM(ps),s\<^sub>0\ \ \throw a,s'\" +| SCallInit\<^sub>1: + "\ P \\<^sub>1 \ps,s\<^sub>0\ [\] \map Val vs,(h\<^sub>1,ls\<^sub>1,sh\<^sub>1)\; + P \ C sees M,Static:Ts\T = body in D; + \sfs. sh\<^sub>1 D = Some(sfs,Done); M \ clinit; + P \\<^sub>1 \INIT D ([D],False) \ unit,(h\<^sub>1,ls\<^sub>1,sh\<^sub>1)\ \ \Val v',(h\<^sub>2,ls\<^sub>2,sh\<^sub>2)\; + size vs = size Ts; ls\<^sub>2' = vs @ replicate (max_vars body) undefined; + P \\<^sub>1 \body,(h\<^sub>2,ls\<^sub>2',sh\<^sub>2)\ \ \e',(h\<^sub>3,ls\<^sub>3,sh\<^sub>3)\ \ + \ P \\<^sub>1 \C\\<^sub>sM(ps),s\<^sub>0\ \ \e',(h\<^sub>3,ls\<^sub>2,sh\<^sub>3)\" +| SCall\<^sub>1: + "\ P \\<^sub>1 \ps,s\<^sub>0\ [\] \map Val vs,(h\<^sub>2,ls\<^sub>2,sh\<^sub>2)\; + P \ C sees M,Static:Ts\T = body in D; + sh\<^sub>2 D = Some(sfs,Done) \ (M = clinit \ sh\<^sub>2 D = \(sfs, Processing)\); + size vs = size Ts; ls\<^sub>2' = vs @ replicate (max_vars body) undefined; + P \\<^sub>1 \body,(h\<^sub>2,ls\<^sub>2',sh\<^sub>2)\ \ \e',(h\<^sub>3,ls\<^sub>3,sh\<^sub>3)\ \ + \ P \\<^sub>1 \C\\<^sub>sM(ps),s\<^sub>0\ \ \e',(h\<^sub>3,ls\<^sub>2,sh\<^sub>3)\" + +| Block\<^sub>1: + "P \\<^sub>1 \e,s\<^sub>0\ \ \e',s\<^sub>1\ \ P \\<^sub>1 \Block i T e,s\<^sub>0\ \ \e',s\<^sub>1\" + +| Seq\<^sub>1: + "\ P \\<^sub>1 \e\<^sub>0,s\<^sub>0\ \ \Val v,s\<^sub>1\; P \\<^sub>1 \e\<^sub>1,s\<^sub>1\ \ \e\<^sub>2,s\<^sub>2\ \ + \ P \\<^sub>1 \e\<^sub>0;;e\<^sub>1,s\<^sub>0\ \ \e\<^sub>2,s\<^sub>2\" +| SeqThrow\<^sub>1: + "P \\<^sub>1 \e\<^sub>0,s\<^sub>0\ \ \throw e,s\<^sub>1\ \ + P \\<^sub>1 \e\<^sub>0;;e\<^sub>1,s\<^sub>0\ \ \throw e,s\<^sub>1\" + +| CondT\<^sub>1: + "\ P \\<^sub>1 \e,s\<^sub>0\ \ \true,s\<^sub>1\; P \\<^sub>1 \e\<^sub>1,s\<^sub>1\ \ \e',s\<^sub>2\ \ + \ P \\<^sub>1 \if (e) e\<^sub>1 else e\<^sub>2,s\<^sub>0\ \ \e',s\<^sub>2\" +| CondF\<^sub>1: + "\ P \\<^sub>1 \e,s\<^sub>0\ \ \false,s\<^sub>1\; P \\<^sub>1 \e\<^sub>2,s\<^sub>1\ \ \e',s\<^sub>2\ \ + \ P \\<^sub>1 \if (e) e\<^sub>1 else e\<^sub>2,s\<^sub>0\ \ \e',s\<^sub>2\" +| CondThrow\<^sub>1: + "P \\<^sub>1 \e,s\<^sub>0\ \ \throw e',s\<^sub>1\ \ + P \\<^sub>1 \if (e) e\<^sub>1 else e\<^sub>2, s\<^sub>0\ \ \throw e',s\<^sub>1\" + +| WhileF\<^sub>1: + "P \\<^sub>1 \e,s\<^sub>0\ \ \false,s\<^sub>1\ \ + P \\<^sub>1 \while (e) c,s\<^sub>0\ \ \unit,s\<^sub>1\" +| WhileT\<^sub>1: + "\ P \\<^sub>1 \e,s\<^sub>0\ \ \true,s\<^sub>1\; P \\<^sub>1 \c,s\<^sub>1\ \ \Val v\<^sub>1,s\<^sub>2\; + P \\<^sub>1 \while (e) c,s\<^sub>2\ \ \e\<^sub>3,s\<^sub>3\ \ + \ P \\<^sub>1 \while (e) c,s\<^sub>0\ \ \e\<^sub>3,s\<^sub>3\" +| WhileCondThrow\<^sub>1: + "P \\<^sub>1 \e,s\<^sub>0\ \ \throw e',s\<^sub>1\ \ + P \\<^sub>1 \while (e) c,s\<^sub>0\ \ \throw e',s\<^sub>1\" +| WhileBodyThrow\<^sub>1: + "\ P \\<^sub>1 \e,s\<^sub>0\ \ \true,s\<^sub>1\; P \\<^sub>1 \c,s\<^sub>1\ \ \throw e',s\<^sub>2\\ + \ P \\<^sub>1 \while (e) c,s\<^sub>0\ \ \throw e',s\<^sub>2\" + +| Throw\<^sub>1: + "P \\<^sub>1 \e,s\<^sub>0\ \ \addr a,s\<^sub>1\ \ + P \\<^sub>1 \throw e,s\<^sub>0\ \ \Throw a,s\<^sub>1\" +| ThrowNull\<^sub>1: + "P \\<^sub>1 \e,s\<^sub>0\ \ \null,s\<^sub>1\ \ + P \\<^sub>1 \throw e,s\<^sub>0\ \ \THROW NullPointer,s\<^sub>1\" +| ThrowThrow\<^sub>1: + "P \\<^sub>1 \e,s\<^sub>0\ \ \throw e',s\<^sub>1\ \ + P \\<^sub>1 \throw e,s\<^sub>0\ \ \throw e',s\<^sub>1\" + +| Try\<^sub>1: + "P \\<^sub>1 \e\<^sub>1,s\<^sub>0\ \ \Val v\<^sub>1,s\<^sub>1\ \ + P \\<^sub>1 \try e\<^sub>1 catch(C i) e\<^sub>2,s\<^sub>0\ \ \Val v\<^sub>1,s\<^sub>1\" +| TryCatch\<^sub>1: + "\ P \\<^sub>1 \e\<^sub>1,s\<^sub>0\ \ \Throw a,(h\<^sub>1,ls\<^sub>1,sh\<^sub>1)\; + h\<^sub>1 a = Some(D,fs); P \ D \\<^sup>* C; i < length ls\<^sub>1; + P \\<^sub>1 \e\<^sub>2,(h\<^sub>1,ls\<^sub>1[i:=Addr a],sh\<^sub>1)\ \ \e\<^sub>2',(h\<^sub>2,ls\<^sub>2,sh\<^sub>2)\ \ + \ P \\<^sub>1 \try e\<^sub>1 catch(C i) e\<^sub>2,s\<^sub>0\ \ \e\<^sub>2',(h\<^sub>2,ls\<^sub>2,sh\<^sub>2)\" +| TryThrow\<^sub>1: + "\ P \\<^sub>1 \e\<^sub>1,s\<^sub>0\ \ \Throw a,(h\<^sub>1,ls\<^sub>1,sh\<^sub>1)\; h\<^sub>1 a = Some(D,fs); \ P \ D \\<^sup>* C \ + \ P \\<^sub>1 \try e\<^sub>1 catch(C i) e\<^sub>2,s\<^sub>0\ \ \Throw a,(h\<^sub>1,ls\<^sub>1,sh\<^sub>1)\" + +| Nil\<^sub>1: + "P \\<^sub>1 \[],s\ [\] \[],s\" + +| Cons\<^sub>1: + "\ P \\<^sub>1 \e,s\<^sub>0\ \ \Val v,s\<^sub>1\; P \\<^sub>1 \es,s\<^sub>1\ [\] \es',s\<^sub>2\ \ + \ P \\<^sub>1 \e#es,s\<^sub>0\ [\] \Val v # es',s\<^sub>2\" +| ConsThrow\<^sub>1: + "P \\<^sub>1 \e,s\<^sub>0\ \ \throw e',s\<^sub>1\ \ + P \\<^sub>1 \e#es,s\<^sub>0\ [\] \throw e' # es, s\<^sub>1\" + +\ \ init rules \ + +| InitFinal\<^sub>1: + "P \\<^sub>1 \e,s\ \ \e',s'\ \ P \\<^sub>1 \INIT C (Nil,b) \ e,s\ \ \e',s'\" +| InitNone\<^sub>1: + "\ sh C = None; P \\<^sub>1 \INIT C' (C#Cs,False) \ e,(h,l,sh(C \ (sblank P C, Prepared)))\ \ \e',s'\ \ + \ P \\<^sub>1 \INIT C' (C#Cs,False) \ e,(h,l,sh)\ \ \e',s'\" +| InitDone\<^sub>1: + "\ sh C = Some(sfs,Done); P \\<^sub>1 \INIT C' (Cs,True) \ e,(h,l,sh)\ \ \e',s'\ \ + \ P \\<^sub>1 \INIT C' (C#Cs,False) \ e,(h,l,sh)\ \ \e',s'\" +| InitProcessing\<^sub>1: + "\ sh C = Some(sfs,Processing); P \\<^sub>1 \INIT C' (Cs,True) \ e,(h,l,sh)\ \ \e',s'\ \ + \ P \\<^sub>1 \INIT C' (C#Cs,False) \ e,(h,l,sh)\ \ \e',s'\" +| InitError\<^sub>1: + "\ sh C = Some(sfs,Error); + P \\<^sub>1 \RI (C, THROW NoClassDefFoundError);Cs \ e,(h,l,sh)\ \ \e',s'\ \ + \ P \\<^sub>1 \INIT C' (C#Cs,False) \ e,(h,l,sh)\ \ \e',s'\" +| InitObject\<^sub>1: + "\ sh C = Some(sfs,Prepared); + C = Object; + sh' = sh(C \ (sfs,Processing)); + P \\<^sub>1 \INIT C' (C#Cs,True) \ e,(h,l,sh')\ \ \e',s'\ \ + \ P \\<^sub>1 \INIT C' (C#Cs,False) \ e,(h,l,sh)\ \ \e',s'\" +| InitNonObject\<^sub>1: + "\ sh C = Some(sfs,Prepared); + C \ Object; + class P C = Some (D,r); + sh' = sh(C \ (sfs,Processing)); + P \\<^sub>1 \INIT C' (D#C#Cs,False) \ e,(h,l,sh')\ \ \e',s'\ \ + \ P \\<^sub>1 \INIT C' (C#Cs,False) \ e,(h,l,sh)\ \ \e',s'\" +| InitRInit\<^sub>1: + "P \\<^sub>1 \RI (C,C\\<^sub>sclinit([]));Cs \ e,(h,l,sh)\ \ \e',s'\ + \ P \\<^sub>1 \INIT C' (C#Cs,True) \ e,(h,l,sh)\ \ \e',s'\" + +| RInit\<^sub>1: + "\ P \\<^sub>1 \e,s\ \ \Val v, (h',l',sh')\; + sh' C = Some(sfs, i); sh'' = sh'(C \ (sfs, Done)); + C' = last(C#Cs); + P \\<^sub>1 \INIT C' (Cs,True) \ e', (h',l',sh'')\ \ \e\<^sub>1,s\<^sub>1\ \ + \ P \\<^sub>1 \RI (C,e);Cs \ e',s\ \ \e\<^sub>1,s\<^sub>1\" +| RInitInitFail\<^sub>1: + "\ P \\<^sub>1 \e,s\ \ \throw a, (h',l',sh')\; + sh' C = Some(sfs, i); sh'' = sh'(C \ (sfs, Error)); + P \\<^sub>1 \RI (D,throw a);Cs \ e', (h',l',sh'')\ \ \e\<^sub>1,s\<^sub>1\ \ + \ P \\<^sub>1 \RI (C,e);D#Cs \ e',s\ \ \e\<^sub>1,s\<^sub>1\" +| RInitFailFinal\<^sub>1: + "\ P \\<^sub>1 \e,s\ \ \throw a, (h',l',sh')\; + sh' C = Some(sfs, i); sh'' = sh'(C \ (sfs, Error)) \ + \ P \\<^sub>1 \RI (C,e);Nil \ e',s\ \ \throw a, (h',l',sh'')\" + + +(*<*) +lemmas eval\<^sub>1_evals\<^sub>1_induct = eval\<^sub>1_evals\<^sub>1.induct [split_format (complete)] + and eval\<^sub>1_evals\<^sub>1_inducts = eval\<^sub>1_evals\<^sub>1.inducts [split_format (complete)] +(*>*) + + +inductive_cases eval\<^sub>1_cases [cases set]: + "P \\<^sub>1 \new C,s\ \ \e',s'\" + "P \\<^sub>1 \Cast C e,s\ \ \e',s'\" + "P \\<^sub>1 \Val v,s\ \ \e',s'\" + "P \\<^sub>1 \e\<^sub>1 \bop\ e\<^sub>2,s\ \ \e',s'\" + "P \\<^sub>1 \Var v,s\ \ \e',s'\" + "P \\<^sub>1 \V:=e,s\ \ \e',s'\" + "P \\<^sub>1 \e\F{D},s\ \ \e',s'\" + "P \\<^sub>1 \C\\<^sub>sF{D},s\ \ \e',s'\" + "P \\<^sub>1 \e\<^sub>1\F{D}:=e\<^sub>2,s\ \ \e',s'\" + "P \\<^sub>1 \C\\<^sub>sF{D}:=e\<^sub>2,s\ \ \e',s'\" + "P \\<^sub>1 \e\M(es),s\ \ \e',s'\" + "P \\<^sub>1 \C\\<^sub>sM(es),s\ \ \e',s'\" + "P \\<^sub>1 \{V:T;e\<^sub>1},s\ \ \e',s'\" + "P \\<^sub>1 \e\<^sub>1;;e\<^sub>2,s\ \ \e',s'\" + "P \\<^sub>1 \if (e) e\<^sub>1 else e\<^sub>2,s\ \ \e',s'\" + "P \\<^sub>1 \while (b) c,s\ \ \e',s'\" + "P \\<^sub>1 \throw e,s\ \ \e',s'\" + "P \\<^sub>1 \try e\<^sub>1 catch(C V) e\<^sub>2,s\ \ \e',s'\" + "P \\<^sub>1 \INIT C (Cs,b) \ e,s\ \ \e',s'\" + "P \\<^sub>1 \RI (C,e);Cs \ e\<^sub>0,s\ \ \e',s'\" + +inductive_cases evals\<^sub>1_cases [cases set]: + "P \\<^sub>1 \[],s\ [\] \e',s'\" + "P \\<^sub>1 \e#es,s\ [\] \e',s'\" +(*>*) + + +lemma eval\<^sub>1_final: "P \\<^sub>1 \e,s\ \ \e',s'\ \ final e'" + and evals\<^sub>1_final: "P \\<^sub>1 \es,s\ [\] \es',s'\ \ finals es'" +(*<*)by(induct rule:eval\<^sub>1_evals\<^sub>1.inducts, simp_all)(*>*) + + +lemma eval\<^sub>1_final_same: "\ P \\<^sub>1 \e,s\ \ \e',s'\; final e \ \ e = e' \ s = s'" +(*<*) +apply(erule finalE) + using eval\<^sub>1_cases(3) apply blast +by (metis eval\<^sub>1_cases(3,17) exp.distinct(101) exp.inject(3) val.distinct(13)) +(*>*) + +subsection "Property preservation" + +lemma eval\<^sub>1_preserves_len: + "P \\<^sub>1 \e\<^sub>0,(h\<^sub>0,ls\<^sub>0,sh\<^sub>0)\ \ \e\<^sub>1,(h\<^sub>1,ls\<^sub>1,sh\<^sub>1)\ \ length ls\<^sub>0 = length ls\<^sub>1" +and evals\<^sub>1_preserves_len: + "P \\<^sub>1 \es\<^sub>0,(h\<^sub>0,ls\<^sub>0,sh\<^sub>0)\ [\] \es\<^sub>1,(h\<^sub>1,ls\<^sub>1,sh\<^sub>1)\ \ length ls\<^sub>0 = length ls\<^sub>1" +(*<*)by (induct rule:eval\<^sub>1_evals\<^sub>1_inducts, simp_all)(*>*) + + +lemma evals\<^sub>1_preserves_elen: + "\es' s s'. P \\<^sub>1 \es,s\ [\] \es',s'\ \ length es = length es'" +(*<*) +apply(induct es type:list) +apply (auto elim:evals\<^sub>1.cases) +done +(*>*) + + +lemma clinit\<^sub>1_loc_pres: + "P \\<^sub>1 \C\<^sub>0\\<^sub>sclinit([]),(h,l,sh)\ \ \e',(h',l',sh')\ \ l = l'" + by(auto elim!: eval\<^sub>1_cases(12) evals\<^sub>1_cases(1)) + +lemma +shows init\<^sub>1_ri\<^sub>1_same_loc: "P \\<^sub>1 \e,(h,l,sh)\ \ \e',(h',l',sh')\ + \ (\C Cs b M a. e = INIT C (Cs,b) \ unit \ e = C\\<^sub>sM([]) \ e = RI (C,Throw a) ; Cs \ unit + \ e = RI (C,C\\<^sub>sclinit([])) ; Cs \ unit + \ l = l')" + and "P \\<^sub>1 \es,(h,l,sh)\ [\] \es',(h',l',sh')\ \ True" +proof(induct rule: eval\<^sub>1_evals\<^sub>1_inducts) + case (RInitInitFail\<^sub>1 e h l sh a') + then show ?case using eval\<^sub>1_final[of _ _ _ "throw a'"] + by(fastforce dest: eval\<^sub>1_final_same[of _ "Throw a"]) +next + case RInitFailFinal\<^sub>1 then show ?case by(auto dest: eval\<^sub>1_final_same) +qed(auto dest: evals\<^sub>1_cases eval\<^sub>1_cases(17) eval\<^sub>1_final_same) + +lemma init\<^sub>1_same_loc: "P \\<^sub>1 \INIT C (Cs,b) \ unit,(h,l,sh)\ \ \e',(h',l',sh')\ \ l = l'" + by(simp add: init\<^sub>1_ri\<^sub>1_same_loc) + + +theorem eval\<^sub>1_hext: "P \\<^sub>1 \e,(h,l,sh)\ \ \e',(h',l',sh')\ \ h \ h'" +and evals\<^sub>1_hext: "P \\<^sub>1 \es,(h,l,sh)\ [\] \es',(h',l',sh')\ \ h \ h'" +(*<*) +proof (induct rule: eval\<^sub>1_evals\<^sub>1_inducts) + case New\<^sub>1 thus ?case + by(fastforce intro!: hext_new intro:LeastI simp:new_Addr_def + split:if_split_asm simp del:fun_upd_apply) +next + case NewInit\<^sub>1 thus ?case + by (meson hext_new hext_trans new_Addr_SomeD) +next + case FAss\<^sub>1 thus ?case + by(auto simp:sym[THEN hext_upd_obj] simp del:fun_upd_apply + elim!: hext_trans) +qed (auto elim!: hext_trans) +(*>*) + +subsection "Initialization" + +lemma rinit\<^sub>1_throw: + "P\<^sub>1 \\<^sub>1 \RI (D,Throw xa) ; Cs \ e,(h, l, sh)\ \ \e',(h', l', sh')\ + \ e' = Throw xa" +apply(induct Cs arbitrary: D h l sh h' l' sh') + apply(drule eval\<^sub>1_cases(20), auto elim: eval\<^sub>1_cases) +apply(drule eval\<^sub>1_cases(20), auto elim: eval\<^sub>1_cases dest: eval\<^sub>1_final_same simp: final_def) +done + +lemma rinit\<^sub>1_throwE: +"P \\<^sub>1 \RI (C,throw e) ; Cs \ e\<^sub>0,s\ \ \e',s'\ + \ \a s\<^sub>t. e' = throw a \ P \\<^sub>1 \throw e,s\ \ \throw a,s\<^sub>t\" +proof(induct Cs arbitrary: C e s) + case Nil + then show ?case + proof(rule eval\<^sub>1_cases(20)) \ \ RI \ + fix v h' l' sh' assume "P \\<^sub>1 \throw e,s\ \ \Val v,(h', l', sh')\" + then show ?case using eval\<^sub>1_cases(17) by blast + qed(auto) +next + case (Cons C' Cs') + show ?case using Cons.prems(1) + proof(rule eval\<^sub>1_cases(20)) \ \ RI \ + fix v h' l' sh' assume "P \\<^sub>1 \throw e,s\ \ \Val v,(h', l', sh')\" + then show ?case using eval\<^sub>1_cases(17) by blast + next + fix a h' l' sh' sfs i D Cs'' + assume e''step: "P \\<^sub>1 \throw e,s\ \ \throw a,(h', l', sh')\" + and shC: "sh' C = \(sfs, i)\" + and riD: "P \\<^sub>1 \RI (D,throw a) ; Cs'' \ e\<^sub>0,(h', l', sh'(C \ (sfs, Error)))\ \ \e',s'\" + and "C' # Cs' = D # Cs''" + then show ?thesis using Cons.hyps eval\<^sub>1_final eval\<^sub>1_final_same by blast + qed(simp) +qed + +end diff --git a/thys/JinjaDCI/Compiler/J1WellForm.thy b/thys/JinjaDCI/Compiler/J1WellForm.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/Compiler/J1WellForm.thy @@ -0,0 +1,531 @@ +(* Title: JinjaDCI/Compiler/J1WellForm.thy + + Author: Tobias Nipkow, Susannah Mansky + Copyright 2003 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory Compiler/J1WellForm.thy by Tobias Nipkow +*) + +section \ Well-Formedness of Intermediate Language \ + +theory J1WellForm +imports "../J/JWellForm" J1 +begin + +subsection "Well-Typedness" + +type_synonym + env\<^sub>1 = "ty list" \ \type environment indexed by variable number\ + +inductive + WT\<^sub>1 :: "[J\<^sub>1_prog,env\<^sub>1, expr\<^sub>1 , ty ] \ bool" + ("(_,_ \\<^sub>1/ _ :: _)" [51,51,51]50) + and WTs\<^sub>1 :: "[J\<^sub>1_prog,env\<^sub>1, expr\<^sub>1 list, ty list] \ bool" + ("(_,_ \\<^sub>1/ _ [::] _)" [51,51,51]50) + for P :: J\<^sub>1_prog +where + + WTNew\<^sub>1: + "is_class P C \ + P,E \\<^sub>1 new C :: Class C" + +| WTCast\<^sub>1: + "\ P,E \\<^sub>1 e :: Class D; is_class P C; P \ C \\<^sup>* D \ P \ D \\<^sup>* C \ + \ P,E \\<^sub>1 Cast C e :: Class C" + +| WTVal\<^sub>1: + "typeof v = Some T \ + P,E \\<^sub>1 Val v :: T" + +| WTVar\<^sub>1: + "\ E!i = T; i < size E \ + \ P,E \\<^sub>1 Var i :: T" + +| WTBinOp\<^sub>1: + "\ P,E \\<^sub>1 e\<^sub>1 :: T\<^sub>1; P,E \\<^sub>1 e\<^sub>2 :: T\<^sub>2; + case bop of Eq \ (P \ T\<^sub>1 \ T\<^sub>2 \ P \ T\<^sub>2 \ T\<^sub>1) \ T = Boolean + | Add \ T\<^sub>1 = Integer \ T\<^sub>2 = Integer \ T = Integer \ + \ P,E \\<^sub>1 e\<^sub>1 \bop\ e\<^sub>2 :: T" + +| WTLAss\<^sub>1: + "\ E!i = T; i < size E; P,E \\<^sub>1 e :: T'; P \ T' \ T \ + \ P,E \\<^sub>1 i:=e :: Void" + +| WTFAcc\<^sub>1: + "\ P,E \\<^sub>1 e :: Class C; P \ C sees F,NonStatic:T in D \ + \ P,E \\<^sub>1 e\F{D} :: T" + +| WTSFAcc\<^sub>1: + "\ P \ C sees F,Static:T in D \ + \ P,E \\<^sub>1 C\\<^sub>sF{D} :: T" + +| WTFAss\<^sub>1: + "\ P,E \\<^sub>1 e\<^sub>1 :: Class C; P \ C sees F,NonStatic:T in D; P,E \\<^sub>1 e\<^sub>2 :: T'; P \ T' \ T \ + \ P,E \\<^sub>1 e\<^sub>1\F{D} := e\<^sub>2 :: Void" + +| WTSFAss\<^sub>1: + "\ P \ C sees F,Static:T in D; P,E \\<^sub>1 e\<^sub>2 :: T'; P \ T' \ T \ + \ P,E \\<^sub>1 C\\<^sub>sF{D}:=e\<^sub>2 :: Void" + +| WTCall\<^sub>1: + "\ P,E \\<^sub>1 e :: Class C; P \ C sees M,NonStatic:Ts' \ T = m in D; + P,E \\<^sub>1 es [::] Ts; P \ Ts [\] Ts' \ + \ P,E \\<^sub>1 e\M(es) :: T" + +| WTSCall\<^sub>1: + "\ P \ C sees M,Static:Ts \ T = m in D; + P,E \\<^sub>1 es [::] Ts'; P \ Ts' [\] Ts; M \ clinit \ + \ P,E \\<^sub>1 C\\<^sub>sM(es) :: T" + +| WTBlock\<^sub>1: + "\ is_type P T; P,E@[T] \\<^sub>1 e::T' \ + \ P,E \\<^sub>1 {i:T; e} :: T'" + +| WTSeq\<^sub>1: + "\ P,E \\<^sub>1 e\<^sub>1::T\<^sub>1; P,E \\<^sub>1 e\<^sub>2::T\<^sub>2 \ + \ P,E \\<^sub>1 e\<^sub>1;;e\<^sub>2 :: T\<^sub>2" + +| WTCond\<^sub>1: + "\ P,E \\<^sub>1 e :: Boolean; P,E \\<^sub>1 e\<^sub>1::T\<^sub>1; P,E \\<^sub>1 e\<^sub>2::T\<^sub>2; + P \ T\<^sub>1 \ T\<^sub>2 \ P \ T\<^sub>2 \ T\<^sub>1; P \ T\<^sub>1 \ T\<^sub>2 \ T = T\<^sub>2; P \ T\<^sub>2 \ T\<^sub>1 \ T = T\<^sub>1 \ + \ P,E \\<^sub>1 if (e) e\<^sub>1 else e\<^sub>2 :: T" + +| WTWhile\<^sub>1: + "\ P,E \\<^sub>1 e :: Boolean; P,E \\<^sub>1 c::T \ + \ P,E \\<^sub>1 while (e) c :: Void" + +| WTThrow\<^sub>1: + "P,E \\<^sub>1 e :: Class C \ + P,E \\<^sub>1 throw e :: Void" + +| WTTry\<^sub>1: + "\ P,E \\<^sub>1 e\<^sub>1 :: T; P,E@[Class C] \\<^sub>1 e\<^sub>2 :: T; is_class P C \ + \ P,E \\<^sub>1 try e\<^sub>1 catch(C i) e\<^sub>2 :: T" + +| WTNil\<^sub>1: + "P,E \\<^sub>1 [] [::] []" + +| WTCons\<^sub>1: + "\ P,E \\<^sub>1 e :: T; P,E \\<^sub>1 es [::] Ts \ + \ P,E \\<^sub>1 e#es [::] T#Ts" + +(*<*) +declare WT\<^sub>1_WTs\<^sub>1.intros[intro!] +declare WTNil\<^sub>1[iff] + +lemmas WT\<^sub>1_WTs\<^sub>1_induct = WT\<^sub>1_WTs\<^sub>1.induct [split_format (complete)] + and WT\<^sub>1_WTs\<^sub>1_inducts = WT\<^sub>1_WTs\<^sub>1.inducts [split_format (complete)] + +inductive_cases eee[elim!]: + "P,E \\<^sub>1 Val v :: T" + "P,E \\<^sub>1 Var i :: T" + "P,E \\<^sub>1 Cast D e :: T" + "P,E \\<^sub>1 i:=e :: T" + "P,E \\<^sub>1 {i:U; e} :: T" + "P,E \\<^sub>1 e\<^sub>1;;e\<^sub>2 :: T" + "P,E \\<^sub>1 if (e) e\<^sub>1 else e\<^sub>2 :: T" + "P,E \\<^sub>1 while (e) c :: T" + "P,E \\<^sub>1 throw e :: T" + "P,E \\<^sub>1 try e\<^sub>1 catch(C i) e\<^sub>2 :: T" + "P,E \\<^sub>1 e\F{D} :: T" + "P,E \\<^sub>1 C\\<^sub>sF{D} :: T" + "P,E \\<^sub>1 e\<^sub>1\F{D}:=e\<^sub>2 :: T" + "P,E \\<^sub>1 C\\<^sub>sF{D}:=e\<^sub>2 :: T" + "P,E \\<^sub>1 e\<^sub>1 \bop\ e\<^sub>2 :: T" + "P,E \\<^sub>1 new C :: T" + "P,E \\<^sub>1 e\M(es) :: T" + "P,E \\<^sub>1 C\\<^sub>sM(es) :: T" + "P,E \\<^sub>1 [] [::] Ts" + "P,E \\<^sub>1 e#es [::] Ts" +(*>*) + +lemma init_nWT\<^sub>1 [simp]:"\P,E \\<^sub>1 INIT C (Cs,b) \ e :: T" + by(auto elim:WT\<^sub>1.cases) +lemma rinit_nWT\<^sub>1 [simp]:"\P,E \\<^sub>1 RI(C,e);Cs \ e' :: T" + by(auto elim:WT\<^sub>1.cases) + +lemma WTs\<^sub>1_same_size: "\Ts. P,E \\<^sub>1 es [::] Ts \ size es = size Ts" +(*<*)by (induct es type:list) auto(*>*) + + +lemma WT\<^sub>1_unique: + "P,E \\<^sub>1 e :: T\<^sub>1 \ (\T\<^sub>2. P,E \\<^sub>1 e :: T\<^sub>2 \ T\<^sub>1 = T\<^sub>2)" and + WTs\<^sub>1_unique: "P,E \\<^sub>1 es [::] Ts\<^sub>1 \ (\Ts\<^sub>2. P,E \\<^sub>1 es [::] Ts\<^sub>2 \ Ts\<^sub>1 = Ts\<^sub>2)" +(*<*) +apply(induct rule:WT\<^sub>1_WTs\<^sub>1.inducts) +apply blast +apply blast +apply clarsimp +apply blast +apply clarsimp +apply(case_tac bop) +apply clarsimp +apply clarsimp +apply blast +apply (blast dest:sees_field_idemp sees_field_fun) +apply (blast dest:sees_field_fun) +apply blast +apply (blast dest:sees_field_fun) +apply (blast dest:sees_method_idemp sees_method_fun) +apply (blast dest:sees_method_fun) +apply blast +apply blast +apply blast +apply blast +apply clarify +apply blast +apply blast +apply blast +done +(*>*) + + +lemma assumes wf: "wf_prog p P" +shows WT\<^sub>1_is_type: "P,E \\<^sub>1 e :: T \ set E \ types P \ is_type P T" +and "P,E \\<^sub>1 es [::] Ts \ True" +(*<*) +apply(induct rule:WT\<^sub>1_WTs\<^sub>1.inducts) +apply simp +apply simp +apply (simp add:typeof_lit_is_type) +apply (blast intro:nth_mem) +apply(simp split:bop.splits) +apply simp +apply (simp add:sees_field_is_type[OF _ wf]) +apply (simp add:sees_field_is_type[OF _ wf]) +apply simp +apply simp +apply(fastforce dest!: sees_wf_mdecl[OF wf] simp:wf_mdecl_def) +apply(fastforce dest!: sees_wf_mdecl[OF wf] simp:wf_mdecl_def) +apply simp +apply simp +apply blast +apply simp +apply simp +apply simp +apply simp +apply simp +done +(*>*) + +lemma WT\<^sub>1_nsub_RI: "P,E \\<^sub>1 e :: T \ \sub_RI e" + and WTs\<^sub>1_nsub_RIs: "P,E \\<^sub>1 es [::] Ts \ \sub_RIs es" +proof(induct rule: WT\<^sub>1_WTs\<^sub>1.inducts) qed(simp_all) + +subsection\ Runtime Well-Typedness \ + +inductive + WTrt\<^sub>1 :: "J\<^sub>1_prog \ heap \ sheap \ env\<^sub>1 \ expr\<^sub>1 \ ty \ bool" + and WTrts\<^sub>1 :: "J\<^sub>1_prog \ heap \ sheap \ env\<^sub>1 \ expr\<^sub>1 list \ ty list \ bool" + and WTrt2\<^sub>1 :: "[J\<^sub>1_prog,env\<^sub>1,heap,sheap,expr\<^sub>1,ty] \ bool" + ("_,_,_,_ \\<^sub>1 _ : _" [51,51,51,51]50) + and WTrts2\<^sub>1 :: "[J\<^sub>1_prog,env\<^sub>1,heap,sheap,expr\<^sub>1 list, ty list] \ bool" + ("_,_,_,_ \\<^sub>1 _ [:] _" [51,51,51,51]50) + for P :: J\<^sub>1_prog and h :: heap and sh :: sheap +where + + "P,E,h,sh \\<^sub>1 e : T \ WTrt\<^sub>1 P h sh E e T" +| "P,E,h,sh \\<^sub>1 es[:]Ts \ WTrts\<^sub>1 P h sh E es Ts" + +| WTrtNew\<^sub>1: + "is_class P C \ + P,E,h,sh \\<^sub>1 new C : Class C" + +| WTrtCast\<^sub>1: + "\ P,E,h,sh \\<^sub>1 e : T; is_refT T; is_class P C \ + \ P,E,h,sh \\<^sub>1 Cast C e : Class C" + +| WTrtVal\<^sub>1: + "typeof\<^bsub>h\<^esub> v = Some T \ + P,E,h,sh \\<^sub>1 Val v : T" + +| WTrtVar\<^sub>1: + "\ E!i = T; i < size E \ \ + P,E,h,sh \\<^sub>1 Var i : T" + +| WTrtBinOpEq\<^sub>1: + "\ P,E,h,sh \\<^sub>1 e\<^sub>1 : T\<^sub>1; P,E,h,sh \\<^sub>1 e\<^sub>2 : T\<^sub>2 \ + \ P,E,h,sh \\<^sub>1 e\<^sub>1 \Eq\ e\<^sub>2 : Boolean" + +| WTrtBinOpAdd\<^sub>1: + "\ P,E,h,sh \\<^sub>1 e\<^sub>1 : Integer; P,E,h,sh \\<^sub>1 e\<^sub>2 : Integer \ + \ P,E,h,sh \\<^sub>1 e\<^sub>1 \Add\ e\<^sub>2 : Integer" + +| WTrtLAss\<^sub>1: + "\ E!i = T; i < size E; P,E,h,sh \\<^sub>1 e : T'; P \ T' \ T \ + \ P,E,h,sh \\<^sub>1 i:=e : Void" + +| WTrtFAcc\<^sub>1: + "\ P,E,h,sh \\<^sub>1 e : Class C; P \ C has F,NonStatic:T in D \ \ + P,E,h,sh \\<^sub>1 e\F{D} : T" + +| WTrtFAccNT\<^sub>1: + "P,E,h,sh \\<^sub>1 e : NT \ + P,E,h,sh \\<^sub>1 e\F{D} : T" + +| WTrtSFAcc\<^sub>1: + "\ P \ C has F,Static:T in D \ \ + P,E,h,sh \\<^sub>1 C\\<^sub>sF{D} : T" + +| WTrtFAss\<^sub>1: + "\ P,E,h,sh \\<^sub>1 e\<^sub>1 : Class C; P \ C has F,NonStatic:T in D; P,E,h,sh \\<^sub>1 e\<^sub>2 : T\<^sub>2; P \ T\<^sub>2 \ T \ + \ P,E,h,sh \\<^sub>1 e\<^sub>1\F{D}:=e\<^sub>2 : Void" + +| WTrtFAssNT\<^sub>1: + "\ P,E,h,sh \\<^sub>1 e\<^sub>1:NT; P,E,h,sh \\<^sub>1 e\<^sub>2 : T\<^sub>2 \ + \ P,E,h,sh \\<^sub>1 e\<^sub>1\F{D}:=e\<^sub>2 : Void" + +| WTrtSFAss\<^sub>1: + "\ P,E,h,sh \\<^sub>1 e\<^sub>2 : T\<^sub>2; P \ C has F,Static:T in D; P \ T\<^sub>2 \ T \ + \ P,E,h,sh \\<^sub>1 C\\<^sub>sF{D}:=e\<^sub>2 : Void" + +| WTrtCall\<^sub>1: + "\ P,E,h,sh \\<^sub>1 e : Class C; P \ C sees M,NonStatic:Ts \ T = m in D; + P,E,h,sh \\<^sub>1 es [:] Ts'; P \ Ts' [\] Ts \ + \ P,E,h,sh \\<^sub>1 e\M(es) : T" + +| WTrtCallNT\<^sub>1: + "\ P,E,h,sh \\<^sub>1 e : NT; P,E,h,sh \\<^sub>1 es [:] Ts \ + \ P,E,h,sh \\<^sub>1 e\M(es) : T" + +| WTrtSCall\<^sub>1: + "\ P \ C sees M,Static:Ts \ T = m in D; + P,E,h,sh \\<^sub>1 es [:] Ts'; P \ Ts' [\] Ts; + M = clinit \ sh D = \(sfs,Processing)\ \ es = map Val vs \ + \ P,E,h,sh \\<^sub>1 C\\<^sub>sM(es) : T" + +| WTrtBlock\<^sub>1: + "P,E@[T],h,sh \\<^sub>1 e : T' \ + P,E,h,sh \\<^sub>1 {i:T; e} : T'" + +| WTrtSeq\<^sub>1: + "\ P,E,h,sh \\<^sub>1 e\<^sub>1:T\<^sub>1; P,E,h,sh \\<^sub>1 e\<^sub>2:T\<^sub>2 \ + \ P,E,h,sh \\<^sub>1 e\<^sub>1;;e\<^sub>2 : T\<^sub>2" + +| WTrtCond\<^sub>1: + "\ P,E,h,sh \\<^sub>1 e : Boolean; P,E,h,sh \\<^sub>1 e\<^sub>1:T\<^sub>1; P,E,h,sh \\<^sub>1 e\<^sub>2:T\<^sub>2; + P \ T\<^sub>1 \ T\<^sub>2 \ P \ T\<^sub>2 \ T\<^sub>1; P \ T\<^sub>1 \ T\<^sub>2 \ T = T\<^sub>2; P \ T\<^sub>2 \ T\<^sub>1 \ T = T\<^sub>1 \ + \ P,E,h,sh \\<^sub>1 if (e) e\<^sub>1 else e\<^sub>2 : T" + +| WTrtWhile\<^sub>1: + "\ P,E,h,sh \\<^sub>1 e : Boolean; P,E,h,sh \\<^sub>1 c:T \ + \ P,E,h,sh \\<^sub>1 while(e) c : Void" + +| WTrtThrow\<^sub>1: + "\ P,E,h,sh \\<^sub>1 e : T\<^sub>r; is_refT T\<^sub>r \ \ + P,E,h,sh \\<^sub>1 throw e : T" + +| WTrtTry\<^sub>1: + "\ P,E,h,sh \\<^sub>1 e\<^sub>1 : T\<^sub>1; P,E@[Class C],h,sh \\<^sub>1 e\<^sub>2 : T\<^sub>2; P \ T\<^sub>1 \ T\<^sub>2 \ + \ P,E,h,sh \\<^sub>1 try e\<^sub>1 catch(C i) e\<^sub>2 : T\<^sub>2" + +| WTrtInit\<^sub>1: + "\ P,E,h,sh \\<^sub>1 e : T; \C' \ set (C#Cs). is_class P C'; \sub_RI e; + \C' \ set (tl Cs). \sfs. sh C' = \(sfs,Processing)\; + b \ (\C' \ set Cs. \sfs. sh C' = \(sfs,Processing)\); + distinct Cs; supercls_lst P Cs \ + \ P,E,h,sh \\<^sub>1 INIT C (Cs, b) \ e : T" + +| WTrtRI\<^sub>1: + "\ P,E,h,sh \\<^sub>1 e : T; P,E,h,sh \\<^sub>1 e' : T'; \C' \ set (C#Cs). is_class P C'; \sub_RI e'; + \C' \ set (C#Cs). not_init C' e; + \C' \ set Cs. \sfs. sh C' = \(sfs,Processing)\; + \sfs. sh C = \(sfs, Processing)\ \ (sh C = \(sfs, Error)\ \ e = THROW NoClassDefFoundError); + distinct (C#Cs); supercls_lst P (C#Cs) \ + \ P,E,h,sh \\<^sub>1 RI(C, e);Cs \ e' : T'" + +\ \well-typed expression lists\ + +| WTrtNil\<^sub>1: + "P,E,h,sh \\<^sub>1 [] [:] []" + +| WTrtCons\<^sub>1: + "\ P,E,h,sh \\<^sub>1 e : T; P,E,h,sh \\<^sub>1 es [:] Ts \ + \ P,E,h,sh \\<^sub>1 e#es [:] T#Ts" + +(*<*) +declare WTrt\<^sub>1_WTrts\<^sub>1.intros[intro!] WTrtNil\<^sub>1[iff] +declare + WTrtFAcc\<^sub>1[rule del] WTrtFAccNT\<^sub>1[rule del] WTrtSFAcc\<^sub>1[rule del] + WTrtFAss\<^sub>1[rule del] WTrtFAssNT\<^sub>1[rule del] WTrtSFAss\<^sub>1[rule del] + WTrtCall\<^sub>1[rule del] WTrtCallNT\<^sub>1[rule del] WTrtSCall\<^sub>1[rule del] + +lemmas WTrt\<^sub>1_induct = WTrt\<^sub>1_WTrts\<^sub>1.induct [split_format (complete)] + and WTrt\<^sub>1_inducts = WTrt\<^sub>1_WTrts\<^sub>1.inducts [split_format (complete)] +(*>*) + +(*<*) +inductive_cases WTrt\<^sub>1_elim_cases[elim!]: + "P,E,h,sh \\<^sub>1 Val v : T" + "P,E,h,sh \\<^sub>1 Var i : T" + "P,E,h,sh \\<^sub>1 v :=e : T" + "P,E,h,sh \\<^sub>1 {i:U; e} : T" + "P,E,h,sh \\<^sub>1 e\<^sub>1;;e\<^sub>2 : T\<^sub>2" + "P,E,h,sh \\<^sub>1 if (e) e\<^sub>1 else e\<^sub>2 : T" + "P,E,h,sh \\<^sub>1 while(e) c : T" + "P,E,h,sh \\<^sub>1 throw e : T" + "P,E,h,sh \\<^sub>1 try e\<^sub>1 catch(C V) e\<^sub>2 : T" + "P,E,h,sh \\<^sub>1 Cast D e : T" + "P,E,h,sh \\<^sub>1 e\F{D} : T" + "P,E,h,sh \\<^sub>1 C\\<^sub>sF{D} : T" + "P,E,h,sh \\<^sub>1 e\F{D} := v : T" + "P,E,h,sh \\<^sub>1 C\\<^sub>sF{D} := v : T" + "P,E,h,sh \\<^sub>1 e\<^sub>1 \bop\ e\<^sub>2 : T" + "P,E,h,sh \\<^sub>1 new C : T" + "P,E,h,sh \\<^sub>1 e\M{D}(es) : T" + "P,E,h,sh \\<^sub>1 C\\<^sub>sM{D}(es) : T" + "P,E,h,sh \\<^sub>1 INIT C (Cs,b) \ e : T" + "P,E,h,sh \\<^sub>1 RI(C,e);Cs \ e' : T" + "P,E,h,sh \\<^sub>1 [] [:] Ts" + "P,E,h,sh \\<^sub>1 e#es [:] Ts" +(*>*) + +lemma WT\<^sub>1_implies_WTrt\<^sub>1: "P,E \\<^sub>1 e :: T \ P,E,h,sh \\<^sub>1 e : T" +and WTs\<^sub>1_implies_WTrts\<^sub>1: "P,E \\<^sub>1 es [::] Ts \ P,E,h,sh \\<^sub>1 es [:] Ts" +(*<*) +apply(induct rule: WT\<^sub>1_WTs\<^sub>1_inducts) +apply fast +apply (fast) +apply(fastforce dest:typeof_lit_typeof) +apply(fast) +apply(rename_tac E e\<^sub>1 T\<^sub>1 e\<^sub>2 T\<^sub>2 bop T) apply(case_tac bop) + apply(fastforce) + apply(fastforce) +apply(fastforce) +apply(meson WTrtFAcc\<^sub>1 has_visible_field) +apply(meson WTrtSFAcc\<^sub>1 has_visible_field) +apply(meson WTrtFAss\<^sub>1 has_visible_field) +apply(meson WTrtSFAss\<^sub>1 has_visible_field) +apply(fastforce simp: WTrtCall\<^sub>1) +apply(fastforce simp: WTrtSCall\<^sub>1) +apply(fastforce) +apply(fastforce) +apply(fastforce simp: WTrtCond\<^sub>1) +apply(fastforce) +apply(fastforce) +apply(fastforce) +apply(simp) +apply(fast) +done +(*>*) + +subsection\ Well-formedness\ + +\ \Indices in blocks increase by 1\ + +primrec \ :: "expr\<^sub>1 \ nat \ bool" + and \s :: "expr\<^sub>1 list \ nat \ bool" where +"\ (new C) i = True" | +"\ (Cast C e) i = \ e i" | +"\ (Val v) i = True" | +"\ (e\<^sub>1 \bop\ e\<^sub>2) i = (\ e\<^sub>1 i \ \ e\<^sub>2 i)" | +"\ (Var j) i = True" | +"\ (e\F{D}) i = \ e i" | +"\ (C\\<^sub>sF{D}) i = True" | +"\ (j:=e) i = \ e i" | +"\ (e\<^sub>1\F{D} := e\<^sub>2) i = (\ e\<^sub>1 i \ \ e\<^sub>2 i)" | +"\ (C\\<^sub>sF{D} := e\<^sub>2) i = \ e\<^sub>2 i" | +"\ (e\M(es)) i = (\ e i \ \s es i)" | +"\ (C\\<^sub>sM(es)) i = \s es i" | +"\ ({j:T ; e}) i = (i = j \ \ e (i+1))" | +"\ (e\<^sub>1;;e\<^sub>2) i = (\ e\<^sub>1 i \ \ e\<^sub>2 i)" | +"\ (if (e) e\<^sub>1 else e\<^sub>2) i = (\ e i \ \ e\<^sub>1 i \ \ e\<^sub>2 i)" | +"\ (throw e) i = \ e i" | +"\ (while (e) c) i = (\ e i \ \ c i)" | +"\ (try e\<^sub>1 catch(C j) e\<^sub>2) i = (\ e\<^sub>1 i \ i=j \ \ e\<^sub>2 (i+1))" | +"\ (INIT C (Cs,b) \ e) i = \ e i" | +"\ (RI(C,e);Cs \ e') i = (\ e i \ \ e' i)" | + +"\s [] i = True" | +"\s (e#es) i = (\ e i \ \s es i)" + + +definition wf_J\<^sub>1_mdecl :: "J\<^sub>1_prog \ cname \ expr\<^sub>1 mdecl \ bool" +where + "wf_J\<^sub>1_mdecl P C \ \(M,b,Ts,T,body). + \sub_RI body \ + (case b of + NonStatic \ + (\T'. P,Class C#Ts \\<^sub>1 body :: T' \ P \ T' \ T) \ + \ body \{..size Ts}\ \ \ body (size Ts + 1) + | Static \ (\T'. P,Ts \\<^sub>1 body :: T' \ P \ T' \ T) \ + \ body \{.. \ \ body (size Ts))" + +lemma wf_J\<^sub>1_mdecl_NonStatic[simp]: + "wf_J\<^sub>1_mdecl P C (M,NonStatic,Ts,T,body) \ + (\sub_RI body \ + (\T'. P,Class C#Ts \\<^sub>1 body :: T' \ P \ T' \ T) \ + \ body \{..size Ts}\ \ \ body (size Ts + 1))" +(*<*)by (simp add:wf_J\<^sub>1_mdecl_def)(*>*) + +lemma wf_J\<^sub>1_mdecl_Static[simp]: + "wf_J\<^sub>1_mdecl P C (M,Static,Ts,T,body) \ + (\sub_RI body \ + (\T'. P,Ts \\<^sub>1 body :: T' \ P \ T' \ T) \ + \ body \{.. \ \ body (size Ts))" +(*<*)by (simp add:wf_J\<^sub>1_mdecl_def)(*>*) + +abbreviation "wf_J\<^sub>1_prog == wf_prog wf_J\<^sub>1_mdecl" + +lemma sees_wf\<^sub>1_nsub_RI: + "\ wf_J\<^sub>1_prog P; P \ C sees M,b : Ts\T = body in D \ \ \sub_RI body" +apply(drule sees_wf_mdecl, simp) +apply(unfold wf_J\<^sub>1_mdecl_def wf_mdecl_def, simp) +done + +lemma wf\<^sub>1_types_clinit: +assumes wf:"wf_prog wf_md P" and ex: "class P C = Some a" and proc: "sh C = \(sfs, Processing)\" +shows "P,E,h,sh \\<^sub>1 C\\<^sub>sclinit([]) : Void" +proof - + from ex obtain D fs ms where "a = (D,fs,ms)" by(cases a) + then have sP: "(C, D, fs, ms) \ set P" using ex map_of_SomeD[of P C a] by(simp add: class_def) + then have "wf_clinit ms" using assms by(unfold wf_prog_def wf_cdecl_def, auto) + then obtain m where sm: "(clinit, Static, [], Void, m) \ set ms" + by(unfold wf_clinit_def) auto + then have "P \ C sees clinit,Static:[] \ Void = m in C" + using mdecl_visible[OF wf sP sm] by simp + then show ?thesis using WTrtSCall\<^sub>1 proc by blast +qed + + +lemma assumes wf: "wf_J\<^sub>1_prog P" +shows eval\<^sub>1_proc_pres: "P \\<^sub>1 \e,(h,l,sh)\ \ \e',(h',l',sh')\ + \ not_init C e \ \sfs. sh C = \(sfs, Processing)\ \ \sfs'. sh' C = \(sfs', Processing)\" + and evals\<^sub>1_proc_pres: "P \\<^sub>1 \es,(h,l,sh)\ [\] \es',(h',l',sh')\ + \ not_inits C es \ \sfs. sh C = \(sfs, Processing)\ \ \sfs'. sh' C = \(sfs', Processing)\" +(*<*) +proof(induct rule:eval\<^sub>1_evals\<^sub>1_inducts) + case Call\<^sub>1 then show ?case using sees_wf\<^sub>1_nsub_RI[OF wf Call\<^sub>1.hyps(6)] nsub_RI_not_init by auto +next + case (SCallInit\<^sub>1 ps h l sh vs h\<^sub>1 l\<^sub>1 sh\<^sub>1 C' M Ts T body D v' h\<^sub>2 l\<^sub>2 sh\<^sub>2 l\<^sub>2' e' h\<^sub>3 l\<^sub>3 sh\<^sub>3) + then show ?case + using SCallInit\<^sub>1 sees_wf\<^sub>1_nsub_RI[OF wf SCallInit\<^sub>1.hyps(3)] nsub_RI_not_init[of body] by auto +next + case SCall\<^sub>1 then show ?case using sees_wf\<^sub>1_nsub_RI[OF wf SCall\<^sub>1.hyps(3)] nsub_RI_not_init by auto +next + case (InitNone\<^sub>1 sh C1 C' Cs h l e' a a b) then show ?case by(cases "C = C1") auto +next + case (InitDone\<^sub>1 sh C sfs C' Cs h l e' a a b) then show ?case by(cases Cs, auto) +next + case (InitProcessing\<^sub>1 sh C sfs C' Cs h l e' a a b) then show ?case by(cases Cs, auto) +next + case (InitError\<^sub>1 sh C1 sfs Cs h l e' a a b C') then show ?case by(cases "C = C1") auto +next + case (InitObject\<^sub>1 sh C1 sfs sh' C' Cs h l e' a a b) then show ?case by(cases "C = C1") auto +next + case (InitNonObject\<^sub>1 sh C1 sfs D a b sh' C' Cs h l e' a a b) + then show ?case by(cases "C = C1") auto +next + case (RInit\<^sub>1 e a a b v h' l' sh' C sfs i sh'' C' Cs e\<^sub>1 a a b) then show ?case by(cases Cs, auto) +next + case (RInitInitFail\<^sub>1 e h l sh a h' l' sh' C1 sfs i sh'' D Cs e\<^sub>1 h1 l1 sh1) + then show ?case using eval\<^sub>1_final by fastforce +qed(auto) + +lemma clinit\<^sub>1_proc_pres: + "\ wf_J\<^sub>1_prog P; P \\<^sub>1 \C\<^sub>0\\<^sub>sclinit([]),(h,l,sh)\ \ \e',(h',l',sh')\; + sh C' = \(sfs,Processing)\ \ + \ \sfs. sh' C' = \(sfs,Processing)\" + by(auto dest: eval\<^sub>1_proc_pres) + +end diff --git a/thys/JinjaDCI/Compiler/PCompiler.thy b/thys/JinjaDCI/Compiler/PCompiler.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/Compiler/PCompiler.thy @@ -0,0 +1,314 @@ +(* Title: JinjaDCI/Compiler/PCompiler.thy + + Author: Tobias Nipkow, Susannah Mansky + Copyright TUM 2003, UIUC 2019-20 + + Based on the Jinja theory Common/PCompiler.thy by Tobias Nipkow +*) + +section \ Program Compilation \ + +theory PCompiler +imports "../Common/WellForm" +begin + +definition compM :: "(staticb \ 'a \ 'b) \ 'a mdecl \ 'b mdecl" +where + "compM f \ \(M, b, Ts, T, m). (M, b, Ts, T, f b m)" + +definition compC :: "(staticb \ 'a \ 'b) \ 'a cdecl \ 'b cdecl" +where + "compC f \ \(C,D,Fdecls,Mdecls). (C,D,Fdecls, map (compM f) Mdecls)" + +definition compP :: "(staticb \ 'a \ 'b) \ 'a prog \ 'b prog" +where + "compP f \ map (compC f)" + +text\ Compilation preserves the program structure. Therefore lookup +functions either commute with compilation (like method lookup) or are +preserved by it (like the subclass relation). \ + +lemma map_of_map4: + "map_of (map (\(x,a,b,c).(x,a,b,f c)) ts) = + map_option (\(a,b,c).(a,b,f c)) \ (map_of ts)" +(*<*) +apply(induct ts) + apply simp +apply(rule ext) +apply fastforce +done +(*>*) + +lemma map_of_map245: + "map_of (map (\(x,a,b,c,d).(x,a,b,c,f a c d)) ts) = + map_option (\(a,b,c,d).(a,b,c,f a c d)) \ (map_of ts)" +(*<*) +apply(induct ts) + apply simp +apply(rule ext) +apply fastforce +done +(*>*) + + +lemma class_compP: + "class P C = Some (D, fs, ms) + \ class (compP f P) C = Some (D, fs, map (compM f) ms)" +(*<*)by(simp add:class_def compP_def compC_def map_of_map4)(*>*) + + +lemma class_compPD: + "class (compP f P) C = Some (D, fs, cms) + \ \ms. class P C = Some(D,fs,ms) \ cms = map (compM f) ms" +(*<*)by(clarsimp simp add:class_def compP_def compC_def map_of_map4)(*>*) + + +lemma [simp]: "is_class (compP f P) C = is_class P C" +(*<*)by(auto simp:is_class_def dest: class_compP class_compPD)(*>*) + + +lemma [simp]: "class (compP f P) C = map_option (\c. snd(compC f (C,c))) (class P C)" +(*<*) +apply(simp add:compP_def compC_def class_def map_of_map4) +apply(simp add:split_def) +done +(*>*) + + +lemma sees_methods_compP: + "P \ C sees_methods Mm \ + compP f P \ C sees_methods (map_option (\((b,Ts,T,m),D). ((b,Ts,T,f b m),D)) \ Mm)" +(*<*) +apply(erule Methods.induct) + apply(rule sees_methods_Object) + apply(erule class_compP) + apply(rule ext) + apply(simp add:compM_def map_of_map245 option.map_comp) + apply(case_tac "map_of ms x") + apply simp + apply fastforce +apply(rule sees_methods_rec) + apply(erule class_compP) + apply assumption + apply assumption +apply(rule ext) +apply(simp add:map_add_def compM_def map_of_map245 option.map_comp split:option.split) +done +(*>*) + + +lemma sees_method_compP: + "P \ C sees M,b: Ts\T = m in D \ + compP f P \ C sees M,b: Ts\T = (f b m) in D" +(*<*)by(fastforce elim:sees_methods_compP simp add:Method_def)(*>*) + + +lemma [simp]: + "P \ C sees M,b: Ts\T = m in D \ + method (compP f P) C M = (D,b,Ts,T,f b m)" +(*<*) +apply(drule sees_method_compP) +apply(simp add:method_def) +apply(rule the_equality) + apply simp +apply(fastforce dest:sees_method_fun) +done +(*>*) + + +lemma sees_methods_compPD: + "\ cP \ C sees_methods Mm'; cP = compP f P \ \ + \Mm. P \ C sees_methods Mm \ + Mm' = (map_option (\((b,Ts,T,m),D). ((b,Ts,T,f b m),D)) \ Mm)" +(*<*) +apply(erule Methods.induct) + apply(clarsimp simp:compC_def) + apply(rule exI) + apply(rule conjI, erule sees_methods_Object) + apply(rule refl) + apply(rule ext) + apply(simp add:compM_def map_of_map245 option.map_comp) + apply(case_tac "map_of b x") + apply simp + apply fastforce +apply(clarsimp simp:compC_def) +apply(rule exI, rule conjI) + apply(erule (2) sees_methods_rec) + apply(rule refl) +apply(rule ext) +apply(simp add:map_add_def compM_def map_of_map245 option.map_comp split:option.split) +done +(*>*) + + +lemma sees_method_compPD: + "compP f P \ C sees M,b: Ts\T = fm in D \ + \m. P \ C sees M,b: Ts\T = m in D \ f b m = fm" +(*<*) +apply(simp add:Method_def) +apply clarify +apply(drule sees_methods_compPD[OF _ refl]) +apply clarsimp +apply blast +done +(*>*) + + +lemma [simp]: "subcls1(compP f P) = subcls1 P" +(*<*) +by(fastforce simp add: is_class_def compC_def intro:subcls1I order_antisym dest:subcls1D) +(*>*) + + +lemma compP_widen[simp]: "(compP f P \ T \ T') = (P \ T \ T')" +(*<*)by(cases T')(simp_all add:widen_Class)(*>*) + + +lemma [simp]: "(compP f P \ Ts [\] Ts') = (P \ Ts [\] Ts')" +(*<*) +apply(induct Ts) + apply simp +apply(cases Ts') + apply(auto simp:fun_of_def) +done +(*>*) + + +lemma [simp]: "is_type (compP f P) T = is_type P T" +(*<*)by(cases T) simp_all(*>*) + + +lemma [simp]: "(compP (f::staticb\'a\'b) P \ C has_fields FDTs) = (P \ C has_fields FDTs)" +(*<*) + (is "?A = ?B") +proof + { fix cP::"'b prog" assume "cP \ C has_fields FDTs" + hence "cP = compP f P \ P \ C has_fields FDTs" + proof induct + case has_fields_Object + thus ?case by(fast intro:Fields.has_fields_Object dest:class_compPD) + next + case has_fields_rec + thus ?case by(fast intro:Fields.has_fields_rec dest:class_compPD) + qed + } note lem = this + assume ?A + with lem show ?B by blast +next + assume ?B + thus ?A + proof induct + case has_fields_Object + thus ?case by(fast intro:Fields.has_fields_Object class_compP) + next + case has_fields_rec + thus ?case by(fast intro:Fields.has_fields_rec class_compP) + qed +qed +(*>*) + + +lemma fields_compP [simp]: "fields (compP f P) C = fields P C" +(*<*)by(simp add:fields_def)(*>*) + +lemma ifields_compP [simp]: "ifields (compP f P) C = ifields P C" +(*<*)by(simp add:ifields_def)(*>*) + +lemma blank_compP [simp]: "blank (compP f P) C = blank P C" +(*<*)by(simp add:blank_def)(*>*) + +lemma isfields_compP [simp]: "isfields (compP f P) C = isfields P C" +(*<*)by(simp add:isfields_def)(*>*) + +lemma sblank_compP [simp]: "sblank (compP f P) C = sblank P C" +(*<*)by(simp add:sblank_def)(*>*) + +lemma sees_fields_compP [simp]: "(compP f P \ C sees F,b:T in D) = (P \ C sees F,b:T in D)" +(*<*)by(simp add:sees_field_def)(*>*) + +lemma has_field_compP [simp]: "(compP f P \ C has F,b:T in D) = (P \ C has F,b:T in D)" +(*<*)by(simp add:has_field_def)(*>*) + +lemma field_compP [simp]: "field (compP f P) F D = field P F D" +(*<*)by(simp add:field_def)(*>*) + + +subsection\Invariance of @{term wf_prog} under compilation \ + +lemma [iff]: "distinct_fst (compP f P) = distinct_fst P" +(*<*) +apply(simp add:distinct_fst_def compP_def compC_def) +apply(induct P) +apply (auto simp:image_iff) +done +(*>*) + + +lemma [iff]: "distinct_fst (map (compM f) ms) = distinct_fst ms" +(*<*) +apply(simp add:distinct_fst_def compM_def) +apply(induct ms) +apply (auto simp:image_iff) +done +(*>*) + + +lemma [iff]: "wf_syscls (compP f P) = wf_syscls P" +(*<*)by(simp add:wf_syscls_def compP_def compC_def image_def Bex_def)(*>*) + + +lemma [iff]: "wf_fdecl (compP f P) = wf_fdecl P" +(*<*)by(simp add:wf_fdecl_def)(*>*) + + +lemma wf_clinit_compM [iff]: "wf_clinit (map (compM f) ms) = wf_clinit ms" +(*<*) +apply(simp add: wf_clinit_def compM_def) +apply(rule iffI) + apply clarsimp apply(rename_tac m) + apply(rule_tac x = m in exI, simp+) +apply clarsimp apply(rename_tac m) +apply(rule_tac x = "f Static m" in exI, simp add: rev_image_eqI) +done +(*>*) + +lemma set_compP: + "((C,D,fs,ms') \ set(compP f P)) = + (\ms. (C,D,fs,ms) \ set P \ ms' = map (compM f) ms)" +(*<*)by(fastforce simp add:compP_def compC_def image_iff Bex_def)(*>*) + +lemma wf_cdecl_compPI: + "\ \C M b Ts T m. + \ wf_mdecl wf\<^sub>1 P C (M,b,Ts,T,m); P \ C sees M,b:Ts\T = m in C \ + \ wf_mdecl wf\<^sub>2 (compP f P) C (M,b,Ts,T, f b m); + \x\set P. wf_cdecl wf\<^sub>1 P x; x \ set (compP f P); wf_prog p P \ + \ wf_cdecl wf\<^sub>2 (compP f P) x" +(*<*) +apply(clarsimp simp add:wf_cdecl_def Ball_def set_compP) +apply(rename_tac C D fs ms) +apply(rule conjI) + apply (clarsimp simp:compM_def) + apply (drule (2) mdecl_visible) + apply simp +apply(clarify) +apply(drule sees_method_compPD[where f = f]) +apply clarsimp +apply(fastforce simp:image_iff compM_def) +done +(*>*) + + +lemma wf_prog_compPI: +assumes lift: + "\C M b Ts T m. + \ P \ C sees M,b:Ts\T = m in C; wf_mdecl wf\<^sub>1 P C (M,b,Ts,T,m) \ + \ wf_mdecl wf\<^sub>2 (compP f P) C (M,b,Ts,T, f b m)" +and wf: "wf_prog wf\<^sub>1 P" +shows "wf_prog wf\<^sub>2 (compP f P)" +(*<*) +using wf +by (simp add:wf_prog_def) (blast intro:wf_cdecl_compPI lift wf) +(*>*) + + +end diff --git a/thys/JinjaDCI/Compiler/TypeComp.thy b/thys/JinjaDCI/Compiler/TypeComp.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/Compiler/TypeComp.thy @@ -0,0 +1,1471 @@ +(* Title: JinjaDCI/Compiler/TypeComp.thy + + Author: Tobias Nipkow, Susannah Mansky + Copyright TUM 2003, UIUC 2019-20 + + Based on the Jinja theory Compiler/TypeComp.thy by Tobias Nipkow +*) + +section \ Preservation of Well-Typedness \ + +theory TypeComp +imports Compiler "../BV/BVSpec" +begin + +(*<*) +declare nth_append[simp] +(*>*) + +lemma max_stack1: "P,E \\<^sub>1 e :: T \ 1 \ max_stack e" +(*<*)using max_stack1'[OF WT\<^sub>1_nsub_RI] by simp(*>*) + +locale TC0 = + fixes P :: "J\<^sub>1_prog" and mxl :: nat +begin + +definition "ty E e = (THE T. P,E \\<^sub>1 e :: T)" + +definition "ty\<^sub>l E A' = map (\i. if i \ A' \ i < size E then OK(E!i) else Err) [0..i' ST E A = (case A of None \ None | \A'\ \ Some(ST, ty\<^sub>l E A'))" + +definition "after E A ST e = ty\<^sub>i' (ty E e # ST) E (A \ \ e)" + +end + +lemma (in TC0) ty_def2 [simp]: "P,E \\<^sub>1 e :: T \ ty E e = T" +(*<*) +apply (unfold ty_def) +apply(blast intro: the_equality WT\<^sub>1_unique) +done +(*>*) + +lemma (in TC0) [simp]: "ty\<^sub>i' ST E None = None" +(*<*)by (simp add: ty\<^sub>i'_def)(*>*) + +lemma (in TC0) ty\<^sub>l_app_diff[simp]: + "ty\<^sub>l (E@[T]) (A - {size E}) = ty\<^sub>l E A" +(*<*)by(auto simp add:ty\<^sub>l_def hyperset_defs)(*>*) + + +lemma (in TC0) ty\<^sub>i'_app_diff[simp]: + "ty\<^sub>i' ST (E @ [T]) (A \ size E) = ty\<^sub>i' ST E A" +(*<*)by(auto simp add:ty\<^sub>i'_def hyperset_defs)(*>*) + + +lemma (in TC0) ty\<^sub>l_antimono: + "A \ A' \ P \ ty\<^sub>l E A' [\\<^sub>\] ty\<^sub>l E A" +(*<*)by(auto simp:ty\<^sub>l_def list_all2_conv_all_nth)(*>*) + + +lemma (in TC0) ty\<^sub>i'_antimono: + "A \ A' \ P \ ty\<^sub>i' ST E \A'\ \' ty\<^sub>i' ST E \A\" +(*<*)by(auto simp:ty\<^sub>i'_def ty\<^sub>l_def list_all2_conv_all_nth)(*>*) + + +lemma (in TC0) ty\<^sub>l_env_antimono: + "P \ ty\<^sub>l (E@[T]) A [\\<^sub>\] ty\<^sub>l E A" +(*<*)by(auto simp:ty\<^sub>l_def list_all2_conv_all_nth)(*>*) + + +lemma (in TC0) ty\<^sub>i'_env_antimono: + "P \ ty\<^sub>i' ST (E@[T]) A \' ty\<^sub>i' ST E A" +(*<*)by(auto simp:ty\<^sub>i'_def ty\<^sub>l_def list_all2_conv_all_nth)(*>*) + + +lemma (in TC0) ty\<^sub>i'_incr: + "P \ ty\<^sub>i' ST (E @ [T]) \insert (size E) A\ \' ty\<^sub>i' ST E \A\" +(*<*)by(auto simp:ty\<^sub>i'_def ty\<^sub>l_def list_all2_conv_all_nth)(*>*) + + +lemma (in TC0) ty\<^sub>l_incr: + "P \ ty\<^sub>l (E @ [T]) (insert (size E) A) [\\<^sub>\] ty\<^sub>l E A" +(*<*)by(auto simp: hyperset_defs ty\<^sub>l_def list_all2_conv_all_nth)(*>*) + + +lemma (in TC0) ty\<^sub>l_in_types: + "set E \ types P \ ty\<^sub>l E A \ list mxl (err (types P))" +(*<*)by(auto simp add:ty\<^sub>l_def intro!:listI dest!: nth_mem)(*>*) + +locale TC1 = TC0 +begin + +primrec compT :: "ty list \ nat hyperset \ ty list \ expr\<^sub>1 \ ty\<^sub>i' list" and + compTs :: "ty list \ nat hyperset \ ty list \ expr\<^sub>1 list \ ty\<^sub>i' list" where +"compT E A ST (new C) = []" +| "compT E A ST (Cast C e) = + compT E A ST e @ [after E A ST e]" +| "compT E A ST (Val v) = []" +| "compT E A ST (e\<^sub>1 \bop\ e\<^sub>2) = + (let ST\<^sub>1 = ty E e\<^sub>1#ST; A\<^sub>1 = A \ \ e\<^sub>1 in + compT E A ST e\<^sub>1 @ [after E A ST e\<^sub>1] @ + compT E A\<^sub>1 ST\<^sub>1 e\<^sub>2 @ [after E A\<^sub>1 ST\<^sub>1 e\<^sub>2])" +| "compT E A ST (Var i) = []" +| "compT E A ST (i := e) = compT E A ST e @ + [after E A ST e, ty\<^sub>i' ST E (A \ \ e \ \{i}\)]" +| "compT E A ST (e\F{D}) = + compT E A ST e @ [after E A ST e]" +| "compT E A ST (C\\<^sub>sF{D}) = []" +| "compT E A ST (e\<^sub>1\F{D} := e\<^sub>2) = + (let ST\<^sub>1 = ty E e\<^sub>1#ST; A\<^sub>1 = A \ \ e\<^sub>1; A\<^sub>2 = A\<^sub>1 \ \ e\<^sub>2 in + compT E A ST e\<^sub>1 @ [after E A ST e\<^sub>1] @ + compT E A\<^sub>1 ST\<^sub>1 e\<^sub>2 @ [after E A\<^sub>1 ST\<^sub>1 e\<^sub>2] @ + [ty\<^sub>i' ST E A\<^sub>2])" +| "compT E A ST (C\\<^sub>sF{D} := e\<^sub>2) = compT E A ST e\<^sub>2 @ [after E A ST e\<^sub>2] @ [ty\<^sub>i' ST E (A \ \ e\<^sub>2)]" +| "compT E A ST {i:T; e} = compT (E@[T]) (A\i) ST e" +| "compT E A ST (e\<^sub>1;;e\<^sub>2) = + (let A\<^sub>1 = A \ \ e\<^sub>1 in + compT E A ST e\<^sub>1 @ [after E A ST e\<^sub>1, ty\<^sub>i' ST E A\<^sub>1] @ + compT E A\<^sub>1 ST e\<^sub>2)" +| "compT E A ST (if (e) e\<^sub>1 else e\<^sub>2) = + (let A\<^sub>0 = A \ \ e; \ = ty\<^sub>i' ST E A\<^sub>0 in + compT E A ST e @ [after E A ST e, \] @ + compT E A\<^sub>0 ST e\<^sub>1 @ [after E A\<^sub>0 ST e\<^sub>1, \] @ + compT E A\<^sub>0 ST e\<^sub>2)" +| "compT E A ST (while (e) c) = + (let A\<^sub>0 = A \ \ e; A\<^sub>1 = A\<^sub>0 \ \ c; \ = ty\<^sub>i' ST E A\<^sub>0 in + compT E A ST e @ [after E A ST e, \] @ + compT E A\<^sub>0 ST c @ [after E A\<^sub>0 ST c, ty\<^sub>i' ST E A\<^sub>1, ty\<^sub>i' ST E A\<^sub>0])" +| "compT E A ST (throw e) = compT E A ST e @ [after E A ST e]" +| "compT E A ST (e\M(es)) = + compT E A ST e @ [after E A ST e] @ + compTs E (A \ \ e) (ty E e # ST) es" +| "compT E A ST (C\\<^sub>sM(es)) = compTs E A ST es" +| "compT E A ST (try e\<^sub>1 catch(C i) e\<^sub>2) = + compT E A ST e\<^sub>1 @ [after E A ST e\<^sub>1] @ + [ty\<^sub>i' (Class C#ST) E A, ty\<^sub>i' ST (E@[Class C]) (A \ \{i}\)] @ + compT (E@[Class C]) (A \ \{i}\) ST e\<^sub>2" +| "compT E A ST (INIT C (Cs,b) \ e) = []" +| "compT E A ST (RI(C,e');Cs \ e) = []" +| "compTs E A ST [] = []" +| "compTs E A ST (e#es) = compT E A ST e @ [after E A ST e] @ + compTs E (A \ (\ e)) (ty E e # ST) es" + +definition compT\<^sub>a :: "ty list \ nat hyperset \ ty list \ expr\<^sub>1 \ ty\<^sub>i' list" where + "compT\<^sub>a E A ST e = compT E A ST e @ [after E A ST e]" + +end + +lemma compE\<^sub>2_not_Nil[simp]: "P,E \\<^sub>1 e :: T \ compE\<^sub>2 e \ []" +(*<*)by(simp add: compE\<^sub>2_not_Nil' WT\<^sub>1_nsub_RI)(*>*) + +lemma (in TC1) compT_sizes': +shows "\E A ST. \sub_RI e \ size(compT E A ST e) = size(compE\<^sub>2 e) - 1" +and "\E A ST. \sub_RIs es \ size(compTs E A ST es) = size(compEs\<^sub>2 es)" +(*<*) +apply(induct e and es rule: compE\<^sub>2.induct compEs\<^sub>2.induct) +apply(auto split:bop.splits nat_diff_split simp: compE\<^sub>2_not_Nil') +done +(*>*) + +lemma (in TC1) compT_sizes[simp]: +shows "\E A ST. P,E \\<^sub>1 e :: T \ size(compT E A ST e) = size(compE\<^sub>2 e) - 1" +and "\E A ST. P,E \\<^sub>1 es [::] Ts \ size(compTs E A ST es) = size(compEs\<^sub>2 es)" +(*<*)using compT_sizes' WT\<^sub>1_nsub_RI WTs\<^sub>1_nsub_RIs by auto(*>*) + + +lemma (in TC1) [simp]: "\ST E. \\\ \ set (compT E None ST e)" +and [simp]: "\ST E. \\\ \ set (compTs E None ST es)" +(*<*)by(induct e and es rule: compT.induct compTs.induct) (simp_all add:after_def)(*>*) + + +lemma (in TC0) pair_eq_ty\<^sub>i'_conv: + "(\(ST, LT)\ = ty\<^sub>i' ST\<^sub>0 E A) = + (case A of None \ False | Some A \ (ST = ST\<^sub>0 \ LT = ty\<^sub>l E A))" +(*<*)by(simp add:ty\<^sub>i'_def)(*>*) + + +lemma (in TC0) pair_conv_ty\<^sub>i': + "\(ST, ty\<^sub>l E A)\ = ty\<^sub>i' ST E \A\" +(*<*)by(simp add:ty\<^sub>i'_def)(*>*) + +(*<*) +declare (in TC0) + ty\<^sub>i'_antimono [intro!] after_def[simp] + pair_conv_ty\<^sub>i'[simp] pair_eq_ty\<^sub>i'_conv[simp] +(*>*) + + +lemma (in TC1) compT_LT_prefix: + "\E A ST\<^sub>0. \ \(ST,LT)\ \ set(compT E A ST\<^sub>0 e); \ e (size E) \ + \ P \ \(ST,LT)\ \' ty\<^sub>i' ST E A" +and + "\E A ST\<^sub>0. \ \(ST,LT)\ \ set(compTs E A ST\<^sub>0 es); \s es (size E) \ + \ P \ \(ST,LT)\ \' ty\<^sub>i' ST E A" +(*<*) +proof(induct e and es rule: compT.induct compTs.induct) + case FAss thus ?case by(fastforce simp:hyperset_defs elim!:sup_state_opt_trans) +next + case BinOp thus ?case + by(fastforce simp:hyperset_defs elim!:sup_state_opt_trans split:bop.splits) +next + case Seq thus ?case by(fastforce simp:hyperset_defs elim!:sup_state_opt_trans) +next + case While thus ?case by(fastforce simp:hyperset_defs elim!:sup_state_opt_trans) +next + case Cond thus ?case by(fastforce simp:hyperset_defs elim!:sup_state_opt_trans) +next + case Block thus ?case + by(force simp add:hyperset_defs ty\<^sub>i'_def simp del:pair_conv_ty\<^sub>i' + elim!:sup_state_opt_trans) +next + case Call thus ?case by(fastforce simp:hyperset_defs elim!:sup_state_opt_trans) +next + case Cons_exp thus ?case + by(fastforce simp:hyperset_defs elim!:sup_state_opt_trans) +next + case TryCatch thus ?case + by(fastforce simp:hyperset_defs intro!: ty\<^sub>i'_incr + elim!:sup_state_opt_trans) +qed (auto simp:hyperset_defs) + +declare (in TC0) + ty\<^sub>i'_antimono [rule del] after_def[simp del] + pair_conv_ty\<^sub>i'[simp del] pair_eq_ty\<^sub>i'_conv[simp del] +(*>*) + + +lemma [iff]: "OK None \ states P mxs mxl" +(*<*)by(simp add: JVM_states_unfold)(*>*) + +lemma (in TC0) after_in_states: + "\ wf_prog p P; P,E \\<^sub>1 e :: T; set E \ types P; set ST \ types P; + size ST + max_stack e \ mxs \ + \ OK (after E A ST e) \ states P mxs mxl" +(*<*) +apply(subgoal_tac "size ST + 1 \ mxs") + apply(simp add: after_def ty\<^sub>i'_def JVM_states_unfold ty\<^sub>l_in_types) + apply(blast intro!:listI WT\<^sub>1_is_type) +using max_stack1[where e=e] apply fastforce +done +(*>*) + + +lemma (in TC0) OK_ty\<^sub>i'_in_statesI[simp]: + "\ set E \ types P; set ST \ types P; size ST \ mxs \ + \ OK (ty\<^sub>i' ST E A) \ states P mxs mxl" +(*<*) +apply(simp add:ty\<^sub>i'_def JVM_states_unfold ty\<^sub>l_in_types) +apply(blast intro!:listI) +done +(*>*) + + +lemma is_class_type_aux: "is_class P C \ is_type P (Class C)" +(*<*)by(simp)(*>*) + +(*<*) +declare is_type_simps[simp del] subsetI[rule del] +(*>*) + +theorem (in TC1) compT_states: +assumes wf: "wf_prog p P" +shows "\E T A ST. + \ P,E \\<^sub>1 e :: T; set E \ types P; set ST \ types P; + size ST + max_stack e \ mxs; size E + max_vars e \ mxl \ + \ OK ` set(compT E A ST e) \ states P mxs mxl" +(*<*)(is "\E T A ST. PROP ?P e E T A ST")(*>*) + +and "\E Ts A ST. + \ P,E \\<^sub>1 es[::]Ts; set E \ types P; set ST \ types P; + size ST + max_stacks es \ mxs; size E + max_varss es \ mxl \ + \ OK ` set(compTs E A ST es) \ states P mxs mxl" +(*<*)(is "\E Ts A ST. PROP ?Ps es E Ts A ST") +proof(induct e and es rule: compT.induct compTs.induct) + case new thus ?case by(simp) +next + case (Cast C e) thus ?case by (auto simp:after_in_states[OF wf]) +next + case Val thus ?case by(simp) +next + case Var thus ?case by(simp) +next + case LAss thus ?case by(auto simp:after_in_states[OF wf]) +next + case FAcc thus ?case by(auto simp:after_in_states[OF wf]) +next + case SFAcc thus ?case by(auto simp:after_in_states[OF wf]) +next + case FAss thus ?case + by(auto simp:image_Un WT\<^sub>1_is_type[OF wf] after_in_states[OF wf]) +next + case SFAss thus ?case + by(auto simp:image_Un WT\<^sub>1_is_type[OF wf] after_in_states[OF wf]) +next + case Seq thus ?case + by(auto simp:image_Un after_in_states[OF wf]) +next + case BinOp thus ?case + by(auto simp:image_Un WT\<^sub>1_is_type[OF wf] after_in_states[OF wf]) +next + case Cond thus ?case + by(force simp:image_Un WT\<^sub>1_is_type[OF wf] after_in_states[OF wf]) +next + case While thus ?case + by(auto simp:image_Un WT\<^sub>1_is_type[OF wf] after_in_states[OF wf]) +next + case Block thus ?case by(auto) +next + case (TryCatch e\<^sub>1 C i e\<^sub>2) + moreover have "size ST + 1 \ mxs" + using TryCatch.prems max_stack1[where e=e\<^sub>1] by fastforce + ultimately show ?case + by(auto simp:image_Un WT\<^sub>1_is_type[OF wf] after_in_states[OF wf] + is_class_type_aux) +next + case Nil_exp thus ?case by simp +next + case Cons_exp thus ?case + by(auto simp:image_Un WT\<^sub>1_is_type[OF wf] after_in_states[OF wf]) +next + case throw thus ?case + by(auto simp: WT\<^sub>1_is_type[OF wf] after_in_states[OF wf]) +next + case Call thus ?case + by(auto simp:image_Un WT\<^sub>1_is_type[OF wf] after_in_states[OF wf]) +next + case SCall thus ?case + by(auto simp:image_Un WT\<^sub>1_is_type[OF wf] after_in_states[OF wf]) +next + case INIT thus ?case by simp +next + case RI thus ?case by simp +qed + +declare is_type_simps[simp] subsetI[intro!] +(*>*) + + +definition shift :: "nat \ ex_table \ ex_table" +where + "shift n xt \ map (\(from,to,C,handler,depth). (from+n,to+n,C,handler+n,depth)) xt" + + +lemma [simp]: "shift 0 xt = xt" +(*<*)by(induct xt)(auto simp:shift_def)(*>*) + +lemma [simp]: "shift n [] = []" +(*<*)by(simp add:shift_def)(*>*) + +lemma [simp]: "shift n (xt\<^sub>1 @ xt\<^sub>2) = shift n xt\<^sub>1 @ shift n xt\<^sub>2" +(*<*)by(simp add:shift_def)(*>*) + +lemma [simp]: "shift m (shift n xt) = shift (m+n) xt" +(*<*)by(induct xt)(auto simp:shift_def)(*>*) + +lemma [simp]: "pcs (shift n xt) = {pc+n|pc. pc \ pcs xt}" +(*<*) +apply(auto simp:shift_def pcs_def) +apply(rule_tac x = "x-n" in exI) +apply (force split:nat_diff_split) +done +(*>*) + + +lemma shift_compxE\<^sub>2: +shows "\pc pc' d. shift pc (compxE\<^sub>2 e pc' d) = compxE\<^sub>2 e (pc' + pc) d" +and "\pc pc' d. shift pc (compxEs\<^sub>2 es pc' d) = compxEs\<^sub>2 es (pc' + pc) d" +(*<*) +apply(induct e and es rule: compxE\<^sub>2.induct compxEs\<^sub>2.induct) +apply(auto simp:shift_def ac_simps) +done +(*>*) + + +lemma compxE\<^sub>2_size_convs[simp]: +shows "n \ 0 \ compxE\<^sub>2 e n d = shift n (compxE\<^sub>2 e 0 d)" +and "n \ 0 \ compxEs\<^sub>2 es n d = shift n (compxEs\<^sub>2 es 0 d)" +(*<*)by(simp_all add:shift_compxE\<^sub>2)(*>*) + +locale TC2 = TC1 + + fixes T\<^sub>r :: ty and mxs :: pc +begin + +definition + wt_instrs :: "instr list \ ex_table \ ty\<^sub>i' list \ bool" + ("(\ _, _ /[::]/ _)" [0,0,51] 50) where + "\ is,xt [::] \s \ size is < size \s \ pcs xt \ {0.. + (\pc< size is. P,T\<^sub>r,mxs,size \s,xt \ is!pc,pc :: \s)" + +end + +notation TC2.wt_instrs ("(_,_,_ \/ _, _ /[::]/ _)" [50,50,50,50,50,51] 50) + +(*<*) +lemmas (in TC2) wt_defs = + wt_instrs_def wt_instr_def app_def eff_def norm_eff_def +(*>*) + +lemma (in TC2) [simp]: "\s \ [] \ \ [],[] [::] \s" +(*<*) by (simp add: wt_defs) (*>*) + +lemma [simp]: "eff i P pc et None = []" +(*<*)by (simp add: Effect.eff_def)(*>*) + +(*<*) +declare split_comp_eq[simp del] +(*>*) + +lemma wt_instr_appR: + "\ P,T,m,mpc,xt \ is!pc,pc :: \s; + pc < size is; size is < size \s; mpc \ size \s; mpc \ mpc' \ + \ P,T,m,mpc',xt \ is!pc,pc :: \s@\s'" +(*<*)by (fastforce simp:wt_instr_def app_def)(*>*) + + +lemma relevant_entries_shift [simp]: + "relevant_entries P i (pc+n) (shift n xt) = shift n (relevant_entries P i pc xt)" +(*<*) + apply (induct xt) + apply (unfold relevant_entries_def shift_def) + apply simp + apply (auto simp add: is_relevant_entry_def) + done +(*>*) + + +lemma [simp]: + "xcpt_eff i P (pc+n) \ (shift n xt) = + map (\(pc,\). (pc + n, \)) (xcpt_eff i P pc \ xt)" +(*<*) +apply(simp add: xcpt_eff_def) +apply(cases \) +apply(auto simp add: shift_def) +done +(*>*) + + +lemma [simp]: + "app\<^sub>i (i, P, pc, m, T, \) \ + eff i P (pc+n) (shift n xt) (Some \) = + map (\(pc,\). (pc+n,\)) (eff i P pc xt (Some \))" +(*<*) +apply(simp add:eff_def norm_eff_def) +apply(cases "i",auto) +done +(*>*) + + +lemma [simp]: + "xcpt_app i P (pc+n) mxs (shift n xt) \ = xcpt_app i P pc mxs xt \" +(*<*)by (simp add: xcpt_app_def) (auto simp add: shift_def)(*>*) + + +lemma wt_instr_appL: + "\ P,T,m,mpc,xt \ i,pc :: \s; pc < size \s; mpc \ size \s \ + \ P,T,m,mpc + size \s',shift (size \s') xt \ i,pc+size \s' :: \s'@\s" +(*<*) +apply(auto simp:wt_instr_def app_def) +prefer 2 apply(fast) +prefer 2 apply(fast) +apply(cases "i",auto) +done +(*>*) + + +lemma wt_instr_Cons: + "\ P,T,m,mpc - 1,[] \ i,pc - 1 :: \s; + 0 < pc; 0 < mpc; pc < size \s + 1; mpc \ size \s + 1 \ + \ P,T,m,mpc,[] \ i,pc :: \#\s" +(*<*) +apply(drule wt_instr_appL[where \s' = "[\]"]) +apply arith +apply arith +apply (simp split:nat_diff_split_asm) +done +(*>*) + + +lemma wt_instr_append: + "\ P,T,m,mpc - size \s',[] \ i,pc - size \s' :: \s; + size \s' \ pc; size \s' \ mpc; pc < size \s + size \s'; mpc \ size \s + size \s' \ + \ P,T,m,mpc,[] \ i,pc :: \s'@\s" +(*<*) +apply(drule wt_instr_appL[where \s' = \s']) +apply arith +apply arith +apply (simp split:nat_diff_split_asm) +done +(*>*) + + +lemma xcpt_app_pcs: + "pc \ pcs xt \ xcpt_app i P pc mxs xt \" +(*<*) +by (auto simp add: xcpt_app_def relevant_entries_def is_relevant_entry_def pcs_def) +(*>*) + + +lemma xcpt_eff_pcs: + "pc \ pcs xt \ xcpt_eff i P pc \ xt = []" +(*<*) +by (cases \) + (auto simp add: is_relevant_entry_def xcpt_eff_def relevant_entries_def pcs_def + intro!: filter_False) +(*>*) + + +lemma pcs_shift: + "pc < n \ pc \ pcs (shift n xt)" +(*<*)by (auto simp add: shift_def pcs_def)(*>*) + + +lemma wt_instr_appRx: + "\ P,T,m,mpc,xt \ is!pc,pc :: \s; pc < size is; size is < size \s; mpc \ size \s \ + \ P,T,m,mpc,xt @ shift (size is) xt' \ is!pc,pc :: \s" +(*<*)by (auto simp:wt_instr_def eff_def app_def xcpt_app_pcs xcpt_eff_pcs)(*>*) + + +lemma wt_instr_appLx: + "\ P,T,m,mpc,xt \ i,pc :: \s; pc \ pcs xt' \ + \ P,T,m,mpc,xt'@xt \ i,pc :: \s" +(*<*)by (auto simp:wt_instr_def app_def eff_def xcpt_app_pcs xcpt_eff_pcs)(*>*) + + +lemma (in TC2) wt_instrs_extR: + "\ is,xt [::] \s \ \ is,xt [::] \s @ \s'" +(*<*)by(auto simp add:wt_instrs_def wt_instr_appR)(*>*) + + +lemma (in TC2) wt_instrs_ext: + "\ \ is\<^sub>1,xt\<^sub>1 [::] \s\<^sub>1@\s\<^sub>2; \ is\<^sub>2,xt\<^sub>2 [::] \s\<^sub>2; size \s\<^sub>1 = size is\<^sub>1 \ + \ \ is\<^sub>1@is\<^sub>2, xt\<^sub>1 @ shift (size is\<^sub>1) xt\<^sub>2 [::] \s\<^sub>1@\s\<^sub>2" +(*<*) +apply(clarsimp simp:wt_instrs_def) +apply(rule conjI, fastforce) +apply(rule conjI, fastforce) +apply clarsimp +apply(rule conjI, fastforce simp:wt_instr_appRx) +apply clarsimp +apply(erule_tac x = "pc - size is\<^sub>1" in allE)+ +apply(thin_tac "P \ Q" for P Q) +apply(erule impE, arith) +apply(drule_tac \s' = "\s\<^sub>1" in wt_instr_appL) + apply arith + apply simp +apply(fastforce simp add:add.commute intro!: wt_instr_appLx) +done +(*>*) + +corollary (in TC2) wt_instrs_ext2: + "\ \ is\<^sub>2,xt\<^sub>2 [::] \s\<^sub>2; \ is\<^sub>1,xt\<^sub>1 [::] \s\<^sub>1@\s\<^sub>2; size \s\<^sub>1 = size is\<^sub>1 \ + \ \ is\<^sub>1@is\<^sub>2, xt\<^sub>1 @ shift (size is\<^sub>1) xt\<^sub>2 [::] \s\<^sub>1@\s\<^sub>2" +(*<*)by(rule wt_instrs_ext)(*>*) + + +corollary (in TC2) wt_instrs_ext_prefix [trans]: + "\ \ is\<^sub>1,xt\<^sub>1 [::] \s\<^sub>1@\s\<^sub>2; \ is\<^sub>2,xt\<^sub>2 [::] \s\<^sub>3; + size \s\<^sub>1 = size is\<^sub>1; prefix \s\<^sub>3 \s\<^sub>2 \ + \ \ is\<^sub>1@is\<^sub>2, xt\<^sub>1 @ shift (size is\<^sub>1) xt\<^sub>2 [::] \s\<^sub>1@\s\<^sub>2" +(*<*)by(bestsimp simp:prefix_def elim: wt_instrs_ext dest:wt_instrs_extR)(*>*) + + +corollary (in TC2) wt_instrs_app: + assumes is\<^sub>1: "\ is\<^sub>1,xt\<^sub>1 [::] \s\<^sub>1@[\]" + assumes is\<^sub>2: "\ is\<^sub>2,xt\<^sub>2 [::] \#\s\<^sub>2" + assumes s: "size \s\<^sub>1 = size is\<^sub>1" + shows "\ is\<^sub>1@is\<^sub>2, xt\<^sub>1@shift (size is\<^sub>1) xt\<^sub>2 [::] \s\<^sub>1@\#\s\<^sub>2" +(*<*) +proof - + from is\<^sub>1 have "\ is\<^sub>1,xt\<^sub>1 [::] (\s\<^sub>1@[\])@\s\<^sub>2" + by (rule wt_instrs_extR) + hence "\ is\<^sub>1,xt\<^sub>1 [::] \s\<^sub>1@\#\s\<^sub>2" by simp + from this is\<^sub>2 s show ?thesis by (rule wt_instrs_ext) +qed +(*>*) + + +corollary (in TC2) wt_instrs_app_last[trans]: + "\ \ is\<^sub>2,xt\<^sub>2 [::] \#\s\<^sub>2; \ is\<^sub>1,xt\<^sub>1 [::] \s\<^sub>1; + last \s\<^sub>1 = \; size \s\<^sub>1 = size is\<^sub>1+1 \ + \ \ is\<^sub>1@is\<^sub>2, xt\<^sub>1@shift (size is\<^sub>1) xt\<^sub>2 [::] \s\<^sub>1@\s\<^sub>2" +(*<*) +apply(cases \s\<^sub>1 rule:rev_cases) + apply simp +apply(simp add:wt_instrs_app) +done +(*>*) + + +corollary (in TC2) wt_instrs_append_last[trans]: + "\ \ is,xt [::] \s; P,T\<^sub>r,mxs,mpc,[] \ i,pc :: \s; + pc = size is; mpc = size \s; size is + 1 < size \s \ + \ \ is@[i],xt [::] \s" +(*<*) +apply(clarsimp simp add:wt_instrs_def) +apply(rule conjI, fastforce) +apply(fastforce intro!:wt_instr_appLx[where xt = "[]",simplified] + dest!:less_antisym) +done +(*>*) + + +corollary (in TC2) wt_instrs_app2: + "\ \ is\<^sub>2,xt\<^sub>2 [::] \'#\s\<^sub>2; \ is\<^sub>1,xt\<^sub>1 [::] \#\s\<^sub>1@[\']; + xt' = xt\<^sub>1 @ shift (size is\<^sub>1) xt\<^sub>2; size \s\<^sub>1+1 = size is\<^sub>1 \ + \ \ is\<^sub>1@is\<^sub>2,xt' [::] \#\s\<^sub>1@\'#\s\<^sub>2" +(*<*)using wt_instrs_app[where ?\s\<^sub>1.0 = "\ # \s\<^sub>1"] by simp (*>*) + + +corollary (in TC2) wt_instrs_app2_simp[trans,simp]: + "\ \ is\<^sub>2,xt\<^sub>2 [::] \'#\s\<^sub>2; \ is\<^sub>1,xt\<^sub>1 [::] \#\s\<^sub>1@[\']; size \s\<^sub>1+1 = size is\<^sub>1 \ + \ \ is\<^sub>1@is\<^sub>2, xt\<^sub>1@shift (size is\<^sub>1) xt\<^sub>2 [::] \#\s\<^sub>1@\'#\s\<^sub>2" +(*<*)using wt_instrs_app[where ?\s\<^sub>1.0 = "\ # \s\<^sub>1"] by simp(*>*) + + +corollary (in TC2) wt_instrs_Cons[simp]: + "\ \s \ []; \ [i],[] [::] [\,\']; \ is,xt [::] \'#\s \ + \ \ i#is,shift 1 xt [::] \#\'#\s" +(*<*) +using wt_instrs_app2[where ?is\<^sub>1.0 = "[i]" and ?\s\<^sub>1.0 = "[]" and ?is\<^sub>2.0 = "is" + and ?xt\<^sub>1.0 = "[]"] +by simp + + +corollary (in TC2) wt_instrs_Cons2[trans]: + assumes \s: "\ is,xt [::] \s" + assumes i: "P,T\<^sub>r,mxs,mpc,[] \ i,0 :: \#\s" + assumes mpc: "mpc = size \s + 1" + shows "\ i#is,shift 1 xt [::] \#\s" +(*<*) +proof - + from \s have "\s \ []" by (auto simp: wt_instrs_def) + with mpc i have "\ [i],[] [::] [\]@\s" by (simp add: wt_instrs_def) + with \s show ?thesis by (fastforce dest: wt_instrs_ext) +qed +(*>*) + + +lemma (in TC2) wt_instrs_last_incr[trans]: + "\ \ is,xt [::] \s@[\]; P \ \ \' \' \ \ \ is,xt [::] \s@[\']" +(*<*) +apply(clarsimp simp add:wt_instrs_def wt_instr_def) +apply(rule conjI) +apply(fastforce) +apply(clarsimp) +apply(rename_tac pc' tau') +apply(erule allE, erule (1) impE) +apply(clarsimp) +apply(drule (1) bspec) +apply(clarsimp) +apply(subgoal_tac "pc' = size \s") +prefer 2 +apply(clarsimp simp:app_def) +apply(drule (1) bspec) +apply(clarsimp) +apply(auto elim!:sup_state_opt_trans) +done +(*>*) + + +lemma [iff]: "xcpt_app i P pc mxs [] \" +(*<*)by (simp add: xcpt_app_def relevant_entries_def)(*>*) + + +lemma [simp]: "xcpt_eff i P pc \ [] = []" +(*<*)by (simp add: xcpt_eff_def relevant_entries_def)(*>*) + + +lemma (in TC2) wt_New: + "\ is_class P C; size ST < mxs \ \ + \ [New C],[] [::] [ty\<^sub>i' ST E A, ty\<^sub>i' (Class C#ST) E A]" +(*<*)by(simp add:wt_defs ty\<^sub>i'_def)(*>*) + + +lemma (in TC2) wt_Cast: + "is_class P C \ + \ [Checkcast C],[] [::] [ty\<^sub>i' (Class D # ST) E A, ty\<^sub>i' (Class C # ST) E A]" +(*<*)by(simp add: ty\<^sub>i'_def wt_defs)(*>*) + + +lemma (in TC2) wt_Push: + "\ size ST < mxs; typeof v = Some T \ + \ \ [Push v],[] [::] [ty\<^sub>i' ST E A, ty\<^sub>i' (T#ST) E A]" +(*<*)by(simp add: ty\<^sub>i'_def wt_defs)(*>*) + + +lemma (in TC2) wt_Pop: + "\ [Pop],[] [::] (ty\<^sub>i' (T#ST) E A # ty\<^sub>i' ST E A # \s)" +(*<*)by(simp add: ty\<^sub>i'_def wt_defs)(*>*) + + +lemma (in TC2) wt_CmpEq: + "\ P \ T\<^sub>1 \ T\<^sub>2 \ P \ T\<^sub>2 \ T\<^sub>1\ + \ \ [CmpEq],[] [::] [ty\<^sub>i' (T\<^sub>2 # T\<^sub>1 # ST) E A, ty\<^sub>i' (Boolean # ST) E A]" +(*<*) by(auto simp:ty\<^sub>i'_def wt_defs elim!: refTE not_refTE) (*>*) + + +lemma (in TC2) wt_IAdd: + "\ [IAdd],[] [::] [ty\<^sub>i' (Integer#Integer#ST) E A, ty\<^sub>i' (Integer#ST) E A]" +(*<*)by(simp add:ty\<^sub>i'_def wt_defs)(*>*) + + +lemma (in TC2) wt_Load: + "\ size ST < mxs; size E \ mxl; i \\ A; i < size E \ + \ \ [Load i],[] [::] [ty\<^sub>i' ST E A, ty\<^sub>i' (E!i # ST) E A]" +(*<*)by(auto simp add:ty\<^sub>i'_def wt_defs ty\<^sub>l_def hyperset_defs)(*>*) + + +lemma (in TC2) wt_Store: + "\ P \ T \ E!i; i < size E; size E \ mxl \ \ + \ [Store i],[] [::] [ty\<^sub>i' (T#ST) E A, ty\<^sub>i' ST E (\{i}\ \ A)]" +(*<*) +by(auto simp:hyperset_defs nth_list_update ty\<^sub>i'_def wt_defs ty\<^sub>l_def + intro:list_all2_all_nthI) +(*>*) + + +lemma (in TC2) wt_Get: + "\ P \ C sees F,NonStatic:T in D \ \ + \ [Getfield F D],[] [::] [ty\<^sub>i' (Class C # ST) E A, ty\<^sub>i' (T # ST) E A]" +(*<*)by(auto simp: ty\<^sub>i'_def wt_defs dest: sees_field_idemp sees_field_decl_above)(*>*) + +lemma (in TC2) wt_GetS: + "\ size ST < mxs; P \ C sees F,Static:T in D \ \ + \ [Getstatic C F D],[] [::] [ty\<^sub>i' ST E A, ty\<^sub>i' (T # ST) E A]" +(*<*)by(auto simp: ty\<^sub>i'_def wt_defs dest: sees_field_idemp sees_field_decl_above)(*>*) + +lemma (in TC2) wt_Put: + "\ P \ C sees F,NonStatic:T in D; P \ T' \ T \ \ + \ [Putfield F D],[] [::] [ty\<^sub>i' (T' # Class C # ST) E A, ty\<^sub>i' ST E A]" +(*<*)by(auto intro: sees_field_idemp sees_field_decl_above simp: ty\<^sub>i'_def wt_defs)(*>*) + +lemma (in TC2) wt_PutS: + "\ P \ C sees F,Static:T in D; P \ T' \ T \ \ + \ [Putstatic C F D],[] [::] [ty\<^sub>i' (T' # ST) E A, ty\<^sub>i' ST E A]" +(*<*)by(auto intro: sees_field_idemp sees_field_decl_above simp: ty\<^sub>i'_def wt_defs)(*>*) + + +lemma (in TC2) wt_Throw: + "\ [Throw],[] [::] [ty\<^sub>i' (Class C # ST) E A, \']" +(*<*)by(auto simp: ty\<^sub>i'_def wt_defs)(*>*) + + +lemma (in TC2) wt_IfFalse: + "\ 2 \ i; nat i < size \s + 2; P \ ty\<^sub>i' ST E A \' \s ! nat(i - 2) \ + \ \ [IfFalse i],[] [::] ty\<^sub>i' (Boolean # ST) E A # ty\<^sub>i' ST E A # \s" +(*<*) +by(simp add: ty\<^sub>i'_def wt_defs eval_nat_numeral nat_diff_distrib) +(*>*) + + +lemma wt_Goto: + "\ 0 \ int pc + i; nat (int pc + i) < size \s; size \s \ mpc; + P \ \s!pc \' \s ! nat (int pc + i) \ + \ P,T,mxs,mpc,[] \ Goto i,pc :: \s" +(*<*)by(clarsimp simp add: TC2.wt_defs)(*>*) + + +lemma (in TC2) wt_Invoke: + "\ size es = size Ts'; P \ C sees M,NonStatic: Ts\T = m in D; P \ Ts' [\] Ts \ + \ \ [Invoke M (size es)],[] [::] [ty\<^sub>i' (rev Ts' @ Class C # ST) E A, ty\<^sub>i' (T#ST) E A]" +(*<*)by(fastforce simp add: ty\<^sub>i'_def wt_defs)(*>*) + +lemma (in TC2) wt_Invokestatic: + "\ size ST < mxs; size es = size Ts'; M \ clinit; + P \ C sees M,Static: Ts\T = m in D; P \ Ts' [\] Ts \ + \ \ [Invokestatic C M (size es)],[] [::] [ty\<^sub>i' (rev Ts' @ ST) E A, ty\<^sub>i' (T#ST) E A]" +(*<*)by(fastforce simp add: ty\<^sub>i'_def wt_defs)(*>*) + + +corollary (in TC2) wt_instrs_app3[simp]: + "\ \ is\<^sub>2,[] [::] (\' # \s\<^sub>2); \ is\<^sub>1,xt\<^sub>1 [::] \ # \s\<^sub>1 @ [\']; size \s\<^sub>1+1 = size is\<^sub>1\ + \ \ (is\<^sub>1 @ is\<^sub>2),xt\<^sub>1 [::] \ # \s\<^sub>1 @ \' # \s\<^sub>2" +(*<*)using wt_instrs_app2[where ?xt\<^sub>2.0 = "[]"] by (simp add:shift_def)(*>*) + + +corollary (in TC2) wt_instrs_Cons3[simp]: + "\ \s \ []; \ [i],[] [::] [\,\']; \ is,[] [::] \'#\s \ + \ \ (i # is),[] [::] \ # \' # \s" +(*<*) +using wt_instrs_Cons[where ?xt = "[]"] +by (simp add:shift_def) + +(*<*) +declare nth_append[simp del] +declare [[simproc del: list_to_set_comprehension]] +(*>*) + +lemma (in TC2) wt_instrs_xapp[trans]: + "\ \ is\<^sub>1 @ is\<^sub>2, xt [::] \s\<^sub>1 @ ty\<^sub>i' (Class C # ST) E A # \s\<^sub>2; + \\ \ set \s\<^sub>1. \ST' LT'. \ = Some(ST',LT') \ + size ST \ size ST' \ P \ Some (drop (size ST' - size ST) ST',LT') \' ty\<^sub>i' ST E A; + size is\<^sub>1 = size \s\<^sub>1; is_class P C; size ST < mxs \ \ + \ is\<^sub>1 @ is\<^sub>2, xt @ [(0,size is\<^sub>1 - 1,C,size is\<^sub>1,size ST)] [::] \s\<^sub>1 @ ty\<^sub>i' (Class C # ST) E A # \s\<^sub>2" +(*<*) +apply(simp add:wt_instrs_def) +apply(rule conjI) + apply(clarsimp) + apply arith +apply clarsimp +apply(erule allE, erule (1) impE) +apply(clarsimp simp add: wt_instr_def app_def eff_def) +apply(rule conjI) + apply (thin_tac "\x\ A \ B. P x" for A B P) + apply (thin_tac "\x\ A \ B. P x" for A B P) + apply (clarsimp simp add: xcpt_app_def relevant_entries_def) + apply (simp add: nth_append is_relevant_entry_def split!: if_splits) + apply (drule_tac x="\s\<^sub>1!pc" in bspec) + apply (blast intro: nth_mem) + apply fastforce +apply (rule conjI) + apply clarsimp + apply (erule disjE, blast) + apply (erule disjE, blast) + apply (clarsimp simp add: xcpt_eff_def relevant_entries_def split: if_split_asm) +apply clarsimp +apply (erule disjE, blast) +apply (erule disjE, blast) +apply (clarsimp simp add: xcpt_eff_def relevant_entries_def split: if_split_asm) +apply (simp add: nth_append is_relevant_entry_def split: if_split_asm) + apply (drule_tac x = "\s\<^sub>1!pc" in bspec) + apply (blast intro: nth_mem) + apply (fastforce simp add: ty\<^sub>i'_def) +done + +declare [[simproc add: list_to_set_comprehension]] +declare nth_append[simp] +(*>*) + +lemma drop_Cons_Suc: + "\xs. drop n xs = y#ys \ drop (Suc n) xs = ys" + apply (induct n) + apply simp + apply (simp add: drop_Suc) + done + +lemma drop_mess: + "\Suc (length xs\<^sub>0) \ length xs; drop (length xs - Suc (length xs\<^sub>0)) xs = x # xs\<^sub>0\ + \ drop (length xs - length xs\<^sub>0) xs = xs\<^sub>0" +apply (cases xs) + apply simp +apply (simp add: Suc_diff_le) +apply (case_tac "length list - length xs\<^sub>0") + apply simp +apply (simp add: drop_Cons_Suc) +done + +(*<*) +declare (in TC0) + after_def[simp] pair_eq_ty\<^sub>i'_conv[simp] +(*>*) + +lemma (in TC1) compT_ST_prefix: + "\E A ST\<^sub>0. \(ST,LT)\ \ set(compT E A ST\<^sub>0 e) \ + size ST\<^sub>0 \ size ST \ drop (size ST - size ST\<^sub>0) ST = ST\<^sub>0" +and + "\E A ST\<^sub>0. \(ST,LT)\ \ set(compTs E A ST\<^sub>0 es) \ + size ST\<^sub>0 \ size ST \ drop (size ST - size ST\<^sub>0) ST = ST\<^sub>0" +(*<*) +proof(induct e and es rule: compT.induct compTs.induct) + case (FAss e\<^sub>1 F D e\<^sub>2) + moreover { + let ?ST\<^sub>0 = "ty E e\<^sub>1 # ST\<^sub>0" + fix A assume "\(ST, LT)\ \ set (compT E A ?ST\<^sub>0 e\<^sub>2)" + with FAss + have "length ?ST\<^sub>0 \ length ST \ drop (size ST - size ?ST\<^sub>0) ST = ?ST\<^sub>0" by blast + hence ?case by (clarsimp simp add: drop_mess) + } + ultimately show ?case by auto +next + case TryCatch thus ?case by auto +next + case Block thus ?case by auto +next + case Seq thus ?case by auto +next + case While thus ?case by auto +next + case Cond thus ?case by auto +next + case (Call e M es) + moreover { + let ?ST\<^sub>0 = "ty E e # ST\<^sub>0" + fix A assume "\(ST, LT)\ \ set (compTs E A ?ST\<^sub>0 es)" + with Call + have "length ?ST\<^sub>0 \ length ST \ drop (size ST - size ?ST\<^sub>0) ST = ?ST\<^sub>0" by blast + hence ?case by (clarsimp simp add: drop_mess) + } + ultimately show ?case by auto +next + case (Cons_exp e es) + moreover { + let ?ST\<^sub>0 = "ty E e # ST\<^sub>0" + fix A assume "\(ST, LT)\ \ set (compTs E A ?ST\<^sub>0 es)" + with Cons_exp + have "length ?ST\<^sub>0 \ length ST \ drop (size ST - size ?ST\<^sub>0) ST = ?ST\<^sub>0" by blast + hence ?case by (clarsimp simp add: drop_mess) + } + ultimately show ?case by auto +next + case (BinOp e\<^sub>1 bop e\<^sub>2) + moreover { + let ?ST\<^sub>0 = "ty E e\<^sub>1 # ST\<^sub>0" + fix A assume "\(ST, LT)\ \ set (compT E A ?ST\<^sub>0 e\<^sub>2)" + with BinOp + have "length ?ST\<^sub>0 \ length ST \ drop (size ST - size ?ST\<^sub>0) ST = ?ST\<^sub>0" by blast + hence ?case by (clarsimp simp add: drop_mess) + } + ultimately show ?case by auto +next + case new thus ?case by auto +next + case Val thus ?case by auto +next + case Cast thus ?case by auto +next + case Var thus ?case by auto +next + case LAss thus ?case by auto +next + case throw thus ?case by auto +next + case FAcc thus ?case by auto +next + case SFAcc thus ?case by auto +next + case SFAss thus ?case by auto +next + case (SCall C M es) thus ?case by auto +next + case INIT thus ?case by auto +next + case RI thus ?case by auto +next + case Nil_exp thus ?case by auto +qed + +declare (in TC0) + after_def[simp del] pair_eq_ty\<^sub>i'_conv[simp del] +(*>*) + +(* FIXME *) +lemma fun_of_simp [simp]: "fun_of S x y = ((x,y) \ S)" +(*<*) by (simp add: fun_of_def)(*>*) + +theorem (in TC2) compT_wt_instrs: "\E T A ST. + \ P,E \\<^sub>1 e :: T; \ e A; \ e (size E); + size ST + max_stack e \ mxs; size E + max_vars e \ mxl \ + \ \ compE\<^sub>2 e, compxE\<^sub>2 e 0 (size ST) [::] + ty\<^sub>i' ST E A # compT E A ST e @ [after E A ST e]" +(*<*)(is "\E T A ST. PROP ?P e E T A ST")(*>*) + +and "\E Ts A ST. + \ P,E \\<^sub>1 es[::]Ts; \s es A; \s es (size E); + size ST + max_stacks es \ mxs; size E + max_varss es \ mxl \ + \ let \s = ty\<^sub>i' ST E A # compTs E A ST es in + \ compEs\<^sub>2 es,compxEs\<^sub>2 es 0 (size ST) [::] \s \ + last \s = ty\<^sub>i' (rev Ts @ ST) E (A \ \s es)" +(*<*) +(is "\E Ts A ST. PROP ?Ps es E Ts A ST") +proof(induct e and es rule: compxE\<^sub>2.induct compxEs\<^sub>2.induct) + case (TryCatch e\<^sub>1 C i e\<^sub>2) + hence [simp]: "i = size E" by simp + have wt\<^sub>1: "P,E \\<^sub>1 e\<^sub>1 :: T" and wt\<^sub>2: "P,E@[Class C] \\<^sub>1 e\<^sub>2 :: T" + and "class": "is_class P C" using TryCatch by auto + let ?A\<^sub>1 = "A \ \ e\<^sub>1" let ?A\<^sub>i = "A \ \{i}\" let ?E\<^sub>i = "E @ [Class C]" + let ?\ = "ty\<^sub>i' ST E A" let ?\s\<^sub>1 = "compT E A ST e\<^sub>1" + let ?\\<^sub>1 = "ty\<^sub>i' (T#ST) E ?A\<^sub>1" let ?\\<^sub>2 = "ty\<^sub>i' (Class C#ST) E A" + let ?\\<^sub>3 = "ty\<^sub>i' ST ?E\<^sub>i ?A\<^sub>i" let ?\s\<^sub>2 = "compT ?E\<^sub>i ?A\<^sub>i ST e\<^sub>2" + let ?\\<^sub>2' = "ty\<^sub>i' (T#ST) ?E\<^sub>i (?A\<^sub>i \ \ e\<^sub>2)" + let ?\' = "ty\<^sub>i' (T#ST) E (A \ \ e\<^sub>1 \ (\ e\<^sub>2 \ i))" + let ?go = "Goto (int(size(compE\<^sub>2 e\<^sub>2)) + 2)" + have "PROP ?P e\<^sub>2 ?E\<^sub>i T ?A\<^sub>i ST" by fact + hence "\ compE\<^sub>2 e\<^sub>2,compxE\<^sub>2 e\<^sub>2 0 (size ST) [::] (?\\<^sub>3 # ?\s\<^sub>2) @ [?\\<^sub>2']" + using TryCatch.prems by(auto simp:after_def) + also have "?A\<^sub>i \ \ e\<^sub>2 = (A \ \ e\<^sub>2) \ \{size E}\" + by(fastforce simp:hyperset_defs) + also have "P \ ty\<^sub>i' (T#ST) ?E\<^sub>i \ \' ty\<^sub>i' (T#ST) E (A \ \ e\<^sub>2)" + by(simp add:hyperset_defs ty\<^sub>l_incr ty\<^sub>i'_def) + also have "P \ \ \' ty\<^sub>i' (T#ST) E (A \ \ e\<^sub>1 \ (\ e\<^sub>2 \ i))" + by(auto intro!: ty\<^sub>l_antimono simp:hyperset_defs ty\<^sub>i'_def) + also have "(?\\<^sub>3 # ?\s\<^sub>2) @ [?\'] = ?\\<^sub>3 # ?\s\<^sub>2 @ [?\']" by simp + also have "\ [Store i],[] [::] ?\\<^sub>2 # [] @ [?\\<^sub>3]" + using TryCatch.prems + by(auto simp:nth_list_update wt_defs ty\<^sub>i'_def ty\<^sub>l_def + list_all2_conv_all_nth hyperset_defs) + also have "[] @ (?\\<^sub>3 # ?\s\<^sub>2 @ [?\']) = (?\\<^sub>3 # ?\s\<^sub>2 @ [?\'])" by simp + also have "P,T\<^sub>r,mxs,size(compE\<^sub>2 e\<^sub>2)+3,[] \ ?go,0 :: ?\\<^sub>1#?\\<^sub>2#?\\<^sub>3#?\s\<^sub>2 @ [?\']" using wt\<^sub>2 + by (auto simp: hyperset_defs ty\<^sub>i'_def wt_defs nth_Cons nat_add_distrib + fun_of_def intro: ty\<^sub>l_antimono list_all2_refl split:nat.split) + also have "\ compE\<^sub>2 e\<^sub>1,compxE\<^sub>2 e\<^sub>1 0 (size ST) [::] ?\ # ?\s\<^sub>1 @ [?\\<^sub>1]" + using TryCatch by(auto simp:after_def) + also have "?\ # ?\s\<^sub>1 @ ?\\<^sub>1 # ?\\<^sub>2 # ?\\<^sub>3 # ?\s\<^sub>2 @ [?\'] = + (?\ # ?\s\<^sub>1 @ [?\\<^sub>1]) @ ?\\<^sub>2 # ?\\<^sub>3 # ?\s\<^sub>2 @ [?\']" by simp + also have "compE\<^sub>2 e\<^sub>1 @ ?go # [Store i] @ compE\<^sub>2 e\<^sub>2 = + (compE\<^sub>2 e\<^sub>1 @ [?go]) @ (Store i # compE\<^sub>2 e\<^sub>2)" by simp + also + let "?Q \" = "\ST' LT'. \ = \(ST', LT')\ \ + size ST \ size ST' \ P \ Some (drop (size ST' - size ST) ST',LT') \' ty\<^sub>i' ST E A" + { + have "?Q (ty\<^sub>i' ST E A)" by (clarsimp simp add: ty\<^sub>i'_def) + moreover have "?Q (ty\<^sub>i' (T # ST) E ?A\<^sub>1)" + by (fastforce simp add: ty\<^sub>i'_def hyperset_defs intro!: ty\<^sub>l_antimono) + moreover have "\\. \ \ set (compT E A ST e\<^sub>1) \ ?Q \" using TryCatch.prems + by clarsimp (frule compT_ST_prefix, + fastforce dest!: compT_LT_prefix simp add: ty\<^sub>i'_def) + ultimately + have "\\\set (ty\<^sub>i' ST E A # compT E A ST e\<^sub>1 @ [ty\<^sub>i' (T # ST) E ?A\<^sub>1]). ?Q \" + by auto + } + also from TryCatch.prems max_stack1[OF wt\<^sub>1] have "size ST + 1 \ mxs" by auto + ultimately show ?case using wt\<^sub>1 wt\<^sub>2 TryCatch.prems "class" + by (simp add:after_def) +next + case new thus ?case by(auto simp add:after_def wt_New) +next + case (BinOp e\<^sub>1 bop e\<^sub>2) + let ?op = "case bop of Eq \ [CmpEq] | Add \ [IAdd]" + have T: "P,E \\<^sub>1 e\<^sub>1 \bop\ e\<^sub>2 :: T" by fact + then obtain T\<^sub>1 T\<^sub>2 where T\<^sub>1: "P,E \\<^sub>1 e\<^sub>1 :: T\<^sub>1" and T\<^sub>2: "P,E \\<^sub>1 e\<^sub>2 :: T\<^sub>2" and + bopT: "case bop of Eq \ (P \ T\<^sub>1 \ T\<^sub>2 \ P \ T\<^sub>2 \ T\<^sub>1) \ T = Boolean + | Add \ T\<^sub>1 = Integer \ T\<^sub>2 = Integer \ T = Integer" by auto + let ?A\<^sub>1 = "A \ \ e\<^sub>1" let ?A\<^sub>2 = "?A\<^sub>1 \ \ e\<^sub>2" + let ?\ = "ty\<^sub>i' ST E A" let ?\s\<^sub>1 = "compT E A ST e\<^sub>1" + let ?\\<^sub>1 = "ty\<^sub>i' (T\<^sub>1#ST) E ?A\<^sub>1" let ?\s\<^sub>2 = "compT E ?A\<^sub>1 (T\<^sub>1#ST) e\<^sub>2" + let ?\\<^sub>2 = "ty\<^sub>i' (T\<^sub>2#T\<^sub>1#ST) E ?A\<^sub>2" let ?\' = "ty\<^sub>i' (T#ST) E ?A\<^sub>2" + from bopT have "\ ?op,[] [::] [?\\<^sub>2,?\']" + by (cases bop) (auto simp add: wt_CmpEq wt_IAdd) + also have "PROP ?P e\<^sub>2 E T\<^sub>2 ?A\<^sub>1 (T\<^sub>1#ST)" by fact + with BinOp.prems T\<^sub>2 + have "\ compE\<^sub>2 e\<^sub>2, compxE\<^sub>2 e\<^sub>2 0 (size (T\<^sub>1#ST)) [::] ?\\<^sub>1#?\s\<^sub>2@[?\\<^sub>2]" + by (auto simp: after_def) + also from BinOp T\<^sub>1 have "\ compE\<^sub>2 e\<^sub>1, compxE\<^sub>2 e\<^sub>1 0 (size ST) [::] ?\#?\s\<^sub>1@[?\\<^sub>1]" + by (auto simp: after_def) + finally show ?case using T T\<^sub>1 T\<^sub>2 by (simp add: after_def hyperUn_assoc) +next + case (Cons_exp e es) + have "P,E \\<^sub>1 e # es [::] Ts" by fact + then obtain T\<^sub>e Ts' where + T\<^sub>e: "P,E \\<^sub>1 e :: T\<^sub>e" and Ts': "P,E \\<^sub>1 es [::] Ts'" and + Ts: "Ts = T\<^sub>e#Ts'" by auto + let ?A\<^sub>e = "A \ \ e" + let ?\ = "ty\<^sub>i' ST E A" let ?\s\<^sub>e = "compT E A ST e" + let ?\\<^sub>e = "ty\<^sub>i' (T\<^sub>e#ST) E ?A\<^sub>e" let ?\s' = "compTs E ?A\<^sub>e (T\<^sub>e#ST) es" + let ?\s = "?\ # ?\s\<^sub>e @ (?\\<^sub>e # ?\s')" + have Ps: "PROP ?Ps es E Ts' ?A\<^sub>e (T\<^sub>e#ST)" by fact + with Cons_exp.prems T\<^sub>e Ts' + have "\ compEs\<^sub>2 es, compxEs\<^sub>2 es 0 (size (T\<^sub>e#ST)) [::] ?\\<^sub>e#?\s'" by (simp add: after_def) + also from Cons_exp T\<^sub>e have "\ compE\<^sub>2 e, compxE\<^sub>2 e 0 (size ST) [::] ?\#?\s\<^sub>e@[?\\<^sub>e]" + by (auto simp: after_def) + moreover + from Ps Cons_exp.prems T\<^sub>e Ts' Ts + have "last ?\s = ty\<^sub>i' (rev Ts@ST) E (?A\<^sub>e \ \s es)" by simp + ultimately show ?case using T\<^sub>e by (simp add: after_def hyperUn_assoc) +next + case (FAss e\<^sub>1 F D e\<^sub>2) + hence Void: "P,E \\<^sub>1 e\<^sub>1\F{D} := e\<^sub>2 :: Void" by auto + then obtain C T T' where + C: "P,E \\<^sub>1 e\<^sub>1 :: Class C" and sees: "P \ C sees F,NonStatic:T in D" and + T': "P,E \\<^sub>1 e\<^sub>2 :: T'" and T'_T: "P \ T' \ T" by auto + let ?A\<^sub>1 = "A \ \ e\<^sub>1" let ?A\<^sub>2 = "?A\<^sub>1 \ \ e\<^sub>2" + let ?\ = "ty\<^sub>i' ST E A" let ?\s\<^sub>1 = "compT E A ST e\<^sub>1" + let ?\\<^sub>1 = "ty\<^sub>i' (Class C#ST) E ?A\<^sub>1" let ?\s\<^sub>2 = "compT E ?A\<^sub>1 (Class C#ST) e\<^sub>2" + let ?\\<^sub>2 = "ty\<^sub>i' (T'#Class C#ST) E ?A\<^sub>2" let ?\\<^sub>3 = "ty\<^sub>i' ST E ?A\<^sub>2" + let ?\' = "ty\<^sub>i' (Void#ST) E ?A\<^sub>2" + from FAss.prems sees T'_T + have "\ [Putfield F D,Push Unit],[] [::] [?\\<^sub>2,?\\<^sub>3,?\']" + by (fastforce simp add: wt_Push wt_Put) + also have "PROP ?P e\<^sub>2 E T' ?A\<^sub>1 (Class C#ST)" by fact + with FAss.prems T' + have "\ compE\<^sub>2 e\<^sub>2, compxE\<^sub>2 e\<^sub>2 0 (size ST+1) [::] ?\\<^sub>1#?\s\<^sub>2@[?\\<^sub>2]" + by (auto simp add: after_def hyperUn_assoc) + also from FAss C have "\ compE\<^sub>2 e\<^sub>1, compxE\<^sub>2 e\<^sub>1 0 (size ST) [::] ?\#?\s\<^sub>1@[?\\<^sub>1]" + by (auto simp add: after_def) + finally show ?case using Void C T' by (simp add: after_def hyperUn_assoc) +next + case (SFAss C F D e\<^sub>2) + hence Void: "P,E \\<^sub>1 C\\<^sub>sF{D} := e\<^sub>2 :: Void" by auto + then obtain T T' where + sees: "P \ C sees F,Static:T in D" and + T': "P,E \\<^sub>1 e\<^sub>2 :: T'" and T'_T: "P \ T' \ T" by auto + let ?A\<^sub>2 = "A \ \ e\<^sub>2" + let ?\ = "ty\<^sub>i' ST E A" let ?\s\<^sub>2 = "compT E A ST e\<^sub>2" + let ?\\<^sub>2 = "ty\<^sub>i' (T'#ST) E ?A\<^sub>2" let ?\\<^sub>3 = "ty\<^sub>i' ST E ?A\<^sub>2" + let ?\' = "ty\<^sub>i' (Void#ST) E ?A\<^sub>2" + from SFAss.prems sees T'_T max_stack1[OF T'] + have "\ [Putstatic C F D,Push Unit],[] [::] [?\\<^sub>2,?\\<^sub>3,?\']" + by (fastforce simp add: wt_Push wt_PutS) + also have "PROP ?P e\<^sub>2 E T' A ST" by fact + with SFAss.prems T' + have "\ compE\<^sub>2 e\<^sub>2, compxE\<^sub>2 e\<^sub>2 0 (size ST) [::] ?\#?\s\<^sub>2@[?\\<^sub>2]" + by (auto simp add: after_def hyperUn_assoc) + finally show ?case using Void T' by (simp add: after_def hyperUn_assoc) +next + case Val thus ?case by(auto simp:after_def wt_Push) +next + case Cast thus ?case by (auto simp:after_def wt_Cast) +next + case (Block i T\<^sub>i e) + let ?\s = "ty\<^sub>i' ST E A # compT (E @ [T\<^sub>i]) (A\i) ST e" + have IH: "PROP ?P e (E@[T\<^sub>i]) T (A\i) ST" by fact + hence "\ compE\<^sub>2 e, compxE\<^sub>2 e 0 (size ST) [::] + ?\s @ [ty\<^sub>i' (T#ST) (E@[T\<^sub>i]) (A\(size E) \ \ e)]" + using Block.prems by (auto simp add: after_def) + also have "P \ ty\<^sub>i' (T # ST) (E@[T\<^sub>i]) (A \ size E \ \ e) \' + ty\<^sub>i' (T # ST) (E@[T\<^sub>i]) ((A \ \ e) \ size E)" + by(auto simp add:hyperset_defs intro: ty\<^sub>i'_antimono) + also have "\ = ty\<^sub>i' (T # ST) E (A \ \ e)" by simp + also have "P \ \ \' ty\<^sub>i' (T # ST) E (A \ (\ e \ i))" + by(auto simp add:hyperset_defs intro: ty\<^sub>i'_antimono) + finally show ?case using Block.prems by(simp add: after_def) +next + case Var thus ?case by(auto simp:after_def wt_Load) +next + case FAcc thus ?case by(auto simp:after_def wt_Get) +next + case SFAcc thus ?case by(auto simp: after_def wt_GetS) +next + case (LAss i e) + then obtain T' where wt: "P,E \\<^sub>1 e :: T'" by auto + show ?case using max_stack1[OF wt] LAss + by(auto simp: hyper_insert_comm after_def wt_Store wt_Push) +next + case Nil_exp thus ?case by auto +next + case throw thus ?case by(auto simp add: after_def wt_Throw) +next + case (While e c) + obtain Tc where wte: "P,E \\<^sub>1 e :: Boolean" and wtc: "P,E \\<^sub>1 c :: Tc" + and [simp]: "T = Void" using While by auto + have [simp]: "ty E (while (e) c) = Void" using While by simp + let ?A\<^sub>0 = "A \ \ e" let ?A\<^sub>1 = "?A\<^sub>0 \ \ c" + let ?\ = "ty\<^sub>i' ST E A" let ?\s\<^sub>e = "compT E A ST e" + let ?\\<^sub>e = "ty\<^sub>i' (Boolean#ST) E ?A\<^sub>0" let ?\\<^sub>1 = "ty\<^sub>i' ST E ?A\<^sub>0" + let ?\s\<^sub>c = "compT E ?A\<^sub>0 ST c" let ?\\<^sub>c = "ty\<^sub>i' (Tc#ST) E ?A\<^sub>1" + let ?\\<^sub>2 = "ty\<^sub>i' ST E ?A\<^sub>1" let ?\' = "ty\<^sub>i' (Void#ST) E ?A\<^sub>0" + let ?\s = "(?\ # ?\s\<^sub>e @ [?\\<^sub>e]) @ ?\\<^sub>1 # ?\s\<^sub>c @ [?\\<^sub>c, ?\\<^sub>2, ?\\<^sub>1, ?\']" + have "\ [],[] [::] [] @ ?\s" by(simp add:wt_instrs_def) + also + have "PROP ?P e E Boolean A ST" by fact + hence "\ compE\<^sub>2 e,compxE\<^sub>2 e 0 (size ST) [::] ?\ # ?\s\<^sub>e @ [?\\<^sub>e]" + using While.prems by (auto simp:after_def) + also + have "[] @ ?\s = (?\ # ?\s\<^sub>e) @ ?\\<^sub>e # ?\\<^sub>1 # ?\s\<^sub>c @ [?\\<^sub>c,?\\<^sub>2,?\\<^sub>1,?\']" by simp + also + let ?n\<^sub>e = "size(compE\<^sub>2 e)" let ?n\<^sub>c = "size(compE\<^sub>2 c)" + let ?if = "IfFalse (int ?n\<^sub>c + 3)" + have "\ [?if],[] [::] ?\\<^sub>e # ?\\<^sub>1 # ?\s\<^sub>c @ [?\\<^sub>c, ?\\<^sub>2, ?\\<^sub>1, ?\']" using wtc + by(simp add: wt_instr_Cons wt_instr_append wt_IfFalse + nat_add_distrib split: nat_diff_split) + also + have "(?\ # ?\s\<^sub>e) @ (?\\<^sub>e # ?\\<^sub>1 # ?\s\<^sub>c @ [?\\<^sub>c, ?\\<^sub>2, ?\\<^sub>1, ?\']) = ?\s" by simp + also + have "PROP ?P c E Tc ?A\<^sub>0 ST" by fact + hence "\ compE\<^sub>2 c,compxE\<^sub>2 c 0 (size ST) [::] ?\\<^sub>1 # ?\s\<^sub>c @ [?\\<^sub>c]" + using While.prems wtc by (auto simp:after_def) + also have "?\s = (?\ # ?\s\<^sub>e @ [?\\<^sub>e,?\\<^sub>1] @ ?\s\<^sub>c) @ [?\\<^sub>c,?\\<^sub>2,?\\<^sub>1,?\']" by simp + also have "\ [Pop],[] [::] [?\\<^sub>c, ?\\<^sub>2]" by(simp add:wt_Pop) + also have "(?\ # ?\s\<^sub>e @ [?\\<^sub>e,?\\<^sub>1] @ ?\s\<^sub>c) @ [?\\<^sub>c,?\\<^sub>2,?\\<^sub>1,?\'] = ?\s" by simp + also let ?go = "Goto (-int(?n\<^sub>c+?n\<^sub>e+2))" + have "P \ ?\\<^sub>2 \' ?\" by(fastforce intro: ty\<^sub>i'_antimono simp: hyperset_defs) + hence "P,T\<^sub>r,mxs,size ?\s,[] \ ?go,?n\<^sub>e+?n\<^sub>c+2 :: ?\s" using wte wtc + by(simp add: wt_Goto split: nat_diff_split) + also have "?\s = (?\ # ?\s\<^sub>e @ [?\\<^sub>e,?\\<^sub>1] @ ?\s\<^sub>c @ [?\\<^sub>c, ?\\<^sub>2]) @ [?\\<^sub>1, ?\']" + by simp + also have "\ [Push Unit],[] [::] [?\\<^sub>1,?\']" + using While.prems max_stack1[OF wtc] by(auto simp add:wt_Push) + finally show ?case using wtc wte + by (simp add:after_def) +next + case (Cond e e\<^sub>1 e\<^sub>2) + obtain T\<^sub>1 T\<^sub>2 where wte: "P,E \\<^sub>1 e :: Boolean" + and wt\<^sub>1: "P,E \\<^sub>1 e\<^sub>1 :: T\<^sub>1" and wt\<^sub>2: "P,E \\<^sub>1 e\<^sub>2 :: T\<^sub>2" + and sub\<^sub>1: "P \ T\<^sub>1 \ T" and sub\<^sub>2: "P \ T\<^sub>2 \ T" + using Cond by auto + have [simp]: "ty E (if (e) e\<^sub>1 else e\<^sub>2) = T" using Cond by simp + let ?A\<^sub>0 = "A \ \ e" let ?A\<^sub>2 = "?A\<^sub>0 \ \ e\<^sub>2" let ?A\<^sub>1 = "?A\<^sub>0 \ \ e\<^sub>1" + let ?A' = "?A\<^sub>0 \ \ e\<^sub>1 \ \ e\<^sub>2" + let ?\\<^sub>2 = "ty\<^sub>i' ST E ?A\<^sub>0" let ?\' = "ty\<^sub>i' (T#ST) E ?A'" + let ?\s\<^sub>2 = "compT E ?A\<^sub>0 ST e\<^sub>2" + have "PROP ?P e\<^sub>2 E T\<^sub>2 ?A\<^sub>0 ST" by fact + hence "\ compE\<^sub>2 e\<^sub>2, compxE\<^sub>2 e\<^sub>2 0 (size ST) [::] (?\\<^sub>2#?\s\<^sub>2) @ [ty\<^sub>i' (T\<^sub>2#ST) E ?A\<^sub>2]" + using Cond.prems wt\<^sub>2 by(auto simp add:after_def) + also have "P \ ty\<^sub>i' (T\<^sub>2#ST) E ?A\<^sub>2 \' ?\'" using sub\<^sub>2 + by(auto simp add: hyperset_defs ty\<^sub>i'_def intro!: ty\<^sub>l_antimono) + also + let ?\\<^sub>3 = "ty\<^sub>i' (T\<^sub>1 # ST) E ?A\<^sub>1" + let ?g\<^sub>2 = "Goto(int (size (compE\<^sub>2 e\<^sub>2) + 1))" + from sub\<^sub>1 have "P,T\<^sub>r,mxs,size(compE\<^sub>2 e\<^sub>2)+2,[] \ ?g\<^sub>2,0 :: ?\\<^sub>3#(?\\<^sub>2#?\s\<^sub>2)@[?\']" using wt\<^sub>2 + by(auto simp: hyperset_defs wt_defs nth_Cons ty\<^sub>i'_def + split:nat.split intro!: ty\<^sub>l_antimono) + also + let ?\s\<^sub>1 = "compT E ?A\<^sub>0 ST e\<^sub>1" + have "PROP ?P e\<^sub>1 E T\<^sub>1 ?A\<^sub>0 ST" by fact + hence "\ compE\<^sub>2 e\<^sub>1,compxE\<^sub>2 e\<^sub>1 0 (size ST) [::] ?\\<^sub>2 # ?\s\<^sub>1 @ [?\\<^sub>3]" + using Cond.prems wt\<^sub>1 by(auto simp add:after_def) + also + let ?\s\<^sub>1\<^sub>2 = "?\\<^sub>2 # ?\s\<^sub>1 @ ?\\<^sub>3 # (?\\<^sub>2 # ?\s\<^sub>2) @ [?\']" + let ?\\<^sub>1 = "ty\<^sub>i' (Boolean#ST) E ?A\<^sub>0" + let ?g\<^sub>1 = "IfFalse(int (size (compE\<^sub>2 e\<^sub>1) + 2))" + let ?code = "compE\<^sub>2 e\<^sub>1 @ ?g\<^sub>2 # compE\<^sub>2 e\<^sub>2" + have "\ [?g\<^sub>1],[] [::] [?\\<^sub>1] @ ?\s\<^sub>1\<^sub>2" using wt\<^sub>1 + by(simp add: wt_IfFalse nat_add_distrib split:nat_diff_split) + also (wt_instrs_ext2) have "[?\\<^sub>1] @ ?\s\<^sub>1\<^sub>2 = ?\\<^sub>1 # ?\s\<^sub>1\<^sub>2" by simp also + let ?\ = "ty\<^sub>i' ST E A" + have "PROP ?P e E Boolean A ST" by fact + hence "\ compE\<^sub>2 e, compxE\<^sub>2 e 0 (size ST) [::] ?\ # compT E A ST e @ [?\\<^sub>1]" + using Cond.prems wte by(auto simp add:after_def) + finally show ?case using wte wt\<^sub>1 wt\<^sub>2 by(simp add:after_def hyperUn_assoc) +next + case (Call e M es) + obtain C D Ts m Ts' where C: "P,E \\<^sub>1 e :: Class C" + and "method": "P \ C sees M,NonStatic:Ts \ T = m in D" + and wtes: "P,E \\<^sub>1 es [::] Ts'" and subs: "P \ Ts' [\] Ts" + using Call.prems by auto + from wtes have same_size: "size es = size Ts'" by(rule WTs\<^sub>1_same_size) + let ?A\<^sub>0 = "A \ \ e" let ?A\<^sub>1 = "?A\<^sub>0 \ \s es" + let ?\ = "ty\<^sub>i' ST E A" let ?\s\<^sub>e = "compT E A ST e" + let ?\\<^sub>e = "ty\<^sub>i' (Class C # ST) E ?A\<^sub>0" + let ?\s\<^sub>e\<^sub>s = "compTs E ?A\<^sub>0 (Class C # ST) es" + let ?\\<^sub>1 = "ty\<^sub>i' (rev Ts' @ Class C # ST) E ?A\<^sub>1" + let ?\' = "ty\<^sub>i' (T # ST) E ?A\<^sub>1" + have "\ [Invoke M (size es)],[] [::] [?\\<^sub>1,?\']" + by(rule wt_Invoke[OF same_size "method" subs]) + also + have "PROP ?Ps es E Ts' ?A\<^sub>0 (Class C # ST)" by fact + hence "\ compEs\<^sub>2 es,compxEs\<^sub>2 es 0 (size ST+1) [::] ?\\<^sub>e # ?\s\<^sub>e\<^sub>s" + "last (?\\<^sub>e # ?\s\<^sub>e\<^sub>s) = ?\\<^sub>1" + using Call.prems wtes by(auto simp add:after_def) + also have "(?\\<^sub>e # ?\s\<^sub>e\<^sub>s) @ [?\'] = ?\\<^sub>e # ?\s\<^sub>e\<^sub>s @ [?\']" by simp + also have "\ compE\<^sub>2 e,compxE\<^sub>2 e 0 (size ST) [::] ?\ # ?\s\<^sub>e @ [?\\<^sub>e]" + using Call C by(auto simp add:after_def) + finally show ?case using Call.prems C wtes by(simp add:after_def hyperUn_assoc) +next + case (SCall C M es) + obtain D Ts m Ts' where "method": "P \ C sees M,Static:Ts \ T = m in D" + and wtes: "P,E \\<^sub>1 es [::] Ts'" and subs: "P \ Ts' [\] Ts" + using SCall.prems by auto + from SCall.prems(1) have nclinit: "M \ clinit" by auto + from wtes have same_size: "size es = size Ts'" by(rule WTs\<^sub>1_same_size) + have mxs: "length ST < mxs" using WT\<^sub>1_nsub_RI[OF SCall.prems(1)] SCall.prems(4) by simp + let ?A\<^sub>1 = "A \ \s es" + let ?\ = "ty\<^sub>i' ST E A" + let ?\s\<^sub>e\<^sub>s = "compTs E A ST es" + let ?\\<^sub>1 = "ty\<^sub>i' (rev Ts' @ ST) E ?A\<^sub>1" + let ?\' = "ty\<^sub>i' (T # ST) E ?A\<^sub>1" + have "\ [Invokestatic C M (size es)],[] [::] [?\\<^sub>1,?\']" + by(rule wt_Invokestatic[OF mxs same_size nclinit "method" subs]) + also + have "PROP ?Ps es E Ts' A ST" by fact + hence "\ compEs\<^sub>2 es,compxEs\<^sub>2 es 0 (size ST) [::] ?\ # ?\s\<^sub>e\<^sub>s" + "last (?\ # ?\s\<^sub>e\<^sub>s) = ?\\<^sub>1" + using SCall.prems wtes by(auto simp add:after_def) + also have "(?\ # ?\s\<^sub>e\<^sub>s) @ [?\'] = ?\ # ?\s\<^sub>e\<^sub>s @ [?\']" by simp + finally show ?case using SCall.prems wtes by(simp add:after_def hyperUn_assoc) +next + case Seq thus ?case + by(auto simp:after_def) + (fastforce simp:wt_Push wt_Pop hyperUn_assoc + intro:wt_instrs_app2 wt_instrs_Cons) +next + case (INIT C Cs b e) + have "P,E \\<^sub>1 INIT C (Cs,b) \ e :: T" by fact + thus ?case using WT\<^sub>1_nsub_RI by simp +next + case (RI C e' Cs e) + have "P,E \\<^sub>1 RI (C,e') ; Cs \ e :: T" by fact + thus ?case using WT\<^sub>1_nsub_RI by simp +qed +(*>*) + + +lemma [simp]: "types (compP f P) = types P" +(*<*)by auto(*>*) + +lemma [simp]: "states (compP f P) mxs mxl = states P mxs mxl" +(*<*)by (simp add: JVM_states_unfold)(*>*) + +lemma [simp]: "app\<^sub>i (i, compP f P, pc, mpc, T, \) = app\<^sub>i (i, P, pc, mpc, T, \)" +(*<*) + apply (cases \) + apply (cases i) + apply auto +\ \ Invoke \ + apply (fastforce dest!: sees_method_compPD) + apply (force dest: sees_method_compP) +\ \ Invokestatic \ + apply (force dest!: sees_method_compPD) + apply (force dest: sees_method_compP) + done +(*>*) + +lemma [simp]: "is_relevant_entry (compP f P) i = is_relevant_entry P i" +(*<*) + apply (rule ext)+ + apply (unfold is_relevant_entry_def) + apply (cases i) + apply auto + done +(*>*) + +lemma [simp]: "relevant_entries (compP f P) i pc xt = relevant_entries P i pc xt" +(*<*) by (simp add: relevant_entries_def)(*>*) + +lemma [simp]: "app i (compP f P) mpc T pc mxl xt \ = app i P mpc T pc mxl xt \" +(*<*) + apply (simp add: app_def xcpt_app_def eff_def xcpt_eff_def norm_eff_def) + apply (fastforce simp add: image_def) + done +(*>*) + +lemma [simp]: "app i P mpc T pc mxl xt \ \ eff i (compP f P) pc xt \ = eff i P pc xt \" +(*<*) + apply (clarsimp simp add: eff_def norm_eff_def xcpt_eff_def app_def) + apply (cases i) + apply auto + done +(*>*) + +lemma [simp]: "subtype (compP f P) = subtype P" +(*<*) + apply (rule ext)+ + apply (simp) + done +(*>*) + +lemma [simp]: "compP f P \ \ \' \' = P \ \ \' \'" +(*<*) by (simp add: sup_state_opt_def sup_state_def sup_ty_opt_def)(*>*) + +lemma [simp]: "compP f P,T,mpc,mxl,xt \ i,pc :: \s = P,T,mpc,mxl,xt \ i,pc :: \s" +(*<*)by (simp add: wt_instr_def cong: conj_cong)(*>*) + +declare TC1.compT_sizes[simp] TC0.ty_def2[simp] + +context TC2 +begin + +lemma compT_method_NonStatic: + fixes e and A and C and Ts and mxl\<^sub>0 + defines [simp]: "E \ Class C # Ts" + and [simp]: "A \ \{..size Ts}\" + and [simp]: "A' \ A \ \ e" + and [simp]: "mxl\<^sub>0 \ max_vars e" + assumes mxs: "max_stack e = mxs" + and mxl: "Suc (length Ts + max_vars e) = mxl" + assumes assm: "wf_prog p P" "P,E \\<^sub>1 e :: T" "\ e A" "\ e (size E)" + "set E \ types P" "P \ T \ T\<^sub>r" + shows "wt_method (compP\<^sub>2 P) C NonStatic Ts T\<^sub>r mxs mxl\<^sub>0 (compE\<^sub>2 e @ [Return]) + (compxE\<^sub>2 e 0 0) (ty\<^sub>i' [] E A # compT\<^sub>a E A [] e)" +(*<*) +using assms apply (simp add: wt_method_def compT\<^sub>a_def after_def mxl) +apply (rule conjI) + apply (simp add: check_types_def OK_ty\<^sub>i'_in_statesI) + apply (rule conjI) + apply (drule (1) WT\<^sub>1_is_type) + apply simp + apply (insert max_stack1 [where e=e]) + apply (rule OK_ty\<^sub>i'_in_statesI) apply (simp_all add: mxs)[3] + apply (erule compT_states(1)) + apply assumption + apply (simp_all add: mxs mxl)[4] +apply (rule conjI) + apply (auto simp add: wt_start_def ty\<^sub>i'_def ty\<^sub>l_def list_all2_conv_all_nth + nth_Cons mxl split: nat.split dest: less_antisym)[1] +apply (frule (1) TC2.compT_wt_instrs [of P _ _ _ _ "[]" "max_stack e" "Suc (length Ts + max_vars e)" T\<^sub>r]) + apply simp_all +apply (clarsimp simp: after_def) +apply hypsubst_thin +apply (rule conjI) + apply (clarsimp simp: wt_instrs_def after_def mxl mxs) +apply clarsimp +apply (drule (1) less_antisym) +apply (clarsimp simp: wt_defs xcpt_app_pcs xcpt_eff_pcs ty\<^sub>i'_def) +done +(*>*) + +lemma compT_method_Static: + fixes e and A and C and Ts and mxl\<^sub>0 + defines [simp]: "E \ Ts" + and [simp]: "A \ \{.." + and [simp]: "A' \ A \ \ e" + and [simp]: "mxl\<^sub>0 \ max_vars e" + assumes mxs: "max_stack e = mxs" + and mxl: "length Ts + max_vars e = mxl" + assumes assm: "wf_prog p P" "P,E \\<^sub>1 e :: T" "\ e A" "\ e (size E)" + "set E \ types P" "P \ T \ T\<^sub>r" + shows "wt_method (compP\<^sub>2 P) C Static Ts T\<^sub>r mxs mxl\<^sub>0 (compE\<^sub>2 e @ [Return]) + (compxE\<^sub>2 e 0 0) (ty\<^sub>i' [] E A # compT\<^sub>a E A [] e)" +(*<*) +using assms apply (simp add: wt_method_def compT\<^sub>a_def after_def mxl) +apply (rule conjI) + apply (simp add: check_types_def OK_ty\<^sub>i'_in_statesI) + apply (rule conjI) + apply (drule (1) WT\<^sub>1_is_type) + apply simp + apply (insert max_stack1 [where e=e]) + apply (rule OK_ty\<^sub>i'_in_statesI) apply (simp_all add: mxs)[3] + apply (erule compT_states(1)) + apply assumption + apply (simp_all add: mxs mxl)[4] +apply (rule conjI) + apply (auto simp add: wt_start_def ty\<^sub>i'_def ty\<^sub>l_def list_all2_conv_all_nth + nth_Cons mxl split: nat.split dest: less_antisym)[1] +apply (frule (1) TC2.compT_wt_instrs [of P _ _ _ _ "[]" "max_stack e" "length Ts + max_vars e" T\<^sub>r]) + apply simp_all +apply (clarsimp simp: after_def) +apply hypsubst_thin +apply (rule conjI) + apply (clarsimp simp: wt_instrs_def after_def mxl mxs) +apply clarsimp +apply (drule (1) less_antisym) +apply (clarsimp simp: wt_defs xcpt_app_pcs xcpt_eff_pcs ty\<^sub>i'_def) +done +(*>*) + +end + +definition compTP :: "J\<^sub>1_prog \ ty\<^sub>P" where + "compTP P C M = ( + let (D,b,Ts,T,e) = method P C M; + E = case b of Static \ Ts | NonStatic \ Class C # Ts; + A = case b of Static \ \{.. | NonStatic \ \{..size Ts}\; + mxl = (case b of Static \ 0 | NonStatic \ 1) + size Ts + max_vars e + in (TC0.ty\<^sub>i' mxl [] E A # TC1.compT\<^sub>a P mxl E A [] e))" + +theorem wt_compP\<^sub>2: + "wf_J\<^sub>1_prog P \ wf_jvm_prog (compP\<^sub>2 P)" +(*<*) + apply (simp add: wf_jvm_prog_def wf_jvm_prog_phi_def) + apply(rule_tac x = "compTP P" in exI) + apply (rule wf_prog_compPI) + prefer 2 apply assumption + apply (simp add: compTP_def) apply(rename_tac C M b Ts T m) + apply(case_tac b) +\ \ Static \ + apply (clarsimp simp add: wf_mdecl_def) + apply (rule TC2.compT_method_Static [simplified]) + apply (rule refl) + apply (rule refl) + apply assumption + apply assumption + apply assumption + apply assumption + apply (drule (1) sees_wf_mdecl) + apply (simp add: wf_mdecl_def) + apply (blast intro: sees_method_is_class) + apply assumption +\ \ NonStatic \ + apply (clarsimp simp add: wf_mdecl_def) + apply (rule TC2.compT_method_NonStatic [simplified]) + apply (rule refl) + apply (rule refl) + apply assumption + apply assumption + apply assumption + apply assumption + apply (drule (1) sees_wf_mdecl) + apply (simp add: wf_mdecl_def) + apply (blast intro: sees_method_is_class) + apply assumption + done +(*>*) + +theorem wt_J2JVM: + "wf_J_prog P \ wf_jvm_prog (J2JVM P)" +(*<*) +apply(simp only:o_def J2JVM_def) +apply(blast intro:wt_compP\<^sub>2 compP\<^sub>1_pres_wf) +done + +end diff --git a/thys/JinjaDCI/J/Annotate.thy b/thys/JinjaDCI/J/Annotate.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/J/Annotate.thy @@ -0,0 +1,78 @@ +(* Title: JinjaDCI/J/Annotate.thy + + Author: Tobias Nipkow, Susannah Mansky + Copyright 2003 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory J/Annotate.thy by Tobias Nipkow +*) + +section \ Program annotation \ + +theory Annotate imports WellType begin + +(*<*) +abbreviation (output) + unanFAcc :: "expr \ vname \ expr" ("(_\_)" [10,10] 90) where + "unanFAcc e F == FAcc e F []" + +abbreviation (output) + unanFAss :: "expr \ vname \ expr \ expr" ("(_\_ := _)" [10,0,90] 90) where + "unanFAss e F e' == FAss e F [] e'" +(*>*) + +inductive + Anno :: "[J_prog,env, expr , expr] \ bool" + ("_,_ \ _ \ _" [51,0,0,51]50) + and Annos :: "[J_prog,env, expr list, expr list] \ bool" + ("_,_ \ _ [\] _" [51,0,0,51]50) + for P :: J_prog +where + + AnnoNew: "P,E \ new C \ new C" +| AnnoCast: "P,E \ e \ e' \ P,E \ Cast C e \ Cast C e'" +| AnnoVal: "P,E \ Val v \ Val v" +| AnnoVarVar: "E V = \T\ \ P,E \ Var V \ Var V" +| AnnoVarField: "\ E V = None; E this = \Class C\; P \ C sees V,NonStatic:T in D \ + \ P,E \ Var V \ Var this\V{D}" +| AnnoBinOp: + "\ P,E \ e1 \ e1'; P,E \ e2 \ e2' \ + \ P,E \ e1 \bop\ e2 \ e1' \bop\ e2'" +| AnnoLAssVar: + "\ E V = \T\; P,E \ e \ e' \ \ P,E \ V:=e \ V:=e'" +| AnnoLAssField: + "\ E V = None; E this = \Class C\; P \ C sees V,NonStatic:T in D; P,E \ e \ e' \ + \ P,E \ V:=e \ Var this\V{D} := e'" +| AnnoFAcc: + "\ P,E \ e \ e'; P,E \ e' :: Class C; P \ C sees F,NonStatic:T in D \ + \ P,E \ e\F{[]} \ e'\F{D}" +| AnnoSFAcc: + "\ P \ C sees F,Static:T in D \ + \ P,E \ C\\<^sub>sF{[]} \ C\\<^sub>sF{D}" +| AnnoFAss: "\ P,E \ e1 \ e1'; P,E \ e2 \ e2'; + P,E \ e1' :: Class C; P \ C sees F,NonStatic:T in D \ + \ P,E \ e1\F{[]} := e2 \ e1'\F{D} := e2'" +| AnnoSFAss: "\ P,E \ e2 \ e2'; P \ C sees F,Static:T in D \ + \ P,E \ C\\<^sub>sF{[]} := e2 \ C\\<^sub>sF{D} := e2'" +| AnnoCall: + "\ P,E \ e \ e'; P,E \ es [\] es' \ + \ P,E \ Call e M es \ Call e' M es'" +| AnnoSCall: + "\ P,E \ es [\] es' \ + \ P,E \ SCall C M es \ SCall C M es'" +| AnnoBlock: + "P,E(V \ T) \ e \ e' \ P,E \ {V:T; e} \ {V:T; e'}" +| AnnoComp: "\ P,E \ e1 \ e1'; P,E \ e2 \ e2' \ + \ P,E \ e1;;e2 \ e1';;e2'" +| AnnoCond: "\ P,E \ e \ e'; P,E \ e1 \ e1'; P,E \ e2 \ e2' \ + \ P,E \ if (e) e1 else e2 \ if (e') e1' else e2'" +| AnnoLoop: "\ P,E \ e \ e'; P,E \ c \ c' \ + \ P,E \ while (e) c \ while (e') c'" +| AnnoThrow: "P,E \ e \ e' \ P,E \ throw e \ throw e'" +| AnnoTry: "\ P,E \ e1 \ e1'; P,E(V \ Class C) \ e2 \ e2' \ + \ P,E \ try e1 catch(C V) e2 \ try e1' catch(C V) e2'" + +| AnnoNil: "P,E \ [] [\] []" +| AnnoCons: "\ P,E \ e \ e'; P,E \ es [\] es' \ + \ P,E \ e#es [\] e'#es'" + +end diff --git a/thys/JinjaDCI/J/BigStep.thy b/thys/JinjaDCI/J/BigStep.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/J/BigStep.thy @@ -0,0 +1,699 @@ +(* Title: JinjaDCI/J/BigStep.thy + + Author: Tobias Nipkow, Susannah Mansky + Copyright 2003 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory J/BigStep.thy by Tobias Nipkow +*) + +section \ Big Step Semantics \ + +theory BigStep imports Expr State WWellForm begin + +inductive + eval :: "J_prog \ expr \ state \ expr \ state \ bool" + ("_ \ ((1\_,/_\) \/ (1\_,/_\))" [51,0,0,0,0] 81) + and evals :: "J_prog \ expr list \ state \ expr list \ state \ bool" + ("_ \ ((1\_,/_\) [\]/ (1\_,/_\))" [51,0,0,0,0] 81) + for P :: J_prog +where + + New: + "\ sh C = Some (sfs, Done); new_Addr h = Some a; + P \ C has_fields FDTs; h' = h(a\blank P C) \ + \ P \ \new C,(h,l,sh)\ \ \addr a,(h',l,sh)\" + +| NewFail: + "\ sh C = Some (sfs, Done); new_Addr h = None; is_class P C \ \ + P \ \new C, (h,l,sh)\ \ \THROW OutOfMemory,(h,l,sh)\" + +| NewInit: + "\ \sfs. sh C = Some (sfs, Done); P \ \INIT C ([C],False) \ unit,(h,l,sh)\ \ \Val v',(h',l',sh')\; + new_Addr h' = Some a; P \ C has_fields FDTs; h'' = h'(a\blank P C) \ + \ P \ \new C,(h,l,sh)\ \ \addr a,(h'',l',sh')\" + +| NewInitOOM: + "\ \sfs. sh C = Some (sfs, Done); P \ \INIT C ([C],False) \ unit,(h,l,sh)\ \ \Val v',(h',l',sh')\; + new_Addr h' = None; is_class P C \ + \ P \ \new C,(h,l,sh)\ \ \THROW OutOfMemory,(h',l',sh')\" + +| NewInitThrow: + "\ \sfs. sh C = Some (sfs, Done); P \ \INIT C ([C],False) \ unit,(h,l,sh)\ \ \throw a,s'\; + is_class P C \ + \ P \ \new C,(h,l,sh)\ \ \throw a,s'\" + +| Cast: + "\ P \ \e,s\<^sub>0\ \ \addr a,(h,l,sh)\; h a = Some(D,fs); P \ D \\<^sup>* C \ + \ P \ \Cast C e,s\<^sub>0\ \ \addr a,(h,l,sh)\" + +| CastNull: + "P \ \e,s\<^sub>0\ \ \null,s\<^sub>1\ \ + P \ \Cast C e,s\<^sub>0\ \ \null,s\<^sub>1\" + +| CastFail: + "\ P \ \e,s\<^sub>0\\ \addr a,(h,l,sh)\; h a = Some(D,fs); \ P \ D \\<^sup>* C \ + \ P \ \Cast C e,s\<^sub>0\ \ \THROW ClassCast,(h,l,sh)\" + +| CastThrow: + "P \ \e,s\<^sub>0\ \ \throw e',s\<^sub>1\ \ + P \ \Cast C e,s\<^sub>0\ \ \throw e',s\<^sub>1\" + +| Val: + "P \ \Val v,s\ \ \Val v,s\" + +| BinOp: + "\ P \ \e\<^sub>1,s\<^sub>0\ \ \Val v\<^sub>1,s\<^sub>1\; P \ \e\<^sub>2,s\<^sub>1\ \ \Val v\<^sub>2,s\<^sub>2\; binop(bop,v\<^sub>1,v\<^sub>2) = Some v \ + \ P \ \e\<^sub>1 \bop\ e\<^sub>2,s\<^sub>0\ \ \Val v,s\<^sub>2\" + +| BinOpThrow1: + "P \ \e\<^sub>1,s\<^sub>0\ \ \throw e,s\<^sub>1\ \ + P \ \e\<^sub>1 \bop\ e\<^sub>2, s\<^sub>0\ \ \throw e,s\<^sub>1\" + +| BinOpThrow2: + "\ P \ \e\<^sub>1,s\<^sub>0\ \ \Val v\<^sub>1,s\<^sub>1\; P \ \e\<^sub>2,s\<^sub>1\ \ \throw e,s\<^sub>2\ \ + \ P \ \e\<^sub>1 \bop\ e\<^sub>2,s\<^sub>0\ \ \throw e,s\<^sub>2\" + +| Var: + "l V = Some v \ + P \ \Var V,(h,l,sh)\ \ \Val v,(h,l,sh)\" + +| LAss: + "\ P \ \e,s\<^sub>0\ \ \Val v,(h,l,sh)\; l' = l(V\v) \ + \ P \ \V:=e,s\<^sub>0\ \ \unit,(h,l',sh)\" + +| LAssThrow: + "P \ \e,s\<^sub>0\ \ \throw e',s\<^sub>1\ \ + P \ \V:=e,s\<^sub>0\ \ \throw e',s\<^sub>1\" + +| FAcc: + "\ P \ \e,s\<^sub>0\ \ \addr a,(h,l,sh)\; h a = Some(C,fs); + P \ C has F,NonStatic:t in D; + fs(F,D) = Some v \ + \ P \ \e\F{D},s\<^sub>0\ \ \Val v,(h,l,sh)\" + +| FAccNull: + "P \ \e,s\<^sub>0\ \ \null,s\<^sub>1\ \ + P \ \e\F{D},s\<^sub>0\ \ \THROW NullPointer,s\<^sub>1\" + +| FAccThrow: + "P \ \e,s\<^sub>0\ \ \throw e',s\<^sub>1\ \ + P \ \e\F{D},s\<^sub>0\ \ \throw e',s\<^sub>1\" + +| FAccNone: + "\ P \ \e,s\<^sub>0\ \ \addr a,(h,l,sh)\; h a = Some(C,fs); + \(\b t. P \ C has F,b:t in D) \ + \ P \ \e\F{D},s\<^sub>0\ \ \THROW NoSuchFieldError,(h,l,sh)\" + +| FAccStatic: + "\ P \ \e,s\<^sub>0\ \ \addr a,(h,l,sh)\; h a = Some(C,fs); + P \ C has F,Static:t in D \ + \ P \ \e\F{D},s\<^sub>0\ \ \THROW IncompatibleClassChangeError,(h,l,sh)\" + +| SFAcc: + "\ P \ C has F,Static:t in D; + sh D = Some (sfs,Done); + sfs F = Some v \ + \ P \ \C\\<^sub>sF{D},(h,l,sh)\ \ \Val v,(h,l,sh)\" + +| SFAccInit: + "\ P \ C has F,Static:t in D; + \sfs. sh D = Some (sfs,Done); P \ \INIT D ([D],False) \ unit,(h,l,sh)\ \ \Val v',(h',l',sh')\; + sh' D = Some (sfs,i); + sfs F = Some v \ + \ P \ \C\\<^sub>sF{D},(h,l,sh)\ \ \Val v,(h',l',sh')\" + +| SFAccInitThrow: + "\ P \ C has F,Static:t in D; + \sfs. sh D = Some (sfs,Done); P \ \INIT D ([D],False) \ unit,(h,l,sh)\ \ \throw a,s'\ \ + \ P \ \C\\<^sub>sF{D},(h,l,sh)\ \ \throw a,s'\" + +| SFAccNone: + "\ \(\b t. P \ C has F,b:t in D) \ + \ P \ \C\\<^sub>sF{D},s\ \ \THROW NoSuchFieldError,s\" + +| SFAccNonStatic: + "\ P \ C has F,NonStatic:t in D \ + \ P \ \C\\<^sub>sF{D},s\ \ \THROW IncompatibleClassChangeError,s\" + +| FAss: + "\ P \ \e\<^sub>1,s\<^sub>0\ \ \addr a,s\<^sub>1\; P \ \e\<^sub>2,s\<^sub>1\ \ \Val v,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\; + h\<^sub>2 a = Some(C,fs); P \ C has F,NonStatic:t in D; + fs' = fs((F,D)\v); h\<^sub>2' = h\<^sub>2(a\(C,fs')) \ + \ P \ \e\<^sub>1\F{D}:=e\<^sub>2,s\<^sub>0\ \ \unit,(h\<^sub>2',l\<^sub>2,sh\<^sub>2)\" + +| FAssNull: + "\ P \ \e\<^sub>1,s\<^sub>0\ \ \null,s\<^sub>1\; P \ \e\<^sub>2,s\<^sub>1\ \ \Val v,s\<^sub>2\ \ \ + P \ \e\<^sub>1\F{D}:=e\<^sub>2,s\<^sub>0\ \ \THROW NullPointer,s\<^sub>2\" + +| FAssThrow1: + "P \ \e\<^sub>1,s\<^sub>0\ \ \throw e',s\<^sub>1\ \ + P \ \e\<^sub>1\F{D}:=e\<^sub>2,s\<^sub>0\ \ \throw e',s\<^sub>1\" + +| FAssThrow2: + "\ P \ \e\<^sub>1,s\<^sub>0\ \ \Val v,s\<^sub>1\; P \ \e\<^sub>2,s\<^sub>1\ \ \throw e',s\<^sub>2\ \ + \ P \ \e\<^sub>1\F{D}:=e\<^sub>2,s\<^sub>0\ \ \throw e',s\<^sub>2\" + +| FAssNone: + "\ P \ \e\<^sub>1,s\<^sub>0\ \ \addr a,s\<^sub>1\; P \ \e\<^sub>2,s\<^sub>1\ \ \Val v,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\; + h\<^sub>2 a = Some(C,fs); \(\b t. P \ C has F,b:t in D) \ + \ P \ \e\<^sub>1\F{D}:=e\<^sub>2,s\<^sub>0\ \ \THROW NoSuchFieldError,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\" + +| FAssStatic: + "\ P \ \e\<^sub>1,s\<^sub>0\ \ \addr a,s\<^sub>1\; P \ \e\<^sub>2,s\<^sub>1\ \ \Val v,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\; + h\<^sub>2 a = Some(C,fs); P \ C has F,Static:t in D \ + \ P \ \e\<^sub>1\F{D}:=e\<^sub>2,s\<^sub>0\ \ \THROW IncompatibleClassChangeError,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\" + +| SFAss: + "\ P \ \e\<^sub>2,s\<^sub>0\ \ \Val v,(h\<^sub>1,l\<^sub>1,sh\<^sub>1)\; + P \ C has F,Static:t in D; + sh\<^sub>1 D = Some(sfs,Done); sfs' = sfs(F\v); sh\<^sub>1' = sh\<^sub>1(D\(sfs',Done)) \ + \ P \ \C\\<^sub>sF{D}:=e\<^sub>2,s\<^sub>0\ \ \unit,(h\<^sub>1,l\<^sub>1,sh\<^sub>1')\" + +| SFAssInit: + "\ P \ \e\<^sub>2,s\<^sub>0\ \ \Val v,(h\<^sub>1,l\<^sub>1,sh\<^sub>1)\; + P \ C has F,Static:t in D; + \sfs. sh\<^sub>1 D = Some(sfs,Done); P \ \INIT D ([D],False) \ unit,(h\<^sub>1,l\<^sub>1,sh\<^sub>1)\ \ \Val v',(h',l',sh')\; + sh' D = Some(sfs,i); + sfs' = sfs(F\v); sh'' = sh'(D\(sfs',i)) \ + \ P \ \C\\<^sub>sF{D}:=e\<^sub>2,s\<^sub>0\ \ \unit,(h',l',sh'')\" + +| SFAssInitThrow: + "\ P \ \e\<^sub>2,s\<^sub>0\ \ \Val v,(h\<^sub>1,l\<^sub>1,sh\<^sub>1)\; + P \ C has F,Static:t in D; + \sfs. sh\<^sub>1 D = Some(sfs,Done); P \ \INIT D ([D],False) \ unit,(h\<^sub>1,l\<^sub>1,sh\<^sub>1)\ \ \throw a,s'\ \ + \ P \ \C\\<^sub>sF{D}:=e\<^sub>2,s\<^sub>0\ \ \throw a,s'\" + +| SFAssThrow: + "P \ \e\<^sub>2,s\<^sub>0\ \ \throw e',s\<^sub>2\ + \ P \ \C\\<^sub>sF{D}:=e\<^sub>2,s\<^sub>0\ \ \throw e',s\<^sub>2\" + +| SFAssNone: + "\ P \ \e\<^sub>2,s\<^sub>0\ \ \Val v,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\; + \(\b t. P \ C has F,b:t in D) \ + \ P \ \C\\<^sub>sF{D}:=e\<^sub>2,s\<^sub>0\ \ \THROW NoSuchFieldError,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\" + +| SFAssNonStatic: + "\ P \ \e\<^sub>2,s\<^sub>0\ \ \Val v,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\; + P \ C has F,NonStatic:t in D \ + \ P \ \C\\<^sub>sF{D}:=e\<^sub>2,s\<^sub>0\ \ \THROW IncompatibleClassChangeError,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\" + +| CallObjThrow: + "P \ \e,s\<^sub>0\ \ \throw e',s\<^sub>1\ \ + P \ \e\M(ps),s\<^sub>0\ \ \throw e',s\<^sub>1\" + +| CallParamsThrow: + "\ P \ \e,s\<^sub>0\ \ \Val v,s\<^sub>1\; P \ \es,s\<^sub>1\ [\] \map Val vs @ throw ex # es',s\<^sub>2\ \ + \ P \ \e\M(es),s\<^sub>0\ \ \throw ex,s\<^sub>2\" + +| CallNull: + "\ P \ \e,s\<^sub>0\ \ \null,s\<^sub>1\; P \ \ps,s\<^sub>1\ [\] \map Val vs,s\<^sub>2\ \ + \ P \ \e\M(ps),s\<^sub>0\ \ \THROW NullPointer,s\<^sub>2\" + +| CallNone: + "\ P \ \e,s\<^sub>0\ \ \addr a,s\<^sub>1\; P \ \ps,s\<^sub>1\ [\] \map Val vs,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\; + h\<^sub>2 a = Some(C,fs); \(\b Ts T m D. P \ C sees M,b:Ts\T = m in D) \ + \ P \ \e\M(ps),s\<^sub>0\ \ \THROW NoSuchMethodError,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\" + +| CallStatic: + "\ P \ \e,s\<^sub>0\ \ \addr a,s\<^sub>1\; P \ \ps,s\<^sub>1\ [\] \map Val vs,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\; + h\<^sub>2 a = Some(C,fs); P \ C sees M,Static:Ts\T = m in D \ + \ P \ \e\M(ps),s\<^sub>0\ \ \THROW IncompatibleClassChangeError,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\" + +| Call: + "\ P \ \e,s\<^sub>0\ \ \addr a,s\<^sub>1\; P \ \ps,s\<^sub>1\ [\] \map Val vs,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\; + h\<^sub>2 a = Some(C,fs); P \ C sees M,NonStatic:Ts\T = (pns,body) in D; + length vs = length pns; l\<^sub>2' = [this\Addr a, pns[\]vs]; + P \ \body,(h\<^sub>2,l\<^sub>2',sh\<^sub>2)\ \ \e',(h\<^sub>3,l\<^sub>3,sh\<^sub>3)\ \ + \ P \ \e\M(ps),s\<^sub>0\ \ \e',(h\<^sub>3,l\<^sub>2,sh\<^sub>3)\" + +| SCallParamsThrow: + "\ P \ \es,s\<^sub>0\ [\] \map Val vs @ throw ex # es',s\<^sub>2\ \ + \ P \ \C\\<^sub>sM(es),s\<^sub>0\ \ \throw ex,s\<^sub>2\" + +| SCallNone: + "\ P \ \ps,s\<^sub>0\ [\] \map Val vs,s\<^sub>2\; + \(\b Ts T m D. P \ C sees M,b:Ts\T = m in D) \ + \ P \ \C\\<^sub>sM(ps),s\<^sub>0\ \ \THROW NoSuchMethodError,s\<^sub>2\" + +| SCallNonStatic: + "\ P \ \ps,s\<^sub>0\ [\] \map Val vs,s\<^sub>2\; + P \ C sees M,NonStatic:Ts\T = m in D \ + \ P \ \C\\<^sub>sM(ps),s\<^sub>0\ \ \THROW IncompatibleClassChangeError,s\<^sub>2\" + +| SCallInitThrow: + "\ P \ \ps,s\<^sub>0\ [\] \map Val vs,(h\<^sub>1,l\<^sub>1,sh\<^sub>1)\; + P \ C sees M,Static:Ts\T = (pns,body) in D; + \sfs. sh\<^sub>1 D = Some(sfs,Done); M \ clinit; + P \ \INIT D ([D],False) \ unit,(h\<^sub>1,l\<^sub>1,sh\<^sub>1)\ \ \throw a,s'\ \ + \ P \ \C\\<^sub>sM(ps),s\<^sub>0\ \ \throw a,s'\" + +| SCallInit: + "\ P \ \ps,s\<^sub>0\ [\] \map Val vs,(h\<^sub>1,l\<^sub>1,sh\<^sub>1)\; + P \ C sees M,Static:Ts\T = (pns,body) in D; + \sfs. sh\<^sub>1 D = Some(sfs,Done); M \ clinit; + P \ \INIT D ([D],False) \ unit,(h\<^sub>1,l\<^sub>1,sh\<^sub>1)\ \ \Val v',(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\; + length vs = length pns; l\<^sub>2' = [pns[\]vs]; + P \ \body,(h\<^sub>2,l\<^sub>2',sh\<^sub>2)\ \ \e',(h\<^sub>3,l\<^sub>3,sh\<^sub>3)\ \ + \ P \ \C\\<^sub>sM(ps),s\<^sub>0\ \ \e',(h\<^sub>3,l\<^sub>2,sh\<^sub>3)\" + +| SCall: + "\ P \ \ps,s\<^sub>0\ [\] \map Val vs,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\; + P \ C sees M,Static:Ts\T = (pns,body) in D; + sh\<^sub>2 D = Some(sfs,Done) \ (M = clinit \ sh\<^sub>2 D = Some(sfs,Processing)); + length vs = length pns; l\<^sub>2' = [pns[\]vs]; + P \ \body,(h\<^sub>2,l\<^sub>2',sh\<^sub>2)\ \ \e',(h\<^sub>3,l\<^sub>3,sh\<^sub>3)\ \ + \ P \ \C\\<^sub>sM(ps),s\<^sub>0\ \ \e',(h\<^sub>3,l\<^sub>2,sh\<^sub>3)\" + +| Block: + "P \ \e\<^sub>0,(h\<^sub>0,l\<^sub>0(V:=None),sh\<^sub>0)\ \ \e\<^sub>1,(h\<^sub>1,l\<^sub>1,sh\<^sub>1)\ \ + P \ \{V:T; e\<^sub>0},(h\<^sub>0,l\<^sub>0,sh\<^sub>0)\ \ \e\<^sub>1,(h\<^sub>1,l\<^sub>1(V:=l\<^sub>0 V),sh\<^sub>1)\" + +| Seq: + "\ P \ \e\<^sub>0,s\<^sub>0\ \ \Val v,s\<^sub>1\; P \ \e\<^sub>1,s\<^sub>1\ \ \e\<^sub>2,s\<^sub>2\ \ + \ P \ \e\<^sub>0;;e\<^sub>1,s\<^sub>0\ \ \e\<^sub>2,s\<^sub>2\" + +| SeqThrow: + "P \ \e\<^sub>0,s\<^sub>0\ \ \throw e,s\<^sub>1\ \ + P \ \e\<^sub>0;;e\<^sub>1,s\<^sub>0\ \ \throw e,s\<^sub>1\" + +| CondT: + "\ P \ \e,s\<^sub>0\ \ \true,s\<^sub>1\; P \ \e\<^sub>1,s\<^sub>1\ \ \e',s\<^sub>2\ \ + \ P \ \if (e) e\<^sub>1 else e\<^sub>2,s\<^sub>0\ \ \e',s\<^sub>2\" + +| CondF: + "\ P \ \e,s\<^sub>0\ \ \false,s\<^sub>1\; P \ \e\<^sub>2,s\<^sub>1\ \ \e',s\<^sub>2\ \ + \ P \ \if (e) e\<^sub>1 else e\<^sub>2,s\<^sub>0\ \ \e',s\<^sub>2\" + +| CondThrow: + "P \ \e,s\<^sub>0\ \ \throw e',s\<^sub>1\ \ + P \ \if (e) e\<^sub>1 else e\<^sub>2, s\<^sub>0\ \ \throw e',s\<^sub>1\" + +| WhileF: + "P \ \e,s\<^sub>0\ \ \false,s\<^sub>1\ \ + P \ \while (e) c,s\<^sub>0\ \ \unit,s\<^sub>1\" + +| WhileT: + "\ P \ \e,s\<^sub>0\ \ \true,s\<^sub>1\; P \ \c,s\<^sub>1\ \ \Val v\<^sub>1,s\<^sub>2\; P \ \while (e) c,s\<^sub>2\ \ \e\<^sub>3,s\<^sub>3\ \ + \ P \ \while (e) c,s\<^sub>0\ \ \e\<^sub>3,s\<^sub>3\" + +| WhileCondThrow: + "P \ \e,s\<^sub>0\ \ \throw e',s\<^sub>1\ \ + P \ \while (e) c,s\<^sub>0\ \ \throw e',s\<^sub>1\" + +| WhileBodyThrow: + "\ P \ \e,s\<^sub>0\ \ \true,s\<^sub>1\; P \ \c,s\<^sub>1\ \ \throw e',s\<^sub>2\\ + \ P \ \while (e) c,s\<^sub>0\ \ \throw e',s\<^sub>2\" + +| Throw: + "P \ \e,s\<^sub>0\ \ \addr a,s\<^sub>1\ \ + P \ \throw e,s\<^sub>0\ \ \Throw a,s\<^sub>1\" + +| ThrowNull: + "P \ \e,s\<^sub>0\ \ \null,s\<^sub>1\ \ + P \ \throw e,s\<^sub>0\ \ \THROW NullPointer,s\<^sub>1\" + +| ThrowThrow: + "P \ \e,s\<^sub>0\ \ \throw e',s\<^sub>1\ \ + P \ \throw e,s\<^sub>0\ \ \throw e',s\<^sub>1\" + +| Try: + "P \ \e\<^sub>1,s\<^sub>0\ \ \Val v\<^sub>1,s\<^sub>1\ \ + P \ \try e\<^sub>1 catch(C V) e\<^sub>2,s\<^sub>0\ \ \Val v\<^sub>1,s\<^sub>1\" + +| TryCatch: + "\ P \ \e\<^sub>1,s\<^sub>0\ \ \Throw a,(h\<^sub>1,l\<^sub>1,sh\<^sub>1)\; h\<^sub>1 a = Some(D,fs); P \ D \\<^sup>* C; + P \ \e\<^sub>2,(h\<^sub>1,l\<^sub>1(V\Addr a),sh\<^sub>1)\ \ \e\<^sub>2',(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\ \ + \ P \ \try e\<^sub>1 catch(C V) e\<^sub>2,s\<^sub>0\ \ \e\<^sub>2',(h\<^sub>2,l\<^sub>2(V:=l\<^sub>1 V),sh\<^sub>2)\" + +| TryThrow: + "\ P \ \e\<^sub>1,s\<^sub>0\ \ \Throw a,(h\<^sub>1,l\<^sub>1,sh\<^sub>1)\; h\<^sub>1 a = Some(D,fs); \ P \ D \\<^sup>* C \ + \ P \ \try e\<^sub>1 catch(C V) e\<^sub>2,s\<^sub>0\ \ \Throw a,(h\<^sub>1,l\<^sub>1,sh\<^sub>1)\" + +| Nil: + "P \ \[],s\ [\] \[],s\" + +| Cons: + "\ P \ \e,s\<^sub>0\ \ \Val v,s\<^sub>1\; P \ \es,s\<^sub>1\ [\] \es',s\<^sub>2\ \ + \ P \ \e#es,s\<^sub>0\ [\] \Val v # es',s\<^sub>2\" + +| ConsThrow: + "P \ \e, s\<^sub>0\ \ \throw e', s\<^sub>1\ \ + P \ \e#es, s\<^sub>0\ [\] \throw e' # es, s\<^sub>1\" + +\ \ init rules \ + +| InitFinal: + "P \ \e,s\ \ \e',s'\ \ P \ \INIT C (Nil,b) \ e,s\ \ \e',s'\" + +| InitNone: + "\ sh C = None; P \ \INIT C' (C#Cs,False) \ e,(h,l,sh(C \ (sblank P C, Prepared)))\ \ \e',s'\ \ + \ P \ \INIT C' (C#Cs,False) \ e,(h,l,sh)\ \ \e',s'\" + +| InitDone: + "\ sh C = Some(sfs,Done); P \ \INIT C' (Cs,True) \ e,(h,l,sh)\ \ \e',s'\ \ + \ P \ \INIT C' (C#Cs,False) \ e,(h,l,sh)\ \ \e',s'\" + +| InitProcessing: + "\ sh C = Some(sfs,Processing); P \ \INIT C' (Cs,True) \ e,(h,l,sh)\ \ \e',s'\ \ + \ P \ \INIT C' (C#Cs,False) \ e,(h,l,sh)\ \ \e',s'\" + +\ \ note that @{text RI} will mark all classes in the list Cs with the Error flag \ +| InitError: + "\ sh C = Some(sfs,Error); + P \ \RI (C, THROW NoClassDefFoundError);Cs \ e,(h,l,sh)\ \ \e',s'\ \ + \ P \ \INIT C' (C#Cs,False) \ e,(h,l,sh)\ \ \e',s'\" + +| InitObject: + "\ sh C = Some(sfs,Prepared); + C = Object; + sh' = sh(C \ (sfs,Processing)); + P \ \INIT C' (C#Cs,True) \ e,(h,l,sh')\ \ \e',s'\ \ + \ P \ \INIT C' (C#Cs,False) \ e,(h,l,sh)\ \ \e',s'\" + +| InitNonObject: + "\ sh C = Some(sfs,Prepared); + C \ Object; + class P C = Some (D,r); + sh' = sh(C \ (sfs,Processing)); + P \ \INIT C' (D#C#Cs,False) \ e,(h,l,sh')\ \ \e',s'\ \ + \ P \ \INIT C' (C#Cs,False) \ e,(h,l,sh)\ \ \e',s'\" + +| InitRInit: + "P \ \RI (C,C\\<^sub>sclinit([]));Cs \ e,(h,l,sh)\ \ \e',s'\ + \ P \ \INIT C' (C#Cs,True) \ e,(h,l,sh)\ \ \e',s'\" + +| RInit: + "\ P \ \e',s\ \ \Val v, (h',l',sh')\; + sh' C = Some(sfs, i); sh'' = sh'(C \ (sfs, Done)); + C' = last(C#Cs); + P \ \INIT C' (Cs,True) \ e, (h',l',sh'')\ \ \e\<^sub>1,s\<^sub>1\ \ + \ P \ \RI (C,e');Cs \ e,s\ \ \e\<^sub>1,s\<^sub>1\" + +| RInitInitFail: + "\ P \ \e',s\ \ \throw a, (h',l',sh')\; + sh' C = Some(sfs, i); sh'' = sh'(C \ (sfs, Error)); + P \ \RI (D,throw a);Cs \ e, (h',l',sh'')\ \ \e\<^sub>1,s\<^sub>1\ \ + \ P \ \RI (C,e');D#Cs \ e,s\ \ \e\<^sub>1,s\<^sub>1\" + +| RInitFailFinal: + "\ P \ \e',s\ \ \throw a, (h',l',sh')\; + sh' C = Some(sfs, i); sh'' = sh'(C \ (sfs, Error)) \ + \ P \ \RI (C,e');Nil \ e,s\ \ \throw a, (h',l',sh'')\" + +(*<*) +lemmas eval_evals_induct = eval_evals.induct [split_format (complete)] + and eval_evals_inducts = eval_evals.inducts [split_format (complete)] + +inductive_cases eval_cases [cases set]: + "P \ \new C,s\ \ \e',s'\" + "P \ \Cast C e,s\ \ \e',s'\" + "P \ \Val v,s\ \ \e',s'\" + "P \ \e\<^sub>1 \bop\ e\<^sub>2,s\ \ \e',s'\" + "P \ \Var v,s\ \ \e',s'\" + "P \ \V:=e,s\ \ \e',s'\" + "P \ \e\F{D},s\ \ \e',s'\" + "P \ \C\\<^sub>sF{D},s\ \ \e',s'\" + "P \ \e\<^sub>1\F{D}:=e\<^sub>2,s\ \ \e',s'\" + "P \ \C\\<^sub>sF{D}:=e\<^sub>2,s\ \ \e',s'\" + "P \ \e\M(es),s\ \ \e',s'\" + "P \ \C\\<^sub>sM(es),s\ \ \e',s'\" + "P \ \{V:T;e\<^sub>1},s\ \ \e',s'\" + "P \ \e\<^sub>1;;e\<^sub>2,s\ \ \e',s'\" + "P \ \if (e) e\<^sub>1 else e\<^sub>2,s\ \ \e',s'\" + "P \ \while (b) c,s\ \ \e',s'\" + "P \ \throw e,s\ \ \e',s'\" + "P \ \try e\<^sub>1 catch(C V) e\<^sub>2,s\ \ \e',s'\" + "P \ \INIT C (Cs,b) \ e,s\ \ \e',s'\" + "P \ \RI (C,e);Cs \ e\<^sub>0,s\ \ \e',s'\" + +inductive_cases evals_cases [cases set]: + "P \ \[],s\ [\] \e',s'\" + "P \ \e#es,s\ [\] \e',s'\" +(*>*) + +subsection "Final expressions" + +lemma eval_final: "P \ \e,s\ \ \e',s'\ \ final e'" + and evals_final: "P \ \es,s\ [\] \es',s'\ \ finals es'" +(*<*)by(induct rule:eval_evals.inducts, simp_all)(*>*) + +text\ Only used later, in the small to big translation, but is already a +good sanity check: \ + +lemma eval_finalId: "final e \ P \ \e,s\ \ \e,s\" +(*<*)by (erule finalE) (iprover intro: eval_evals.intros)+(*>*) + +lemma eval_final_same: "\ P \ \e,s\ \ \e',s'\; final e \ \ e = e' \ s = s'" +(*<*)by(auto elim!: finalE eval_cases)(*>*) + +lemma eval_finalsId: +assumes finals: "finals es" shows "P \ \es,s\ [\] \es,s\" +(*<*) + using finals +proof (induct es type: list) + case Nil show ?case by (rule eval_evals.intros) +next + case (Cons e es) + have hyp: "finals es \ P \ \es,s\ [\] \es,s\" + and finals: "finals (e # es)" by fact+ + show "P \ \e # es,s\ [\] \e # es,s\" + proof cases + assume "final e" + thus ?thesis + proof (cases rule: finalE) + fix v assume e: "e = Val v" + have "P \ \Val v,s\ \ \Val v,s\" by (simp add: eval_finalId) + moreover from finals e have "P \ \es,s\ [\] \es,s\" by(fast intro:hyp) + ultimately have "P \ \Val v#es,s\ [\] \Val v#es,s\" + by (rule eval_evals.intros) + with e show ?thesis by simp + next + fix a assume e: "e = Throw a" + have "P \ \Throw a,s\ \ \Throw a,s\" by (simp add: eval_finalId) + hence "P \ \Throw a#es,s\ [\] \Throw a#es,s\" by (rule eval_evals.intros) + with e show ?thesis by simp + qed + next + assume "\ final e" + with not_finals_ConsI finals have False by blast + thus ?thesis .. + qed +qed +(*>*) + +lemma evals_finals_same: +assumes finals: "finals es" +shows "P \ \es,s\ [\] \es',s'\ \ es = es' \ s = s'" + using finals +proof (induct es arbitrary: es' type: list) + case Nil then show ?case using evals_cases(1) by blast +next + case (Cons e es) + have IH: "\es'. P \ \es,s\ [\] \es',s'\ \ finals es \ es = es' \ s = s'" + and step: "P \ \e # es,s\ [\] \es',s'\" and finals: "finals (e # es)" by fact+ + then obtain e' es'' where es': "es' = e'#es''" by (meson Cons.prems(1) evals_cases(2)) + have fe: "final e" using finals not_finals_ConsI by auto + show ?case + proof(rule evals_cases(2)[OF step]) + fix v s\<^sub>1 es1 assume es1: "es' = Val v # es1" + and estep: "P \ \e,s\ \ \Val v,s\<^sub>1\" and esstep: "P \ \es,s\<^sub>1\ [\] \es1,s'\" + then have "e = Val v" using eval_final_same fe by auto + then have "finals es" using es' not_finals_ConsI2 finals by blast + then show ?thesis using es' IH estep esstep es1 eval_final_same fe by blast + next + fix e' assume es1: "es' = throw e' # es" and estep: "P \ \e,s\ \ \throw e',s'\" + then have "e = throw e'" using eval_final_same fe by auto + then show ?thesis using es' estep es1 eval_final_same fe by blast + qed +qed +(*>*) + +subsection "Property preservation" + +lemma evals_length: "P \ \es,s\ [\] \es',s'\ \ length es = length es'" + by(induct es arbitrary:es' s s', auto elim: evals_cases) + +corollary evals_empty: "P \ \es,s\ [\] \es',s'\ \ (es = []) = (es' = [])" + by(drule evals_length, fastforce) + +(****) + +theorem eval_hext: "P \ \e,(h,l,sh)\ \ \e',(h',l',sh')\ \ h \ h'" +and evals_hext: "P \ \es,(h,l,sh)\ [\] \es',(h',l',sh')\ \ h \ h'" +(*<*) +proof (induct rule: eval_evals_inducts) + case New thus ?case + by(fastforce intro!: hext_new intro:LeastI simp:new_Addr_def + split:if_split_asm simp del:fun_upd_apply) +next + case NewInit thus ?case + by (meson hext_new hext_trans new_Addr_SomeD) +next + case FAss thus ?case + by(auto simp:sym[THEN hext_upd_obj] simp del:fun_upd_apply + elim!: hext_trans) +qed (auto elim!: hext_trans) +(*>*) + + +lemma eval_lcl_incr: "P \ \e,(h\<^sub>0,l\<^sub>0,sh\<^sub>0)\ \ \e',(h\<^sub>1,l\<^sub>1,sh\<^sub>1)\ \ dom l\<^sub>0 \ dom l\<^sub>1" + and evals_lcl_incr: "P \ \es,(h\<^sub>0,l\<^sub>0,sh\<^sub>0)\ [\] \es',(h\<^sub>1,l\<^sub>1,sh\<^sub>1)\ \ dom l\<^sub>0 \ dom l\<^sub>1" +(*<*) +proof (induct rule: eval_evals_inducts) + case BinOp show ?case by(rule subset_trans)(rule BinOp.hyps)+ +next + case Call thus ?case + by(simp del: fun_upd_apply) +next + case Seq show ?case by(rule subset_trans)(rule Seq.hyps)+ +next + case CondT show ?case by(rule subset_trans)(rule CondT.hyps)+ +next + case CondF show ?case by(rule subset_trans)(rule CondF.hyps)+ +next + case WhileT thus ?case by(blast) +next + case TryCatch thus ?case by(clarsimp simp:dom_def split:if_split_asm) blast +next + case Cons show ?case by(rule subset_trans)(rule Cons.hyps)+ +next + case Block thus ?case by(auto simp del:fun_upd_apply) +qed auto +(*>*) + +lemma +shows init_ri_same_loc: "P \ \e,(h,l,sh)\ \ \e',(h',l',sh')\ + \ (\C Cs b M a. e = INIT C (Cs,b) \ unit \ e = C\\<^sub>sM([]) \ e = RI (C,Throw a) ; Cs \ unit + \ e = RI (C,C\\<^sub>sclinit([])) ; Cs \ unit + \ l = l')" + and "P \ \es,(h,l,sh)\ [\] \es',(h',l',sh')\ \ True" +proof(induct rule: eval_evals_inducts) + case (RInitInitFail e h l sh a') + then show ?case using eval_final[of _ _ _ "throw a'"] + by(fastforce dest: eval_final_same[of _ "Throw a"]) +next + case RInitFailFinal then show ?case by(auto dest: eval_final_same) +qed(auto dest: evals_cases eval_cases(17) eval_final_same) + +lemma init_same_loc: "P \ \INIT C (Cs,b) \ unit,(h,l,sh)\ \ \e',(h',l',sh')\ \ l = l'" + by(simp add: init_ri_same_loc) + +(****) + +lemma assumes wf: "wwf_J_prog P" +shows eval_proc_pres': "P \ \e,(h,l,sh)\ \ \e',(h',l',sh')\ + \ not_init C e \ \sfs. sh C = \(sfs, Processing)\ \ \sfs'. sh' C = \(sfs', Processing)\" + and evals_proc_pres': "P \ \es,(h,l,sh)\ [\] \es',(h',l',sh')\ + \ not_inits C es \ \sfs. sh C = \(sfs, Processing)\ \ \sfs'. sh' C = \(sfs', Processing)\" +(*<*) +proof(induct rule:eval_evals_inducts) + case Call then show ?case using sees_wwf_nsub_RI[OF wf Call.hyps(6)] nsub_RI_not_init by auto +next + case (SCallInit ps h l sh vs h\<^sub>1 l\<^sub>1 sh\<^sub>1 C' M Ts T pns body D v' h\<^sub>2 l\<^sub>2 sh\<^sub>2 l\<^sub>2' e' h\<^sub>3 l\<^sub>3 sh\<^sub>3) + then show ?case + using SCallInit sees_wwf_nsub_RI[OF wf SCallInit.hyps(3)] nsub_RI_not_init[of body] by auto +next + case SCall then show ?case using sees_wwf_nsub_RI[OF wf SCall.hyps(3)] nsub_RI_not_init by auto +next + case (InitNone sh C1 C' Cs h l e' a a b) then show ?case by(cases "C = C1") auto +next + case (InitDone sh C sfs C' Cs h l e' a a b) then show ?case by(cases Cs, auto) +next + case (InitProcessing sh C sfs C' Cs h l e' a a b) then show ?case by(cases Cs, auto) +next + case (InitError sh C1 sfs Cs h l e' a a b C') then show ?case by(cases "C = C1") auto +next + case (InitObject sh C1 sfs sh' C' Cs h l e' a a b) then show ?case by(cases "C = C1") auto +next + case (InitNonObject sh C1 sfs D a b sh' C' Cs h l e' a a b) + then show ?case by(cases "C = C1") auto +next + case (RInit e a a b v h' l' sh' C sfs i sh'' C' Cs e\<^sub>1 a a b) then show ?case by(cases Cs, auto) +next + case (RInitInitFail e h l sh a h' l' sh' C1 sfs i sh'' D Cs e\<^sub>1 h1 l1 sh1) + then show ?case using eval_final by fastforce +qed(auto) + +(************************************************) + +subsection\Init Elimination rules\ + +lemma init_NilE: +assumes init: "P \ \INIT C (Nil,b) \ unit,s\ \ \e',s'\" +shows "e' = unit \ s' = s" +proof(rule eval_cases(19)[OF init]) \ \ Init \ qed(auto dest: eval_final_same) + +lemma init_ProcessingE: +assumes shC: "sh C = \(sfs, Processing)\" + and init: "P \ \INIT C ([C],False) \ unit,(h,l,sh)\ \ \e',s'\" +shows "e' = unit \ s' = (h,l,sh)" +proof(rule eval_cases(19)[OF init]) \ \ Init \ + fix sha Ca sfs Cs ha la + assume "(h, l, sh) = (ha, la, sha)" and "sha Ca = \(sfs, Processing)\" + and "P \ \INIT C (Cs,True) \ unit,(ha, la, sha)\ \ \e',s'\" and "[C] = Ca # Cs" + then show ?thesis using init_NilE by simp +next + fix sha sfs Cs ha la + assume "(h, l, sh) = (ha, la, sha)" and "sha Object = \(sfs, Prepared)\" + and "[C] = Object # Cs" + then show ?thesis using shC by clarsimp +qed(auto simp: assms) + + +lemma rinit_throwE: +"P \ \RI (C,throw e) ; Cs \ e\<^sub>0,s\ \ \e',s'\ + \ \a s\<^sub>t. e' = throw a \ P \ \throw e,s\ \ \throw a,s\<^sub>t\" +proof(induct Cs arbitrary: C e s) + case Nil + then show ?case + proof(rule eval_cases(20)) \ \ RI \ + fix v h' l' sh' assume "P \ \throw e,s\ \ \Val v,(h', l', sh')\" + then show ?case using eval_cases(17) by blast + qed(auto) +next + case (Cons C' Cs') + show ?case using Cons.prems(1) + proof(rule eval_cases(20)) \ \ RI \ + fix v h' l' sh' assume "P \ \throw e,s\ \ \Val v,(h', l', sh')\" + then show ?case using eval_cases(17) by blast + next + fix a h' l' sh' sfs i D Cs'' + assume e''step: "P \ \throw e,s\ \ \throw a,(h', l', sh')\" + and shC: "sh' C = \(sfs, i)\" + and riD: "P \ \RI (D,throw a) ; Cs'' \ e\<^sub>0,(h', l', sh'(C \ (sfs, Error)))\ \ \e',s'\" + and "C' # Cs' = D # Cs''" + then show ?thesis using Cons.hyps eval_final eval_final_same by blast + qed(simp) +qed + +lemma rinit_ValE: +assumes ri: "P \ \RI (C,e) ; Cs \ unit,s\ \ \Val v',s'\" +shows "\v'' s''. P \ \e,s\ \ \Val v'',s''\" +proof(rule eval_cases(20)[OF ri]) \ \ RI \ + fix a h' l' sh' sfs i D Cs' + assume "P \ \RI (D,throw a) ; Cs' \ unit,(h', l', sh'(C \ (sfs, Error)))\ \ \Val v',s'\" + then show ?thesis using rinit_throwE by blast +qed(auto) + +subsection "Some specific evaluations" + +lemma lass_val_of_eval: + "\ lass_val_of e = \a\; P \ \e,(h, l, sh)\ \ \e',(h', l', sh')\ \ + \ e' = unit \ h' = h \ l' = l(fst a\snd a) \ sh' = sh" + by(drule lass_val_of_spec, auto elim: eval.cases) + +lemma eval_throw_nonVal: +assumes eval: "P \ \e,s\ \ \throw a,s'\" +shows "val_of e = None" +proof(cases "val_of e") + case (Some v) show ?thesis using eval by(auto simp: val_of_spec[OF Some] intro: eval.cases) +qed(simp) + +lemma eval_throw_nonLAss: +assumes eval: "P \ \e,s\ \ \throw a,s'\" +shows "lass_val_of e = None" +proof(cases "lass_val_of e") + case (Some v) show ?thesis using eval by(auto simp: lass_val_of_spec[OF Some] intro: eval.cases) +qed(simp) + +end diff --git a/thys/JinjaDCI/J/DefAss.thy b/thys/JinjaDCI/J/DefAss.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/J/DefAss.thy @@ -0,0 +1,189 @@ +(* Title: JinjaDCI/J/DefAss.thy + Author: Tobias Nipkow, Susannah Mansky + Copyright 2003 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory J/DefAss.thy by Tobias Nipkow +*) + +section \ Definite assignment \ + +theory DefAss imports BigStep begin + +subsection "Hypersets" + +type_synonym 'a hyperset = "'a set option" + +definition hyperUn :: "'a hyperset \ 'a hyperset \ 'a hyperset" (infixl "\" 65) +where + "A \ B \ case A of None \ None + | \A\ \ (case B of None \ None | \B\ \ \A \ B\)" + +definition hyperInt :: "'a hyperset \ 'a hyperset \ 'a hyperset" (infixl "\" 70) +where + "A \ B \ case A of None \ B + | \A\ \ (case B of None \ \A\ | \B\ \ \A \ B\)" + +definition hyperDiff1 :: "'a hyperset \ 'a \ 'a hyperset" (infixl "\" 65) +where + "A \ a \ case A of None \ None | \A\ \ \A - {a}\" + +definition hyper_isin :: "'a \ 'a hyperset \ bool" (infix "\\" 50) +where + "a \\ A \ case A of None \ True | \A\ \ a \ A" + +definition hyper_subset :: "'a hyperset \ 'a hyperset \ bool" (infix "\" 50) +where + "A \ B \ case B of None \ True + | \B\ \ (case A of None \ False | \A\ \ A \ B)" + +lemmas hyperset_defs = + hyperUn_def hyperInt_def hyperDiff1_def hyper_isin_def hyper_subset_def + +lemma [simp]: "\{}\ \ A = A \ A \ \{}\ = A" +(*<*)by(simp add:hyperset_defs)(*>*) + +lemma [simp]: "\A\ \ \B\ = \A \ B\ \ \A\ \ a = \A - {a}\" +(*<*)by(simp add:hyperset_defs)(*>*) + +lemma [simp]: "None \ A = None \ A \ None = None" +(*<*)by(simp add:hyperset_defs)(*>*) + +lemma [simp]: "a \\ None \ None \ a = None" +(*<*)by(simp add:hyperset_defs)(*>*) + +lemma hyper_isin_union: "x \\ \A\ \ x \\ \A\ \ B" + by(case_tac B, auto simp: hyper_isin_def) + +lemma hyperUn_assoc: "(A \ B) \ C = A \ (B \ C)" +(*<*)by(simp add:hyperset_defs Un_assoc)(*>*) + +lemma hyper_insert_comm: "A \ \{a}\ = \{a}\ \ A \ A \ (\{a}\ \ B) = \{a}\ \ (A \ B)" +(*<*)by(simp add:hyperset_defs)(*>*) + +lemma hyper_comm: "A \ B = B \ A \ A \ B \ C = B \ A \ C" +apply(case_tac A, simp, case_tac B, simp) +apply(case_tac C, simp add: Un_commute) +apply(simp add: Un_left_commute Un_commute) +done + +subsection "Definite assignment" + +primrec + \ :: "'a exp \ 'a hyperset" + and \s :: "'a exp list \ 'a hyperset" +where + "\ (new C) = \{}\" +| "\ (Cast C e) = \ e" +| "\ (Val v) = \{}\" +| "\ (e\<^sub>1 \bop\ e\<^sub>2) = \ e\<^sub>1 \ \ e\<^sub>2" +| "\ (Var V) = \{}\" +| "\ (LAss V e) = \{V}\ \ \ e" +| "\ (e\F{D}) = \ e" +| "\ (C\\<^sub>sF{D}) = \{}\" +| "\ (e\<^sub>1\F{D}:=e\<^sub>2) = \ e\<^sub>1 \ \ e\<^sub>2" +| "\ (C\\<^sub>sF{D}:=e\<^sub>2) = \ e\<^sub>2" +| "\ (e\M(es)) = \ e \ \s es" +| "\ (C\\<^sub>sM(es)) = \s es" +| "\ ({V:T; e}) = \ e \ V" +| "\ (e\<^sub>1;;e\<^sub>2) = \ e\<^sub>1 \ \ e\<^sub>2" +| "\ (if (e) e\<^sub>1 else e\<^sub>2) = \ e \ (\ e\<^sub>1 \ \ e\<^sub>2)" +| "\ (while (b) e) = \ b" +| "\ (throw e) = None" +| "\ (try e\<^sub>1 catch(C V) e\<^sub>2) = \ e\<^sub>1 \ (\ e\<^sub>2 \ V)" +| "\ (INIT C (Cs,b) \ e) = \{}\" +| "\ (RI (C,e);Cs \ e') = \ e" + +| "\s ([]) = \{}\" +| "\s (e#es) = \ e \ \s es" + +primrec + \ :: "'a exp \ 'a hyperset \ bool" + and \s :: "'a exp list \ 'a hyperset \ bool" +where + "\ (new C) A = True" +| "\ (Cast C e) A = \ e A" +| "\ (Val v) A = True" +| "\ (e\<^sub>1 \bop\ e\<^sub>2) A = (\ e\<^sub>1 A \ \ e\<^sub>2 (A \ \ e\<^sub>1))" +| "\ (Var V) A = (V \\ A)" +| "\ (LAss V e) A = \ e A" +| "\ (e\F{D}) A = \ e A" +| "\ (C\\<^sub>sF{D}) A = True" +| "\ (e\<^sub>1\F{D}:=e\<^sub>2) A = (\ e\<^sub>1 A \ \ e\<^sub>2 (A \ \ e\<^sub>1))" +| "\ (C\\<^sub>sF{D}:=e\<^sub>2) A = \ e\<^sub>2 A" +| "\ (e\M(es)) A = (\ e A \ \s es (A \ \ e))" +| "\ (C\\<^sub>sM(es)) A = \s es A" +| "\ ({V:T; e}) A = \ e (A \ V)" +| "\ (e\<^sub>1;;e\<^sub>2) A = (\ e\<^sub>1 A \ \ e\<^sub>2 (A \ \ e\<^sub>1))" +| "\ (if (e) e\<^sub>1 else e\<^sub>2) A = + (\ e A \ \ e\<^sub>1 (A \ \ e) \ \ e\<^sub>2 (A \ \ e))" +| "\ (while (e) c) A = (\ e A \ \ c (A \ \ e))" +| "\ (throw e) A = \ e A" +| "\ (try e\<^sub>1 catch(C V) e\<^sub>2) A = (\ e\<^sub>1 A \ \ e\<^sub>2 (A \ \{V}\))" +| "\ (INIT C (Cs,b) \ e) A = \ e A" +| "\ (RI (C,e);Cs \ e') A = (\ e A \ \ e' A)" + +| "\s ([]) A = True" +| "\s (e#es) A = (\ e A \ \s es (A \ \ e))" + +lemma As_map_Val[simp]: "\s (map Val vs) = \{}\" +(*<*)by (induct vs) simp_all(*>*) + +lemma D_append[iff]: "\A. \s (es @ es') A = (\s es A \ \s es' (A \ \s es))" +(*<*)by (induct es type:list) (auto simp:hyperUn_assoc)(*>*) + + +lemma A_fv: "\A. \ e = \A\ \ A \ fv e" +and "\A. \s es = \A\ \ A \ fvs es" +(*<*) +apply(induct e and es rule: \.induct \s.induct) +apply (simp_all add:hyperset_defs) +apply blast+ +done +(*>*) + + +lemma sqUn_lem: "A \ A' \ A \ B \ A' \ B" +(*<*)by(simp add:hyperset_defs) blast(*>*) + +lemma diff_lem: "A \ A' \ A \ b \ A' \ b" +(*<*)by(simp add:hyperset_defs) blast(*>*) + +(* This order of the premises avoids looping of the simplifier *) +lemma D_mono: "\A A'. A \ A' \ \ e A \ \ (e::'a exp) A'" +and Ds_mono: "\A A'. A \ A' \ \s es A \ \s (es::'a exp list) A'" +(*<*) +apply(induct e and es rule: \.induct \s.induct) +apply simp +apply simp +apply simp +apply simp apply (iprover dest:sqUn_lem) +apply (fastforce simp add:hyperset_defs) +apply simp +apply simp +apply simp +apply simp apply (iprover dest:sqUn_lem) +apply simp +apply simp apply (iprover dest:sqUn_lem) +apply simp +apply simp apply (iprover dest:diff_lem) +apply simp apply (iprover dest:sqUn_lem) +apply simp apply (iprover dest:sqUn_lem) +apply simp apply (iprover dest:sqUn_lem) +apply simp +apply simp apply (iprover dest:sqUn_lem) +apply simp +apply simp +apply simp +apply simp apply (iprover dest:sqUn_lem) +done +(*>*) + +(* And this is the order of premises preferred during application: *) +lemma D_mono': "\ e A \ A \ A' \ \ e A'" +and Ds_mono': "\s es A \ A \ A' \ \s es A'" +(*<*)by(blast intro:D_mono, blast intro:Ds_mono)(*>*) + + +lemma Ds_Vals: "\s (map Val vs) A" by(induct vs, auto) + +end diff --git a/thys/JinjaDCI/J/EConform.thy b/thys/JinjaDCI/J/EConform.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/J/EConform.thy @@ -0,0 +1,350 @@ +(* Title: JinjaDCI/J/EConform.thy + Author: Susannah Mansky + 2019-20 UIUC +*) + +section \ Expression conformance properties \ + +theory EConform +imports SmallStep BigStep +begin + +lemma cons_to_append: "list \ [] \ (\ls. a # list = ls @ [last list])" + by (metis append_butlast_last_id last_ConsR list.simps(3)) + +subsection "Initialization conformance" + +\ \ returns class that can be initialized (if any) by top-level expression \ +fun init_class :: "'m prog \ 'a exp \ cname option" where +"init_class P (new C) = Some C" | +"init_class P (C\\<^sub>sF{D}) = Some D" | +"init_class P (C\\<^sub>sF{D}:=e\<^sub>2) = Some D" | +"init_class P (C\\<^sub>sM(es)) = seeing_class P C M" | +"init_class _ _ = None" + +lemma icheck_init_class: "icheck P C e \ init_class P e = \C\" +apply(induct e, auto) apply(rename_tac x1 x2 x3 x4) +apply(case_tac x4, auto) +done + +\ \ exp to take next small step (in particular, subexp that may contain initialization) \ +fun ss_exp :: "'a exp \ 'a exp" and ss_exps :: "'a exp list \ 'a exp option" where + "ss_exp (new C) = new C" +| "ss_exp (Cast C e) = (case val_of e of Some v \ Cast C e | _ \ ss_exp e)" +| "ss_exp (Val v) = Val v" +| "ss_exp (e\<^sub>1 \bop\ e\<^sub>2) = (case val_of e\<^sub>1 of Some v \ (case val_of e\<^sub>2 of Some v \ e\<^sub>1 \bop\ e\<^sub>2 | _ \ ss_exp e\<^sub>2) + | _ \ ss_exp e\<^sub>1)" +| "ss_exp (Var V) = Var V" +| "ss_exp (LAss V e) = (case val_of e of Some v \ LAss V e | _ \ ss_exp e)" +| "ss_exp (e\F{D}) = (case val_of e of Some v \ e\F{D} | _ \ ss_exp e)" +| "ss_exp (C\\<^sub>sF{D}) = C\\<^sub>sF{D}" +| "ss_exp (e\<^sub>1\F{D}:=e\<^sub>2) = (case val_of e\<^sub>1 of Some v \ (case val_of e\<^sub>2 of Some v \ e\<^sub>1\F{D}:=e\<^sub>2 | _ \ ss_exp e\<^sub>2) + | _ \ ss_exp e\<^sub>1)" +| "ss_exp (C\\<^sub>sF{D}:=e\<^sub>2) = (case val_of e\<^sub>2 of Some v \ C\\<^sub>sF{D}:=e\<^sub>2 | _ \ ss_exp e\<^sub>2)" +| "ss_exp (e\M(es)) = (case val_of e of Some v \ (case map_vals_of es of Some t \ e\M(es) | _ \ the(ss_exps es)) + | _ \ ss_exp e)" +| "ss_exp (C\\<^sub>sM(es)) = (case map_vals_of es of Some t \ C\\<^sub>sM(es) | _ \ the(ss_exps es))" +| "ss_exp ({V:T; e}) = ss_exp e" +| "ss_exp (e\<^sub>1;;e\<^sub>2) = (case val_of e\<^sub>1 of Some v \ ss_exp e\<^sub>2 + | None \ (case lass_val_of e\<^sub>1 of Some p \ ss_exp e\<^sub>2 + | None \ ss_exp e\<^sub>1))" +| "ss_exp (if (b) e\<^sub>1 else e\<^sub>2) = (case bool_of b of Some True \ if (b) e\<^sub>1 else e\<^sub>2 + | Some False \ if (b) e\<^sub>1 else e\<^sub>2 + | _ \ ss_exp b)" +| "ss_exp (while (b) e) = while (b) e" +| "ss_exp (throw e) = (case val_of e of Some v \ throw e | _ \ ss_exp e)" +| "ss_exp (try e\<^sub>1 catch(C V) e\<^sub>2) = (case val_of e\<^sub>1 of Some v \ try e\<^sub>1 catch(C V) e\<^sub>2 + | _ \ ss_exp e\<^sub>1)" +| "ss_exp (INIT C (Cs,b) \ e) = INIT C (Cs,b) \ e" +| "ss_exp (RI (C,e);Cs \ e') = (case val_of e of Some v \ RI (C,e);Cs \ e | _ \ ss_exp e)" +| "ss_exps([]) = None" +| "ss_exps(e#es) = (case val_of e of Some v \ ss_exps es | _ \ Some (ss_exp e))" + +(*<*) +lemmas ss_exp_ss_exps_induct = ss_exp_ss_exps.induct + [ case_names New Cast Val BinOp Var LAss FAcc SFAcc FAss SFAss Call SCall + Block Seq Cond While Throw Try Init RI Nil Cons ] +(*>*) + +lemma icheck_ss_exp: +assumes "icheck P C e" shows "ss_exp e = e" +using assms +proof(cases e) + case (SFAss C F D e) then show ?thesis using assms + proof(cases e)qed(auto) +qed(auto) + +lemma ss_exps_Vals_None[simp]: + "ss_exps (map Val vs) = None" + by(induct vs, auto) + +lemma ss_exps_Vals_NoneI: + "ss_exps es = None \ \vs. es = map Val vs" +using val_of_spec by(induct es, auto) + +lemma ss_exps_throw_nVal: + "\ val_of e = None; ss_exps (map Val vs @ throw e # es') = \e'\ \ + \ e' = ss_exp e" + by(induct vs, auto) + +lemma ss_exps_throw_Val: + "\ val_of e = \a\; ss_exps (map Val vs @ throw e # es') = \e'\ \ + \ e' = throw e" + by(induct vs, auto) + + +abbreviation curr_init :: "'m prog \ 'a exp \ cname option" where +"curr_init P e \ init_class P (ss_exp e)" +abbreviation curr_inits :: "'m prog \ 'a exp list \ cname option" where +"curr_inits P es \ case ss_exps es of Some e \ init_class P e | _ \ None" + +lemma icheck_curr_init': "\e'. ss_exp e = e' \ icheck P C e' \ curr_init P e = \C\" + and icheck_curr_inits': "\e. ss_exps es = \e\ \ icheck P C e \ curr_inits P es = \C\" +proof(induct rule: ss_exp_ss_exps_induct) +qed(simp_all add: icheck_init_class) + +lemma icheck_curr_init: "icheck P C e' \ ss_exp e = e' \ curr_init P e = \C\" + by(rule icheck_curr_init') + +lemma icheck_curr_inits: "icheck P C e \ ss_exps es = \e\ \ curr_inits P es = \C\" + by(rule icheck_curr_inits') + +definition initPD :: "sheap \ cname \ bool" where +"initPD sh C \ \sfs i. sh C = Some (sfs, i) \ (i = Done \ i = Processing)" + +\ \ checks that @{text INIT} and @{text RI} conform and are only in the main computation \ +fun iconf :: "sheap \ 'a exp \ bool" and iconfs :: " sheap \ 'a exp list \ bool" where + "iconf sh (new C) = True" +| "iconf sh (Cast C e) = iconf sh e" +| "iconf sh (Val v) = True" +| "iconf sh (e\<^sub>1 \bop\ e\<^sub>2) = (case val_of e\<^sub>1 of Some v \ iconf sh e\<^sub>2 | _ \ iconf sh e\<^sub>1 \ \sub_RI e\<^sub>2)" +| "iconf sh (Var V) = True" +| "iconf sh (LAss V e) = iconf sh e" +| "iconf sh (e\F{D}) = iconf sh e" +| "iconf sh (C\\<^sub>sF{D}) = True" +| "iconf sh (e\<^sub>1\F{D}:=e\<^sub>2) = (case val_of e\<^sub>1 of Some v \ iconf sh e\<^sub>2 | _ \ iconf sh e\<^sub>1 \ \sub_RI e\<^sub>2)" +| "iconf sh (C\\<^sub>sF{D}:=e\<^sub>2) = iconf sh e\<^sub>2" +| "iconf sh (e\M(es)) = (case val_of e of Some v \ iconfs sh es | _ \ iconf sh e \ \sub_RIs es)" +| "iconf sh (C\\<^sub>sM(es)) = iconfs sh es" +| "iconf sh ({V:T; e}) = iconf sh e" +| "iconf sh (e\<^sub>1;;e\<^sub>2) = (case val_of e\<^sub>1 of Some v \ iconf sh e\<^sub>2 + | None \ (case lass_val_of e\<^sub>1 of Some p \ iconf sh e\<^sub>2 + | None \ iconf sh e\<^sub>1 \ \sub_RI e\<^sub>2))" +| "iconf sh (if (b) e\<^sub>1 else e\<^sub>2) = (iconf sh b \ \sub_RI e\<^sub>1 \ \sub_RI e\<^sub>2)" +| "iconf sh (while (b) e) = (\sub_RI b \ \sub_RI e)" +| "iconf sh (throw e) = iconf sh e" +| "iconf sh (try e\<^sub>1 catch(C V) e\<^sub>2) = (iconf sh e\<^sub>1 \ \sub_RI e\<^sub>2)" +| "iconf sh (INIT C (Cs,b) \ e) = ((case Cs of Nil \ initPD sh C | C'#Cs' \ last Cs = C) \ \sub_RI e)" +| "iconf sh (RI (C,e);Cs \ e') = (iconf sh e \ \sub_RI e')" +| "iconfs sh ([]) = True" +| "iconfs sh (e#es) = (case val_of e of Some v \ iconfs sh es | _ \ iconf sh e \ \sub_RIs es)" + +lemma iconfs_map_throw: "iconfs sh (map Val vs @ throw e # es') \ iconf sh e" + by(induct vs,auto) + +lemma nsub_RI_iconf_aux: + "(\sub_RI (e::'a exp) \ (\e'. e' \ subexp e \ \sub_RI e' \ iconf sh e') \ iconf sh e) + \ (\sub_RIs (es::'a exp list) \ (\e'. e' \ subexps es \ \sub_RI e' \ iconf sh e') \ iconfs sh es)" +proof(induct rule: sub_RI_sub_RIs.induct) qed(auto) + +lemma nsub_RI_iconf_aux': + "(\e'. subexp_of e' e \ \sub_RI e' \ iconf sh e') \ (\sub_RI e \ iconf sh e)" + by(simp add: nsub_RI_iconf_aux) + +lemma nsub_RI_iconf: "\sub_RI e \ iconf sh e" +apply(cut_tac e = e and R = "\e. \sub_RI e \ iconf sh e" in subexp_induct) + apply(rename_tac ea) apply(case_tac ea, simp_all) +apply(clarsimp simp: nsub_RI_iconf_aux) +done + +lemma nsub_RIs_iconfs: "\sub_RIs es \ iconfs sh es" +apply(cut_tac es = es and R = "\e. \sub_RI e \ iconf sh e" + and Rs = "\es. \sub_RIs es \ iconfs sh es" in subexps_induct) + apply(rename_tac esa) apply(case_tac esa, simp_all) + apply(clarsimp simp: nsub_RI_iconf_aux)+ +done + +lemma lass_val_of_iconf: "lass_val_of e = \a\ \ iconf sh e" + by(drule lass_val_of_nsub_RI, erule nsub_RI_iconf) + +lemma icheck_iconf: +assumes "icheck P C e" shows "iconf sh e" +using assms +proof(cases e) + case (SFAss C F D e) then show ?thesis using assms + proof(cases e)qed(auto) +next + case (SCall C M es) then show ?thesis using assms + by (auto simp: nsub_RIs_iconfs) +next +qed(auto) + + +subsection "Indicator boolean conformance" + +\ \ checks that the given expression, indicator boolean pair is allowed in small-step + (i.e., if @{term b} is True, then @{term e} is an initialization-calling expression to + a class that is marked either @{term Processing} or @{term Done}) \ +definition bconf :: "'m prog \ sheap \ 'a exp \ bool \ bool" ("_,_ \\<^sub>b '(_,_') \" [51,51,0,0] 50) +where + "P,sh \\<^sub>b (e,b) \ \ b \ (\C. icheck P C (ss_exp e) \ initPD sh C)" + +definition bconfs :: "'m prog \ sheap \ 'a exp list \ bool \ bool" ("_,_ \\<^sub>b '(_,_') \" [51,51,0,0] 50) +where + "P,sh \\<^sub>b (es,b) \ \ b \ (\C. (icheck P C (the(ss_exps es)) + \ (curr_inits P es = Some C) \ initPD sh C))" + + +\ \ bconf helper lemmas \ + +lemma bconf_nonVal[simp]: + "P,sh \\<^sub>b (e,True) \ \ val_of e = None" + by(cases e, auto simp: bconf_def) + +lemma bconfs_nonVals[simp]: + "P,sh \\<^sub>b (es,True) \ \ map_vals_of es = None" + by(induct es, auto simp: bconfs_def) + +lemma bconf_Cast[iff]: + "P,sh \\<^sub>b (Cast C e,b) \ \ P,sh \\<^sub>b (e,b) \" +apply(unfold bconf_def, cases b, auto) +apply(drule val_of_spec, simp) +done + +lemma bconf_BinOp[iff]: + "P,sh \\<^sub>b (e1 \bop\ e2,b) \ + \ (case val_of e1 of Some v \ P,sh \\<^sub>b (e2,b) \ | _ \ P,sh \\<^sub>b (e1,b) \)" +apply(unfold bconf_def, cases b, auto) +apply(drule val_of_spec, simp) +done + +lemma bconf_LAss[iff]: + "P,sh \\<^sub>b (LAss V e,b) \ \ P,sh \\<^sub>b (e,b) \" +apply(unfold bconf_def, cases b, auto) +apply(drule val_of_spec, simp) +done + +lemma bconf_FAcc[iff]: + "P,sh \\<^sub>b (e\F{D},b) \ \ P,sh \\<^sub>b (e,b) \" +apply(unfold bconf_def, cases b, auto) +apply(drule val_of_spec, simp) +done + +lemma bconf_FAss[iff]: + "P,sh \\<^sub>b (FAss e1 F D e2,b) \ + \ (case val_of e1 of Some v \ P,sh \\<^sub>b (e2,b) \ | _ \ P,sh \\<^sub>b (e1,b) \)" +apply(unfold bconf_def, cases b, auto) +apply(drule val_of_spec, simp) +done + +lemma bconf_SFAss[iff]: +"val_of e2 = None \ P,sh \\<^sub>b (SFAss C F D e2,b) \ \ P,sh \\<^sub>b (e2,b) \" + by(unfold bconf_def, cases b, auto) + +lemma bconfs_Vals[iff]: + "P,sh \\<^sub>b (map Val vs, b) \ \ \ b" + by(unfold bconfs_def, simp) + +lemma bconf_Call[iff]: + "P,sh \\<^sub>b (e\M(es),b) \ + \ (case val_of e of Some v \ P,sh \\<^sub>b (es,b) \ | _ \ P,sh \\<^sub>b (e,b) \)" +proof(cases b) + case True + then show ?thesis + proof(cases "ss_exps es") + case None + then obtain vs where "es = map Val vs" using ss_exps_Vals_NoneI by auto + then have mv: "map_vals_of es = \vs\" by simp + then show ?thesis by(auto simp: bconf_def) (simp add: bconfs_def) + next + case (Some a) + then show ?thesis by(auto simp: bconf_def, auto simp: bconfs_def icheck_init_class) + qed +qed(simp add: bconf_def bconfs_def) + +lemma bconf_SCall[iff]: +assumes mvn: "map_vals_of es = None" +shows "P,sh \\<^sub>b (C\\<^sub>sM(es),b) \ \ P,sh \\<^sub>b (es,b) \" +proof(cases b) + case True + then show ?thesis + proof(cases "ss_exps es") + case None + then have "\vs. es = map Val vs" using ss_exps_Vals_NoneI by auto + then show ?thesis using mvn finals_def by clarsimp + next + case (Some a) + then show ?thesis by(auto simp: bconf_def, auto simp: bconfs_def icheck_init_class) + qed +qed(simp add: bconf_def bconfs_def) + +lemma bconf_Cons[iff]: + "P,sh \\<^sub>b (e#es,b) \ + \ (case val_of e of Some v \ P,sh \\<^sub>b (es,b) \ | _ \ P,sh \\<^sub>b (e,b) \)" +proof(cases b) + case True + then show ?thesis + proof(cases "ss_exps es") + case None + then have "\vs. es = map Val vs" using ss_exps_Vals_NoneI by auto + then show ?thesis using None by(auto simp: bconf_def bconfs_def icheck_init_class) + next + case (Some a) + then show ?thesis by(auto simp: bconf_def bconfs_def icheck_init_class) + qed +qed(simp add: bconf_def bconfs_def) + +lemma bconf_InitBlock[iff]: + "P,sh \\<^sub>b ({V:T; V:=Val v;; e\<^sub>2},b) \ \ P,sh \\<^sub>b (e\<^sub>2,b) \" + by(unfold bconf_def, cases b, auto simp: assigned_def) + +lemma bconf_Block[iff]: + "P,sh \\<^sub>b ({V:T; e},b) \ \ P,sh \\<^sub>b (e,b) \" + by(unfold bconf_def, cases b, auto) + +lemma bconf_Seq[iff]: + "P,sh \\<^sub>b (e1;;e2,b) \ + \ (case val_of e1 of Some v \ P,sh \\<^sub>b (e2,b) \ + | _ \ (case lass_val_of e1 of Some p \ P,sh \\<^sub>b (e2,b) \ + | None \ P,sh \\<^sub>b (e1,b) \))" (* \ P,sh \\<^sub>b (e1,b) \"*) +by(unfold bconf_def, cases b, auto dest: val_of_spec lass_val_of_spec) + +lemma bconf_Cond[iff]: + "P,sh \\<^sub>b (if (b) e\<^sub>1 else e\<^sub>2,b') \ \ P,sh \\<^sub>b (b,b') \" +apply(unfold bconf_def, cases "bool_of b") apply auto[1] +apply(rename_tac a) apply(case_tac a) + apply(simp, drule bool_of_specT) apply auto[1] +apply(simp, drule bool_of_specF) apply auto[1] +done + +lemma bconf_While[iff]: + "P,sh \\<^sub>b (while (b) e,b') \ \ \b'" + by(unfold bconf_def, cases b, auto) + +lemma bconf_Throw[iff]: + "P,sh \\<^sub>b (throw e,b) \ \ P,sh \\<^sub>b (e,b) \" +apply(unfold bconf_def, cases b, auto) +apply(drule val_of_spec, simp) +done + +lemma bconf_Try[iff]: + "P,sh \\<^sub>b (try e\<^sub>1 catch(C V) e\<^sub>2,b) \ \ P,sh \\<^sub>b (e\<^sub>1,b) \" +apply(unfold bconf_def, cases b, auto) +apply(drule val_of_spec, simp) +done + +lemma bconf_INIT[iff]: + "P,sh \\<^sub>b (INIT C (Cs,b') \ e,b) \ \ \b" + by(unfold bconf_def, cases b, auto) + +lemma bconf_RI[iff]: + "P,sh \\<^sub>b (RI(C,e);Cs \ e',b) \ \ P,sh \\<^sub>b (e,b) \" +apply(unfold bconf_def, cases b, auto) +apply(drule val_of_spec, simp) +done + +lemma bconfs_map_throw[iff]: + "P,sh \\<^sub>b (map Val vs @ throw e # es',b) \ \ P,sh \\<^sub>b (e,b) \" + by(induct vs, auto) + +end diff --git a/thys/JinjaDCI/J/Equivalence.thy b/thys/JinjaDCI/J/Equivalence.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/J/Equivalence.thy @@ -0,0 +1,4292 @@ +(* Title: JinjaDCI/J/Equivalence.thy + Author: Tobias Nipkow, Susannah Mansky + Copyright 2003 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory J/Equivalence.thy by Tobias Nipkow +*) + +section \ Equivalence of Big Step and Small Step Semantics \ + +theory Equivalence imports TypeSafe WWellForm begin + +subsection\Small steps simulate big step\ + +subsubsection "Init" + +text "The reduction of initialization expressions doesn't touch or use + their on-hold expressions (the subexpression to the right of @{text \}) + until the initialization operation completes. This function is used to prove + this and related properties. It is then used for general reduction of + initialization expressions separately from their on-hold expressions by + using the on-hold expression @{term unit}, then putting the real on-hold + expression back in at the end." + +fun init_switch :: "'a exp \ 'a exp \ 'a exp" where +"init_switch (INIT C (Cs,b) \ e\<^sub>i) e = (INIT C (Cs,b) \ e)" | +"init_switch (RI(C,e');Cs \ e\<^sub>i) e = (RI(C,e');Cs \ e)" | +"init_switch e' e = e'" + +fun INIT_class :: "'a exp \ cname option" where +"INIT_class (INIT C (Cs,b) \ e) = (if C = last (C#Cs) then Some C else None)" | +"INIT_class (RI(C,e\<^sub>0);Cs \ e) = Some (last (C#Cs))" | +"INIT_class _ = None" + +lemma init_red_init: +"\ init_exp_of e\<^sub>0 = \e\; P \ \e\<^sub>0,s\<^sub>0,b\<^sub>0\ \ \e\<^sub>1,s\<^sub>1,b\<^sub>1\ \ + \ (init_exp_of e\<^sub>1 = \e\ \ (INIT_class e\<^sub>0 = \C\ \ INIT_class e\<^sub>1 = \C\)) + \ (e\<^sub>1 = e \ b\<^sub>1 = icheck P (the(INIT_class e\<^sub>0)) e) \ (\a. e\<^sub>1 = throw a)" + by(erule red.cases, auto) + +lemma init_exp_switch[simp]: +"init_exp_of e\<^sub>0 = \e\ \ init_exp_of (init_switch e\<^sub>0 e') = \e'\" + by(cases e\<^sub>0, simp_all) + +lemma init_red_sync: +"\ P \ \e\<^sub>0,s\<^sub>0,b\<^sub>0\ \ \e\<^sub>1,s\<^sub>1,b\<^sub>1\; init_exp_of e\<^sub>0 = \e\; e\<^sub>1 \ e \ + \ (\e'. P \ \init_switch e\<^sub>0 e',s\<^sub>0,b\<^sub>0\ \ \init_switch e\<^sub>1 e',s\<^sub>1,b\<^sub>1\)" +proof(induct rule: red.cases) qed(simp_all add: red_reds.intros) + +lemma init_red_sync_end: +"\ P \ \e\<^sub>0,s\<^sub>0,b\<^sub>0\ \ \e\<^sub>1,s\<^sub>1,b\<^sub>1\; init_exp_of e\<^sub>0 = \e\; e\<^sub>1 = e; throw_of e = None \ + \ (\e'. \sub_RI e' \ P \ \init_switch e\<^sub>0 e',s\<^sub>0,b\<^sub>0\ \ \e',s\<^sub>1,icheck P (the(INIT_class e\<^sub>0)) e'\)" +proof(induct rule: red.cases) qed(simp_all add: red_reds.intros) + +lemma init_reds_sync_unit': + "\ P \ \e\<^sub>0,s\<^sub>0,b\<^sub>0\ \* \Val v',s\<^sub>1,b\<^sub>1\; init_exp_of e\<^sub>0 = \unit\; INIT_class e\<^sub>0 = \C\ \ + \ (\e'. \sub_RI e' \ P \ \init_switch e\<^sub>0 e',s\<^sub>0,b\<^sub>0\ \* \e',s\<^sub>1,icheck P (the(INIT_class e\<^sub>0)) e'\)" +proof(induct rule:converse_rtrancl_induct3) +case refl then show ?case by simp +next + case (step e0 s0 b0 e1 s1 b1) + have "(init_exp_of e1 = \unit\ \ (INIT_class e0 = \C\ \ INIT_class e1 = \C\)) + \ (e1 = unit \ b1 = icheck P (the(INIT_class e0)) unit) \ (\a. e1 = throw a)" + using init_red_init[OF step.prems(1) step.hyps(1)] by simp + then show ?case + proof(rule disjE) + assume assm: "init_exp_of e1 = \unit\ \ (INIT_class e0 = \C\ \ INIT_class e1 = \C\)" + then have red: "P \ \init_switch e0 e',s0,b0\ \ \init_switch e1 e',s1,b1\" + using init_red_sync[OF step.hyps(1) step.prems(1)] by simp + have reds: "P \ \init_switch e1 e',s1,b1\ \* \e',s\<^sub>1,icheck P (the (INIT_class e0)) e'\" + using step.hyps(3)[OF _ _ step.prems(3)] assm step.prems(2) by simp + show ?thesis by(rule converse_rtrancl_into_rtrancl[OF red reds]) + next + assume "(e1 = unit \ b1 = icheck P (the(INIT_class e0)) unit) \ (\a. e1 = throw a)" + then show ?thesis + proof(rule disjE) + assume assm: "e1 = unit \ b1 = icheck P (the(INIT_class e0)) unit" then have e1: "e1 = unit" by simp + have sb: "s1 = s\<^sub>1" "b1 = b\<^sub>1" using reds_final_same[OF step.hyps(2)] assm + by(simp_all add: final_def) + then have step': "P \ \init_switch e0 e',s0,b0\ \ \e',s\<^sub>1,icheck P (the (INIT_class e0)) e'\" + using init_red_sync_end[OF step.hyps(1) step.prems(1) e1 _ step.prems(3)] by auto + then have "P \ \init_switch e0 e',s0,b0\ \* \e',s\<^sub>1,icheck P (the (INIT_class e0)) e'\" + using r_into_rtrancl by auto + then show ?thesis using step assm sb by simp + next + assume "\a. e1 = throw a" then obtain a where "e1 = throw a" by clarsimp + then have tof: "throw_of e1 = \a\" by simp + then show ?thesis using reds_throw[OF step.hyps(2) tof] by simp + qed + qed +qed + +lemma init_reds_sync_unit_throw': + "\ P \ \e\<^sub>0,s\<^sub>0,b\<^sub>0\ \* \throw a,s\<^sub>1,b\<^sub>1\; init_exp_of e\<^sub>0 = \unit\ \ + \ (\e'. P \ \init_switch e\<^sub>0 e',s\<^sub>0,b\<^sub>0\ \* \throw a,s\<^sub>1,b\<^sub>1\)" +proof(induct rule:converse_rtrancl_induct3) +case refl then show ?case by simp +next + case (step e0 s0 b0 e1 s1 b1) + have "init_exp_of e1 = \unit\ \ (\C. INIT_class e0 = \C\ \ INIT_class e1 = \C\) \ + e1 = unit \ b1 = icheck P (the (INIT_class e0)) unit \ (\a. e1 = throw a)" + using init_red_init[OF step.prems(1) step.hyps(1)] by auto + then show ?case + proof(rule disjE) + assume assm: "init_exp_of e1 = \unit\ \ (\C. INIT_class e0 = \C\ \ INIT_class e1 = \C\)" + then have "P \ \init_switch e0 e',s0,b0\ \ \init_switch e1 e',s1,b1\" + using step init_red_sync[OF step.hyps(1) step.prems] by simp + then show ?thesis using step assm by (meson converse_rtrancl_into_rtrancl) + next + assume "e1 = unit \ b1 = icheck P (the (INIT_class e0)) unit \ (\a. e1 = throw a)" + then show ?thesis + proof(rule disjE) + assume "e1 = unit \ b1 = icheck P (the (INIT_class e0)) unit" + then show ?thesis using step using final_def reds_final_same by blast + next + assume assm: "\a. e1 = throw a" + then have "P \ \init_switch e0 e',s0,b0\ \ \e1,s1,b1\" + using init_red_sync[OF step.hyps(1) step.prems] by clarsimp + then show ?thesis using step by simp + qed + qed +qed + +lemma init_reds_sync_unit: +assumes "P \ \e\<^sub>0,s\<^sub>0,b\<^sub>0\ \* \Val v',s\<^sub>1,b\<^sub>1\" and "init_exp_of e\<^sub>0 = \unit\" and "INIT_class e\<^sub>0 = \C\" + and "\sub_RI e'" +shows "P \ \init_switch e\<^sub>0 e',s\<^sub>0,b\<^sub>0\ \* \e',s\<^sub>1,icheck P (the(INIT_class e\<^sub>0)) e'\" +using init_reds_sync_unit'[OF assms] by clarsimp + +lemma init_reds_sync_unit_throw: +assumes "P \ \e\<^sub>0,s\<^sub>0,b\<^sub>0\ \* \throw a,s\<^sub>1,b\<^sub>1\" and "init_exp_of e\<^sub>0 = \unit\" +shows "P \ \init_switch e\<^sub>0 e',s\<^sub>0,b\<^sub>0\ \* \throw a,s\<^sub>1,b\<^sub>1\" +using init_reds_sync_unit_throw'[OF assms] by clarsimp + +\ \ init reds lemmas \ + +lemma InitSeqReds: +assumes "P \ \INIT C ([C],b) \ unit,s\<^sub>0,b\<^sub>0\ \* \Val v',s\<^sub>1,b\<^sub>1\" + and "P \ \e,s\<^sub>1,icheck P C e\ \* \e\<^sub>2,s\<^sub>2,b\<^sub>2\" and "\sub_RI e" +shows "P \ \INIT C ([C],b) \ e,s\<^sub>0,b\<^sub>0\ \* \e\<^sub>2,s\<^sub>2,b\<^sub>2\" +using assms +proof - + have "P \ \init_switch (INIT C ([C],b) \ unit) e,s\<^sub>0,b\<^sub>0\ \* \e,s\<^sub>1,icheck P C e\" + using init_reds_sync_unit[OF assms(1) _ _ assms(3)] by simp + then show ?thesis using assms(2) by simp +qed + +lemma InitSeqThrowReds: +assumes "P \ \INIT C ([C],b) \ unit,s\<^sub>0,b\<^sub>0\ \* \throw a,s\<^sub>1,b\<^sub>1\" +shows "P \ \INIT C ([C],b) \ e,s\<^sub>0,b\<^sub>0\ \* \throw a,s\<^sub>1,b\<^sub>1\" +using assms +proof - + have "P \ \init_switch (INIT C ([C],b) \ unit) e,s\<^sub>0,b\<^sub>0\ \* \throw a,s\<^sub>1,b\<^sub>1\" + using init_reds_sync_unit_throw[OF assms(1)] by simp + then show ?thesis by simp +qed + +lemma InitNoneReds: + "\ sh C = None; + P \ \INIT C' (C # Cs,False) \ e,(h, l, sh(C \ (sblank P C, Prepared))),b\ \* \e',s',b'\ \ +\ P \ \INIT C' (C#Cs,False) \ e,(h,l,sh),b\ \* \e',s',b'\" +(*<*) +apply(rule converse_rtrancl_into_rtrancl) + apply(erule InitNoneRed) +apply assumption +done +(*>*) + +lemma InitDoneReds: + "\ sh C = Some(sfs,Done); P \ \INIT C' (Cs,True) \ e,(h,l,sh),b\ \* \e',s',b'\ \ +\ P \ \INIT C' (C#Cs,False) \ e,(h,l,sh),b\ \* \e',s',b'\" +(*<*) +apply(rule converse_rtrancl_into_rtrancl) + apply(erule RedInitDone) +apply assumption +done +(*>*) + +lemma InitProcessingReds: + "\ sh C = Some(sfs,Processing); P \ \INIT C' (Cs,True) \ e,(h,l,sh),b\ \* \e',s',b'\ \ +\ P \ \INIT C' (C#Cs,False) \ e,(h,l,sh),b\ \* \e',s',b'\" +(*<*) +apply(rule converse_rtrancl_into_rtrancl) + apply(erule RedInitProcessing) +apply assumption +done +(*>*) + +lemma InitErrorReds: + "\ sh C = Some(sfs,Error); P \ \RI (C,THROW NoClassDefFoundError);Cs \ e,(h,l,sh),b\ \* \e',s',b'\ \ +\ P \ \INIT C' (C#Cs,False) \ e,(h,l,sh),b\ \* \e',s',b'\" +(*<*) +apply(rule converse_rtrancl_into_rtrancl) + apply(erule RedInitError) +apply assumption +done +(*>*) + +lemma InitObjectReds: + "\ sh C = Some(sfs,Prepared); C = Object; sh' = sh(C \ (sfs,Processing)); + P \ \INIT C' (C#Cs,True) \ e,(h,l,sh'),b\ \* \e',s',b'\ \ +\ P \ \INIT C' (C#Cs,False) \ e,(h,l,sh),b\ \* \e',s',b'\" +(*<*) +apply(rule converse_rtrancl_into_rtrancl) + apply(erule (2) InitObjectRed) +apply assumption +done +(*>*) + +lemma InitNonObjectReds: + "\ sh C = Some(sfs,Prepared); C \ Object; class P C = Some (D,r); + sh' = sh(C \ (sfs,Processing)); + P \ \INIT C' (D#C#Cs,False) \ e,(h,l,sh'),b\ \* \e',s',b'\ \ +\ P \ \INIT C' (C#Cs,False) \ e,(h,l,sh),b\ \* \e',s',b'\" +(*<*) +apply(rule converse_rtrancl_into_rtrancl) + apply(erule (3) InitNonObjectSuperRed) +apply assumption +done +(*>*) + +lemma RedsInitRInit: + "P \ \RI (C,C\\<^sub>sclinit([]));Cs \ e,(h,l,sh),b\ \* \e',s',b'\ +\ P \ \INIT C' (C#Cs,True) \ e,(h,l,sh),b\ \* \e',s',b'\" +(*<*) +apply(rule converse_rtrancl_into_rtrancl) + apply(rule RedInitRInit) +apply assumption +done +(*>*) + +lemmas rtrancl_induct3 = + rtrancl_induct[of "(ax,ay,az)" "(bx,by,bz)", split_format (complete), consumes 1, case_names refl step] + +lemma RInitReds: + "P \ \e,s,b\ \* \e',s',b'\ +\ P \ \RI (C,e);Cs \ e\<^sub>0, s, b\ \* \RI (C,e');Cs \ e\<^sub>0, s', b'\" +(*<*) +apply(erule rtrancl_induct3) + apply blast +apply(erule rtrancl_into_rtrancl) +apply(erule RInitRed) +done +(*>*) + +lemma RedsRInit: + "\ P \ \e\<^sub>0,s\<^sub>0,b\<^sub>0\ \* \Val v,(h\<^sub>1,l\<^sub>1,sh\<^sub>1),b\<^sub>1\; + sh\<^sub>1 C = Some (sfs, i); sh\<^sub>2 = sh\<^sub>1(C \ (sfs,Done)); C' = last(C#Cs); + P \ \INIT C' (Cs,True) \ e,(h\<^sub>1,l\<^sub>1,sh\<^sub>2),b\<^sub>1\ \* \e',s',b'\ \ +\ P \ \RI (C, e\<^sub>0);Cs \ e,s\<^sub>0,b\<^sub>0\ \* \e',s',b'\" +(*<*) +apply(rule rtrancl_trans) + apply(erule RInitReds) +apply(rule converse_rtrancl_into_rtrancl) + apply(erule (2) RedRInit) +apply assumption +done +(*>*) + +lemma RInitInitThrowReds: + "\ P \ \e,s,b\ \* \Throw a, (h',l',sh'),b'\; + sh' C = Some(sfs, i); sh'' = sh'(C \ (sfs, Error)); + P \ \RI (D,Throw a);Cs \ e\<^sub>0, (h',l',sh''),b'\ \* \e\<^sub>1,s\<^sub>1,b\<^sub>1\ \ + \ P \ \RI (C,e);D#Cs \ e\<^sub>0,s,b\ \* \e\<^sub>1,s\<^sub>1,b\<^sub>1\" +(*<*) +apply(rule rtrancl_trans) + apply(erule RInitReds) +apply(rule converse_rtrancl_into_rtrancl) + apply(erule (1) RInitInitThrow) +apply assumption +done +(*>*) + +lemma RInitThrowReds: + "\ P \ \e,s,b\ \* \Throw a, (h',l',sh'),b'\; + sh' C = Some(sfs, i); sh'' = sh'(C \ (sfs, Error)) \ + \ P \ \RI (C,e);Nil \ e\<^sub>0,s,b\ \* \Throw a, (h',l',sh''),b'\" +(*<*) +apply(rule rtrancl_into_rtrancl) + apply(erule RInitReds) +apply(erule RInitThrow) +apply assumption +done +(*>*) + +subsubsection "New" + +lemma NewInitDoneReds: + "\ sh C = Some (sfs, Done); new_Addr h = Some a; + P \ C has_fields FDTs; h' = h(a\blank P C) \ + \ P \ \new C,(h,l,sh),False\ \* \addr a,(h',l,sh),False\" +(*<*) +apply(rule converse_rtrancl_into_rtrancl) + apply(erule NewInitDoneRed) +apply(rule r_into_rtrancl) +apply(erule (2) RedNew) +done +(*>*) + +lemma NewInitDoneReds2: + "\ sh C = Some (sfs, Done); new_Addr h = None; is_class P C \ + \ P \ \new C,(h,l,sh),False\ \* \THROW OutOfMemory, (h,l,sh), False\" +(*<*) +apply(rule_tac converse_rtrancl_into_rtrancl) + apply(erule NewInitDoneRed) +apply(rule r_into_rtrancl) +apply(erule (1) RedNewFail) +done +(*>*) + +lemma NewInitReds: + "\ \sfs. shp s C = Some (sfs, Done); + P \ \INIT C ([C],False) \ unit,s,False\ \* \Val v',(h',l',sh'),b'\; + new_Addr h' = Some a; P \ C has_fields FDTs; h'' = h'(a\blank P C); is_class P C \ + \ P \ \new C,s,False\ \* \addr a,(h'',l',sh'),False\" +(*<*) +apply(rule_tac b = "(INIT C ([C],False) \ new C,s,False)" in converse_rtrancl_into_rtrancl) + apply(cases s, simp) + apply (simp add: NewInitRed) +apply(erule InitSeqReds, simp_all) +apply(rule r_into_rtrancl, rule RedNew) + apply simp+ +done +(*>*) + +lemma NewInitOOMReds: + "\ \sfs. shp s C = Some (sfs, Done); + P \ \INIT C ([C],False) \ unit,s,False\ \* \Val v',(h',l',sh'),b'\; + new_Addr h' = None; is_class P C \ + \ P \ \new C,s,False\ \* \THROW OutOfMemory,(h',l',sh'),False\" +(*<*) +apply(rule_tac b = "(INIT C ([C],False) \ new C,s,False)" in converse_rtrancl_into_rtrancl) + apply(cases s, simp) + apply (simp add: NewInitRed) +apply(erule InitSeqReds, simp_all) +apply(rule r_into_rtrancl, rule RedNewFail) + apply simp+ +done +(*>*) + +lemma NewInitThrowReds: + "\ \sfs. shp s C = Some (sfs, Done); is_class P C; + P \ \INIT C ([C],False) \ unit,s,False\ \* \throw a,s',b'\ \ + \ P \ \new C,s,False\ \* \throw a,s',b'\" +(*<*) +apply(rule_tac b = "(INIT C ([C],False) \ new C,s,False)" in converse_rtrancl_into_rtrancl) + apply(cases s, simp) + apply (simp add: NewInitRed) +apply(erule InitSeqThrowReds) +done +(*>*) + +subsubsection "Cast" + +lemma CastReds: + "P \ \e,s,b\ \* \e',s',b'\ \ P \ \Cast C e,s,b\ \* \Cast C e',s',b'\" +(*<*) +apply(erule rtrancl_induct3) + apply blast +apply(erule rtrancl_into_rtrancl) +apply(erule CastRed) +done +(*>*) + +lemma CastRedsNull: + "P \ \e,s,b\ \* \null,s',b'\ \ P \ \Cast C e,s,b\ \* \null,s',b'\" +(*<*) +apply(rule rtrancl_into_rtrancl) + apply(erule CastReds) +apply(rule RedCastNull) +done +(*>*) + +lemma CastRedsAddr: + "\ P \ \e,s,b\ \* \addr a,s',b'\; hp s' a = Some(D,fs); P \ D \\<^sup>* C \ \ + P \ \Cast C e,s,b\ \* \addr a,s',b'\" +(*<*) +apply(rule rtrancl_into_rtrancl) + apply(erule CastReds) +apply(cases s',simp) +apply(erule (1) RedCast) +done +(*>*) + +lemma CastRedsFail: + "\ P \ \e,s,b\ \* \addr a,s',b'\; hp s' a = Some(D,fs); \ P \ D \\<^sup>* C \ \ + P \ \Cast C e,s,b\ \* \THROW ClassCast,s',b'\" +(*<*) +apply(rule rtrancl_into_rtrancl) + apply(erule CastReds) +apply(cases s',simp) +apply(erule (1) RedCastFail) +done +(*>*) + +lemma CastRedsThrow: + "\ P \ \e,s,b\ \* \throw a,s',b'\ \ \ P \ \Cast C e,s,b\ \* \throw a,s',b'\" +(*<*) +apply(rule rtrancl_into_rtrancl) + apply(erule CastReds) +apply(rule red_reds.CastThrow) +done +(*>*) + +subsubsection "LAss" + +lemma LAssReds: + "P \ \e,s,b\ \* \e',s',b'\ \ P \ \ V:=e,s,b\ \* \ V:=e',s',b'\" +(*<*) +apply(erule rtrancl_induct3) + apply blast +apply(erule rtrancl_into_rtrancl) +apply(erule LAssRed) +done +(*>*) + +lemma LAssRedsVal: + "\ P \ \e,s,b\ \* \Val v,(h',l',sh'),b'\ \ \ P \ \ V:=e,s,b\ \* \unit,(h',l'(V\v),sh'),b'\" +(*<*) +apply(rule rtrancl_into_rtrancl) + apply(erule LAssReds) +apply(rule RedLAss) +done +(*>*) + +lemma LAssRedsThrow: + "\ P \ \e,s,b\ \* \throw a,s',b'\ \ \ P \ \ V:=e,s,b\ \* \throw a,s',b'\" +(*<*) +apply(rule rtrancl_into_rtrancl) + apply(erule LAssReds) +apply(rule red_reds.LAssThrow) +done +(*>*) + +subsubsection "BinOp" + +lemma BinOp1Reds: + "P \ \e,s,b\ \* \e',s',b'\ \ P \ \ e \bop\ e\<^sub>2, s,b\ \* \e' \bop\ e\<^sub>2, s',b'\" +(*<*) +apply(erule rtrancl_induct3) + apply blast +apply(erule rtrancl_into_rtrancl) +apply(erule BinOpRed1) +done +(*>*) + +lemma BinOp2Reds: + "P \ \e,s,b\ \* \e',s',b'\ \ P \ \(Val v) \bop\ e, s,b\ \* \(Val v) \bop\ e', s',b'\" +(*<*) +apply(erule rtrancl_induct3) + apply blast +apply(erule rtrancl_into_rtrancl) +apply(erule BinOpRed2) +done +(*>*) + +lemma BinOpRedsVal: + "\ P \ \e\<^sub>1,s\<^sub>0,b\<^sub>0\ \* \Val v\<^sub>1,s\<^sub>1,b\<^sub>1\; P \ \e\<^sub>2,s\<^sub>1,b\<^sub>1\ \* \Val v\<^sub>2,s\<^sub>2,b\<^sub>2\; binop(bop,v\<^sub>1,v\<^sub>2) = Some v \ + \ P \ \e\<^sub>1 \bop\ e\<^sub>2, s\<^sub>0,b\<^sub>0\ \* \Val v,s\<^sub>2,b\<^sub>2\" +(*<*) +apply(rule rtrancl_trans) + apply(erule BinOp1Reds) +apply(rule rtrancl_into_rtrancl) + apply(erule BinOp2Reds) +apply(rule RedBinOp) +apply simp +done +(*>*) + +lemma BinOpRedsThrow1: + "P \ \e,s,b\ \* \throw e',s',b'\ \ P \ \e \bop\ e\<^sub>2, s,b\ \* \throw e', s',b'\" +(*<*) +apply(rule rtrancl_into_rtrancl) + apply(erule BinOp1Reds) +apply(rule red_reds.BinOpThrow1) +done +(*>*) + +lemma BinOpRedsThrow2: + "\ P \ \e\<^sub>1,s\<^sub>0,b\<^sub>0\ \* \Val v\<^sub>1,s\<^sub>1,b\<^sub>1\; P \ \e\<^sub>2,s\<^sub>1,b\<^sub>1\ \* \throw e,s\<^sub>2,b\<^sub>2\\ + \ P \ \e\<^sub>1 \bop\ e\<^sub>2, s\<^sub>0, b\<^sub>0\ \* \throw e,s\<^sub>2,b\<^sub>2\" +(*<*) +apply(rule rtrancl_trans) + apply(erule BinOp1Reds) +apply(rule rtrancl_into_rtrancl) + apply(erule BinOp2Reds) +apply(rule red_reds.BinOpThrow2) +done +(*>*) + +subsubsection "FAcc" + +lemma FAccReds: + "P \ \e,s,b\ \* \e',s',b'\ \ P \ \e\F{D}, s,b\ \* \e'\F{D}, s',b'\" +(*<*) +apply(erule rtrancl_induct3) + apply blast +apply(erule rtrancl_into_rtrancl) +apply(erule FAccRed) +done +(*>*) + +lemma FAccRedsVal: + "\ P \ \e,s,b\ \* \addr a,s',b'\; hp s' a = Some(C,fs); fs(F,D) = Some v; + P \ C has F,NonStatic:t in D \ + \ P \ \e\F{D},s,b\ \* \Val v,s',b'\" +(*<*) +apply(rule rtrancl_into_rtrancl) + apply(erule FAccReds) +apply(cases s',simp) +apply(erule (2) RedFAcc) +done +(*>*) + +lemma FAccRedsNull: + "P \ \e,s,b\ \* \null,s',b'\ \ P \ \e\F{D},s,b\ \* \THROW NullPointer,s',b'\" +(*<*) +apply(rule rtrancl_into_rtrancl) + apply(erule FAccReds) +apply(rule RedFAccNull) +done +(*>*) + +lemma FAccRedsNone: + "\ P \ \e,s,b\ \* \addr a,s',b'\; + hp s' a = Some(C,fs); + \(\b t. P \ C has F,b:t in D) \ + \ P \ \e\F{D},s,b\ \* \THROW NoSuchFieldError,s',b'\" +(*<*) +apply(rule rtrancl_into_rtrancl) + apply(erule FAccReds) +apply(cases s',simp) +apply(erule RedFAccNone, simp) +done +(*>*) + +lemma FAccRedsStatic: + "\ P \ \e,s,b\ \* \addr a,s',b'\; + hp s' a = Some(C,fs); + P \ C has F,Static:t in D \ + \ P \ \e\F{D},s,b\ \* \THROW IncompatibleClassChangeError,s',b'\" +(*<*) +apply(rule rtrancl_into_rtrancl) + apply(erule FAccReds) +apply(cases s',simp) +apply(erule (1) RedFAccStatic) +done +(*>*) + +lemma FAccRedsThrow: + "P \ \e,s,b\ \* \throw a,s',b'\ \ P \ \e\F{D},s,b\ \* \throw a,s',b'\" +(*<*) +apply(rule rtrancl_into_rtrancl) + apply(erule FAccReds) +apply(rule red_reds.FAccThrow) +done +(*>*) + +subsubsection "SFAcc" + +lemma SFAccReds: + "\ P \ C has F,Static:t in D; + shp s D = Some(sfs,Done); sfs F = Some v \ + \ P \ \C\\<^sub>sF{D},s,True\ \* \Val v,s,False\" +(*<*) +apply(rule r_into_rtrancl) +apply(cases s,simp) +apply(erule (2) RedSFAcc) +done +(*>*) + +lemma SFAccRedsNone: + "\(\b t. P \ C has F,b:t in D) + \ P \ \C\\<^sub>sF{D},s,b\ \* \THROW NoSuchFieldError,s,False\" +(*<*) +apply(rule r_into_rtrancl) +apply(cases s,simp) +apply(rule RedSFAccNone, simp) +done +(*>*) + +lemma SFAccRedsNonStatic: + "P \ C has F,NonStatic:t in D + \ P \ \C\\<^sub>sF{D},s,b\ \* \THROW IncompatibleClassChangeError,s,False\" +(*<*) +apply(rule r_into_rtrancl) +apply(cases s,simp) +apply(erule RedSFAccNonStatic) +done +(*>*) + +lemma SFAccInitDoneReds: + "\ P \ C has F,Static:t in D; + shp s D = Some (sfs,Done); + sfs F = Some v \ + \ P \ \C\\<^sub>sF{D}, s,b\ \* \Val v, s,False\" +(*<*) +apply(cases b) +\ \ case True \ + apply(rule r_into_rtrancl) + apply(cases s, simp) + apply(erule (2) RedSFAcc) +\ \ case False \ +apply(rule_tac b = "(C\\<^sub>sF{D},s,True)" in converse_rtrancl_into_rtrancl) + apply(cases s, simp) + apply(drule (2) SFAccInitDoneRed) +apply(erule SFAccReds, simp+) +done +(*>*) + +lemma SFAccInitReds: + "\ P \ C has F,Static:t in D; + \sfs. shp s D = Some (sfs,Done); + P \ \INIT D ([D],False) \ unit,s,False\ \* \Val v',s',b'\; + shp s' D = Some (sfs,i); sfs F = Some v \ + \ P \ \C\\<^sub>sF{D},s,False\ \* \Val v,s',False\" +(*<*) +apply(rule_tac b = "(INIT D ([D],False) \ C\\<^sub>sF{D},s,False)" in converse_rtrancl_into_rtrancl) + apply(cases s, simp) + apply(simp add: SFAccInitRed) +apply(rule InitSeqReds, simp_all) +apply(subgoal_tac "\T. P \ C has F,Static:T in D") + prefer 2 apply fast +apply(rule r_into_rtrancl) +apply(cases s', simp) +apply(erule (2) RedSFAcc) +done +(*>*) + +lemma SFAccInitThrowReds: + "\ P \ C has F,Static:t in D; + \sfs. shp s D = Some (sfs,Done); + P \ \INIT D ([D],False) \ unit,s,False\ \* \throw a,s',b'\ \ + \ P \ \C\\<^sub>sF{D},s,False\ \* \throw a,s',b'\" +(*<*) +apply(rule_tac b = "(INIT D ([D],False) \ C\\<^sub>sF{D},s,False)" in converse_rtrancl_into_rtrancl) + apply(cases s, simp) + apply (simp add: SFAccInitRed) +apply(erule InitSeqThrowReds) +done +(*>*) + +subsubsection "FAss" + +lemma FAssReds1: + "P \ \e,s,b\ \* \e',s',b'\ \ P \ \e\F{D}:=e\<^sub>2, s,b\ \* \e'\F{D}:=e\<^sub>2, s',b'\" +(*<*) +apply(erule rtrancl_induct3) + apply blast +apply(erule rtrancl_into_rtrancl) +apply(erule FAssRed1) +done +(*>*) + +lemma FAssReds2: + "P \ \e,s,b\ \* \e',s',b'\ \ P \ \Val v\F{D}:=e, s,b\ \* \Val v\F{D}:=e', s',b'\" +(*<*) +apply(erule rtrancl_induct3) + apply blast +apply(erule rtrancl_into_rtrancl) +apply(erule FAssRed2) +done +(*>*) + +lemma FAssRedsVal: + "\ P \ \e\<^sub>1,s\<^sub>0,b\<^sub>0\ \* \addr a,s\<^sub>1,b\<^sub>1\; P \ \e\<^sub>2,s\<^sub>1,b\<^sub>1\ \* \Val v,(h\<^sub>2,l\<^sub>2,sh\<^sub>2),b\<^sub>2\; + P \ C has F,NonStatic:t in D; Some(C,fs) = h\<^sub>2 a \ \ + P \ \e\<^sub>1\F{D}:=e\<^sub>2, s\<^sub>0,b\<^sub>0\ \* \unit, (h\<^sub>2(a\(C,fs((F,D)\v))),l\<^sub>2,sh\<^sub>2),b\<^sub>2\" +(*<*) +apply(rule rtrancl_trans) + apply(erule FAssReds1) +apply(rule rtrancl_into_rtrancl) + apply(erule FAssReds2) +apply(rule RedFAss) + apply simp+ +done +(*>*) + +lemma FAssRedsNull: + "\ P \ \e\<^sub>1,s\<^sub>0,b\<^sub>0\ \* \null,s\<^sub>1,b\<^sub>1\; P \ \e\<^sub>2,s\<^sub>1,b\<^sub>1\ \* \Val v,s\<^sub>2,b\<^sub>2\ \ \ + P \ \e\<^sub>1\F{D}:=e\<^sub>2, s\<^sub>0,b\<^sub>0\ \* \THROW NullPointer, s\<^sub>2,b\<^sub>2\" +(*<*) +apply(rule rtrancl_trans) + apply(erule FAssReds1) +apply(rule rtrancl_into_rtrancl) + apply(erule FAssReds2) +apply(rule RedFAssNull) +done +(*>*) + +lemma FAssRedsThrow1: + "P \ \e,s,b\ \* \throw e',s',b'\ \ P \ \e\F{D}:=e\<^sub>2, s,b\ \* \throw e', s',b'\" +(*<*) +apply(rule rtrancl_into_rtrancl) + apply(erule FAssReds1) +apply(rule red_reds.FAssThrow1) +done +(*>*) + +lemma FAssRedsThrow2: + "\ P \ \e\<^sub>1,s\<^sub>0,b\<^sub>0\ \* \Val v,s\<^sub>1,b\<^sub>1\; P \ \e\<^sub>2,s\<^sub>1,b\<^sub>1\ \* \throw e,s\<^sub>2,b\<^sub>2\ \ + \ P \ \e\<^sub>1\F{D}:=e\<^sub>2,s\<^sub>0,b\<^sub>0\ \* \throw e,s\<^sub>2,b\<^sub>2\" +(*<*) +apply(rule rtrancl_trans) + apply(erule FAssReds1) +apply(rule rtrancl_into_rtrancl) + apply(erule FAssReds2) +apply(rule red_reds.FAssThrow2) +done +(*>*) + +lemma FAssRedsNone: + "\ P \ \e\<^sub>1,s\<^sub>0,b\<^sub>0\ \* \addr a,s\<^sub>1,b\<^sub>1\; P \ \e\<^sub>2,s\<^sub>1,b\<^sub>1\ \* \Val v,(h\<^sub>2,l\<^sub>2,sh\<^sub>2),b\<^sub>2\; + h\<^sub>2 a = Some(C,fs); \(\b t. P \ C has F,b:t in D) \ \ + P \ \e\<^sub>1\F{D}:=e\<^sub>2, s\<^sub>0,b\<^sub>0\ \* \THROW NoSuchFieldError, (h\<^sub>2,l\<^sub>2,sh\<^sub>2),b\<^sub>2\" +(*<*) +apply(rule rtrancl_trans) + apply(erule FAssReds1) +apply(rule rtrancl_into_rtrancl) + apply(erule FAssReds2) +apply(rule RedFAssNone) + apply simp+ +done +(*>*) + +lemma FAssRedsStatic: + "\ P \ \e\<^sub>1,s\<^sub>0,b\<^sub>0\ \* \addr a,s\<^sub>1,b\<^sub>1\; P \ \e\<^sub>2,s\<^sub>1,b\<^sub>1\ \* \Val v,(h\<^sub>2,l\<^sub>2,sh\<^sub>2),b\<^sub>2\; + h\<^sub>2 a = Some(C,fs); P \ C has F,Static:t in D \ \ + P \ \e\<^sub>1\F{D}:=e\<^sub>2, s\<^sub>0,b\<^sub>0\ \* \THROW IncompatibleClassChangeError, (h\<^sub>2,l\<^sub>2,sh\<^sub>2),b\<^sub>2\" +(*<*) +apply(rule rtrancl_trans) + apply(erule FAssReds1) +apply(rule rtrancl_into_rtrancl) + apply(erule FAssReds2) +apply(rule RedFAssStatic) + apply simp+ +done +(*>*) + +subsubsection "SFAss" + +lemma SFAssReds: + "P \ \e,s,b\ \* \e',s',b'\ \ P \ \C\\<^sub>sF{D}:=e,s,b\ \* \C\\<^sub>sF{D}:=e',s',b'\" +(*<*) +apply(erule rtrancl_induct3) + apply blast +apply(erule rtrancl_into_rtrancl) +apply(erule SFAssRed) +done +(*>*) + +lemma SFAssRedsVal: + "\ P \ \e\<^sub>2,s\<^sub>0,b\<^sub>0\ \* \Val v,(h\<^sub>2,l\<^sub>2,sh\<^sub>2),b\<^sub>2\; + P \ C has F,Static:t in D; sh\<^sub>2 D = \(sfs,Done)\ \ \ + P \ \C\\<^sub>sF{D}:=e\<^sub>2, s\<^sub>0,b\<^sub>0\ \* \unit, (h\<^sub>2,l\<^sub>2,sh\<^sub>2(D\(sfs(F\v), Done))),False\" +(*<*) +apply(rule rtrancl_trans) + apply(erule SFAssReds) +apply(cases b\<^sub>2) +\ \ case True \ + apply(rule r_into_rtrancl) + apply(drule_tac l = l\<^sub>2 in RedSFAss, simp_all) +\ \ case False \ +apply(rule converse_rtrancl_into_rtrancl) + apply(drule_tac sh = sh\<^sub>2 in SFAssInitDoneRed, simp_all) +apply(rule r_into_rtrancl) +apply(drule_tac l = l\<^sub>2 in RedSFAss, simp_all) +done +(*>*) + +lemma SFAssRedsThrow: + "\ P \ \e\<^sub>2,s\<^sub>0,b\<^sub>0\ \* \throw e,s\<^sub>2,b\<^sub>2\ \ + \ P \ \C\\<^sub>sF{D}:=e\<^sub>2,s\<^sub>0,b\<^sub>0\ \* \throw e,s\<^sub>2,b\<^sub>2\" +(*<*) +apply(rule rtrancl_into_rtrancl) + apply(erule SFAssReds) +apply(rule red_reds.SFAssThrow) +done +(*>*) + +lemma SFAssRedsNone: + "\ P \ \e\<^sub>2,s\<^sub>0,b\<^sub>0\ \* \Val v,(h\<^sub>2,l\<^sub>2,sh\<^sub>2),b\<^sub>2\; + \(\b t. P \ C has F,b:t in D) \ \ + P \ \C\\<^sub>sF{D}:=e\<^sub>2,s\<^sub>0,b\<^sub>0\ \* \THROW NoSuchFieldError, (h\<^sub>2,l\<^sub>2,sh\<^sub>2),False\" +(*<*) +apply(rule rtrancl_into_rtrancl) + apply(erule SFAssReds) +apply(rule RedSFAssNone) +apply simp +done +(*>*) + +lemma SFAssRedsNonStatic: + "\ P \ \e\<^sub>2,s\<^sub>0,b\<^sub>0\ \* \Val v,(h\<^sub>2,l\<^sub>2,sh\<^sub>2),b\<^sub>2\; + P \ C has F,NonStatic:t in D \ \ + P \ \C\\<^sub>sF{D}:=e\<^sub>2,s\<^sub>0,b\<^sub>0\ \* \THROW IncompatibleClassChangeError,(h\<^sub>2,l\<^sub>2,sh\<^sub>2),False\" +(*<*) +apply(rule rtrancl_into_rtrancl) + apply(erule SFAssReds) +apply(rule RedSFAssNonStatic) +apply simp +done +(*>*) + +lemma SFAssInitReds: + "\ P \ \e\<^sub>2,s\<^sub>0,b\<^sub>0\ \* \Val v,(h\<^sub>2,l\<^sub>2,sh\<^sub>2),False\; + P \ C has F,Static:t in D; + \sfs. sh\<^sub>2 D = Some (sfs, Done); + P \ \INIT D ([D],False) \ unit,(h\<^sub>2,l\<^sub>2,sh\<^sub>2),False\ \* \Val v',(h',l',sh'),b'\; + sh' D = Some(sfs,i); + sfs' = sfs(F\v); sh'' = sh'(D\(sfs',i)) \ + \ P \ \C\\<^sub>sF{D}:=e\<^sub>2,s\<^sub>0,b\<^sub>0\ \* \unit,(h',l',sh''),False\" +(*<*) +apply(rule rtrancl_trans) + apply(erule SFAssReds) +apply(rule_tac converse_rtrancl_into_rtrancl) + apply(erule (1) SFAssInitRed) +apply(erule InitSeqReds, simp_all) +apply(subgoal_tac "\T. P \ C has F,Static:T in D") + prefer 2 apply fast +apply(simp,rule r_into_rtrancl) +apply(erule (2) RedSFAss) +apply simp +done +(*>*) + +lemma SFAssInitThrowReds: + "\ P \ \e\<^sub>2,s\<^sub>0,b\<^sub>0\ \* \Val v,(h\<^sub>2,l\<^sub>2,sh\<^sub>2),False\; + P \ C has F,Static:t in D; + \sfs. sh\<^sub>2 D = Some (sfs, Done); + P \ \INIT D ([D],False) \ unit,(h\<^sub>2,l\<^sub>2,sh\<^sub>2),False\ \* \throw a,s',b'\ \ + \ P \ \C\\<^sub>sF{D}:=e\<^sub>2,s\<^sub>0,b\<^sub>0\ \* \throw a,s',b'\" +(*<*) +apply(rule rtrancl_trans) + apply(erule SFAssReds) +apply(rule converse_rtrancl_into_rtrancl) + apply(erule (1) SFAssInitRed) +apply(erule InitSeqThrowReds) +done +(*>*) + +subsubsection";;" + +lemma SeqReds: + "P \ \e,s,b\ \* \e',s',b'\ \ P \ \e;;e\<^sub>2, s,b\ \* \e';;e\<^sub>2, s',b'\" +(*<*) +apply(erule rtrancl_induct3) + apply blast +apply(erule rtrancl_into_rtrancl) +apply(erule SeqRed) +done +(*>*) + +lemma SeqRedsThrow: + "P \ \e,s,b\ \* \throw e',s',b'\ \ P \ \e;;e\<^sub>2, s,b\ \* \throw e', s',b'\" +(*<*) +apply(rule rtrancl_into_rtrancl) + apply(erule SeqReds) +apply(rule red_reds.SeqThrow) +done +(*>*) + +lemma SeqReds2: + "\ P \ \e\<^sub>1,s\<^sub>0,b\<^sub>0\ \* \Val v\<^sub>1,s\<^sub>1,b\<^sub>1\; P \ \e\<^sub>2,s\<^sub>1,b\<^sub>1\ \* \e\<^sub>2',s\<^sub>2,b\<^sub>2\ \ \ P \ \e\<^sub>1;;e\<^sub>2, s\<^sub>0,b\<^sub>0\ \* \e\<^sub>2',s\<^sub>2,b\<^sub>2\" +(*<*) +apply(rule rtrancl_trans) + apply(erule SeqReds) +apply(rule converse_rtrancl_into_rtrancl) + apply(rule RedSeq) +apply assumption +done +(*>*) + + +subsubsection"If" + +lemma CondReds: + "P \ \e,s,b\ \* \e',s',b'\ \ P \ \if (e) e\<^sub>1 else e\<^sub>2,s,b\ \* \if (e') e\<^sub>1 else e\<^sub>2,s',b'\" +(*<*) +apply(erule rtrancl_induct3) + apply blast +apply(erule rtrancl_into_rtrancl) +apply(erule CondRed) +done +(*>*) + +lemma CondRedsThrow: + "P \ \e,s,b\ \* \throw a,s',b'\ \ P \ \if (e) e\<^sub>1 else e\<^sub>2, s,b\ \* \throw a,s',b'\" +(*<*) +apply(rule rtrancl_into_rtrancl) + apply(erule CondReds) +apply(rule red_reds.CondThrow) +done +(*>*) + +lemma CondReds2T: + "\P \ \e,s\<^sub>0,b\<^sub>0\ \* \true,s\<^sub>1,b\<^sub>1\; P \ \e\<^sub>1, s\<^sub>1,b\<^sub>1\ \* \e',s\<^sub>2,b\<^sub>2\ \ \ P \ \if (e) e\<^sub>1 else e\<^sub>2, s\<^sub>0,b\<^sub>0\ \* \e',s\<^sub>2,b\<^sub>2\" +(*<*) +apply(rule rtrancl_trans) + apply(erule CondReds) +apply(rule converse_rtrancl_into_rtrancl) + apply(rule RedCondT) +apply assumption +done +(*>*) + +lemma CondReds2F: + "\P \ \e,s\<^sub>0,b\<^sub>0\ \* \false,s\<^sub>1,b\<^sub>1\; P \ \e\<^sub>2, s\<^sub>1,b\<^sub>1\ \* \e',s\<^sub>2,b\<^sub>2\ \ \ P \ \if (e) e\<^sub>1 else e\<^sub>2, s\<^sub>0,b\<^sub>0\ \* \e',s\<^sub>2,b\<^sub>2\" +(*<*) +apply(rule rtrancl_trans) + apply(erule CondReds) +apply(rule converse_rtrancl_into_rtrancl) + apply(rule RedCondF) +apply assumption +done +(*>*) + + +subsubsection "While" + +lemma WhileFReds: + "P \ \b,s,b\<^sub>0\ \* \false,s',b'\ \ P \ \while (b) c,s,b\<^sub>0\ \* \unit,s',b'\" +(*<*) +apply(rule converse_rtrancl_into_rtrancl) + apply(rule RedWhile) +apply(rule rtrancl_into_rtrancl) + apply(erule CondReds) +apply(rule RedCondF) +done +(*>*) + +lemma WhileRedsThrow: + "P \ \b,s,b\<^sub>0\ \* \throw e,s',b'\ \ P \ \while (b) c,s,b\<^sub>0\ \* \throw e,s',b'\" +(*<*) +apply(rule converse_rtrancl_into_rtrancl) + apply(rule RedWhile) +apply(rule rtrancl_into_rtrancl) + apply(erule CondReds) +apply(rule red_reds.CondThrow) +done +(*>*) + +lemma WhileTReds: + "\ P \ \b,s\<^sub>0,b\<^sub>0\ \* \true,s\<^sub>1,b\<^sub>1\; P \ \c,s\<^sub>1,b\<^sub>1\ \* \Val v\<^sub>1,s\<^sub>2,b\<^sub>2\; P \ \while (b) c,s\<^sub>2,b\<^sub>2\ \* \e,s\<^sub>3,b\<^sub>3\ \ + \ P \ \while (b) c,s\<^sub>0,b\<^sub>0\ \* \e,s\<^sub>3,b\<^sub>3\" +(*<*) +apply(rule converse_rtrancl_into_rtrancl) + apply(rule RedWhile) +apply(rule rtrancl_trans) + apply(erule CondReds) +apply(rule converse_rtrancl_into_rtrancl) + apply(rule RedCondT) +apply(rule rtrancl_trans) + apply(erule SeqReds) +apply(rule converse_rtrancl_into_rtrancl) + apply(rule RedSeq) +apply assumption +done +(*>*) + +lemma WhileTRedsThrow: + "\ P \ \b,s\<^sub>0,b\<^sub>0\ \* \true,s\<^sub>1,b\<^sub>1\; P \ \c,s\<^sub>1,b\<^sub>1\ \* \throw e,s\<^sub>2,b\<^sub>2\ \ + \ P \ \while (b) c,s\<^sub>0,b\<^sub>0\ \* \throw e,s\<^sub>2,b\<^sub>2\" +(*<*) +apply(rule converse_rtrancl_into_rtrancl) + apply(rule RedWhile) +apply(rule rtrancl_trans) + apply(erule CondReds) +apply(rule converse_rtrancl_into_rtrancl) + apply(rule RedCondT) +apply(rule rtrancl_into_rtrancl) + apply(erule SeqReds) +apply(rule red_reds.SeqThrow) +done +(*>*) + +subsubsection"Throw" + +lemma ThrowReds: + "P \ \e,s,b\ \* \e',s',b'\ \ P \ \throw e,s,b\ \* \throw e',s',b'\" +(*<*) +apply(erule rtrancl_induct3) + apply blast +apply(erule rtrancl_into_rtrancl) +apply(erule ThrowRed) +done +(*>*) + +lemma ThrowRedsNull: + "P \ \e,s,b\ \* \null,s',b'\ \ P \ \throw e,s,b\ \* \THROW NullPointer,s',b'\" +(*<*) +apply(rule rtrancl_into_rtrancl) + apply(erule ThrowReds) +apply(rule RedThrowNull) +done +(*>*) + +lemma ThrowRedsThrow: + "P \ \e,s,b\ \* \throw a,s',b'\ \ P \ \throw e,s,b\ \* \throw a,s',b'\" +(*<*) +apply(rule rtrancl_into_rtrancl) + apply(erule ThrowReds) +apply(rule red_reds.ThrowThrow) +done +(*>*) + +subsubsection "InitBlock" + +lemma InitBlockReds_aux: + "P \ \e,s,b\ \* \e',s',b'\ \ + \h l sh h' l' sh' v. s = (h,l(V\v),sh) \ s' = (h',l',sh') \ + P \ \{V:T := Val v; e},(h,l,sh),b\ \* \{V:T := Val(the(l' V)); e'},(h',l'(V:=(l V)),sh'),b'\" +(*<*) +apply(erule converse_rtrancl_induct3) + apply(fastforce simp: fun_upd_same simp del:fun_upd_apply) +apply clarify +apply(rename_tac e0 X Y x3 b0 e1 h1 l1 sh1 b1 h0 l0 sh0 h2 l2 sh2 v0) +apply(subgoal_tac "V \ dom l1") + prefer 2 + apply(drule red_lcl_incr) + apply simp +apply clarsimp +apply(rename_tac v1) +apply(rule converse_rtrancl_into_rtrancl) + apply(rule InitBlockRed) + apply assumption + apply simp +apply(erule_tac x = "l1(V := l0 V)" in allE) +apply(erule_tac x = v1 in allE) +apply(erule impE) + apply(rule ext) + apply(simp add:fun_upd_def) +apply(simp add:fun_upd_def) +done +(*>*) + +lemma InitBlockReds: + "P \ \e, (h,l(V\v),sh),b\ \* \e', (h',l',sh'),b'\ \ + P \ \{V:T := Val v; e}, (h,l,sh),b\ \* \{V:T := Val(the(l' V)); e'}, (h',l'(V:=(l V)),sh'),b'\" +(*<*)by(blast dest:InitBlockReds_aux)(*>*) + +lemma InitBlockRedsFinal: + "\ P \ \e,(h,l(V\v),sh),b\ \* \e',(h',l',sh'),b'\; final e' \ \ + P \ \{V:T := Val v; e},(h,l,sh),b\ \* \e',(h', l'(V := l V),sh'),b'\" +(*<*) +apply(rule rtrancl_into_rtrancl) + apply(erule InitBlockReds) +apply(fast elim!:finalE intro:RedInitBlock InitBlockThrow) +done +(*>*) + + +subsubsection "Block" + +lemmas converse_rtranclE3 = converse_rtranclE [of "(xa,xb,xc)" "(za,zb,zc)", split_rule] + +lemma BlockRedsFinal: +assumes reds: "P \ \e\<^sub>0,s\<^sub>0,b\<^sub>0\ \* \e\<^sub>2,(h\<^sub>2,l\<^sub>2,sh\<^sub>2),b\<^sub>2\" and fin: "final e\<^sub>2" +shows "\h\<^sub>0 l\<^sub>0 sh\<^sub>0. s\<^sub>0 = (h\<^sub>0,l\<^sub>0(V:=None),sh\<^sub>0) \ P \ \{V:T; e\<^sub>0},(h\<^sub>0,l\<^sub>0,sh\<^sub>0),b\<^sub>0\ \* \e\<^sub>2,(h\<^sub>2,l\<^sub>2(V:=l\<^sub>0 V),sh\<^sub>2),b\<^sub>2\" +(*<*) +using reds +proof (induct rule:converse_rtrancl_induct3) + case refl thus ?case + by(fastforce intro:finalE[OF fin] RedBlock BlockThrow + simp del:fun_upd_apply) +next + case (step e\<^sub>0 s\<^sub>0 b\<^sub>0 e\<^sub>1 s\<^sub>1 b\<^sub>1) + have red: "P \ \e\<^sub>0,s\<^sub>0,b\<^sub>0\ \ \e\<^sub>1,s\<^sub>1,b\<^sub>1\" + and reds: "P \ \e\<^sub>1,s\<^sub>1,b\<^sub>1\ \* \e\<^sub>2,(h\<^sub>2,l\<^sub>2,sh\<^sub>2),b\<^sub>2\" + and IH: "\h l sh. s\<^sub>1 = (h,l(V := None),sh) + \ P \ \{V:T; e\<^sub>1},(h,l,sh),b\<^sub>1\ \* \e\<^sub>2,(h\<^sub>2, l\<^sub>2(V := l V),sh\<^sub>2),b\<^sub>2\" + and s\<^sub>0: "s\<^sub>0 = (h\<^sub>0, l\<^sub>0(V := None),sh\<^sub>0)" by fact+ + obtain h\<^sub>1 l\<^sub>1 sh\<^sub>1 where s\<^sub>1: "s\<^sub>1 = (h\<^sub>1,l\<^sub>1,sh\<^sub>1)" + using prod_cases3 by blast + show ?case + proof cases + assume "assigned V e\<^sub>0" + then obtain v e where e\<^sub>0: "e\<^sub>0 = V := Val v;; e" + by (unfold assigned_def)blast + from red e\<^sub>0 s\<^sub>0 have e\<^sub>1: "e\<^sub>1 = unit;;e" and s\<^sub>1: "s\<^sub>1 = (h\<^sub>0, l\<^sub>0(V \ v),sh\<^sub>0)" and b\<^sub>1: "b\<^sub>1 = b\<^sub>0" + by auto + from e\<^sub>1 fin have "e\<^sub>1 \ e\<^sub>2" by (auto simp:final_def) + then obtain e' s' b' where red1: "P \ \e\<^sub>1,s\<^sub>1,b\<^sub>1\ \ \e',s',b'\" + and reds': "P \ \e',s',b'\ \* \e\<^sub>2,(h\<^sub>2,l\<^sub>2,sh\<^sub>2),b\<^sub>2\" + using converse_rtranclE3[OF reds] by blast + from red1 e\<^sub>1 b\<^sub>1 have es': "e' = e" "s' = s\<^sub>1" "b' = b\<^sub>0" by auto + show ?case using e\<^sub>0 s\<^sub>1 es' reds' + by(auto intro!: InitBlockRedsFinal[OF _ fin] simp del:fun_upd_apply) + next + assume unass: "\ assigned V e\<^sub>0" + show ?thesis + proof (cases "l\<^sub>1 V") + assume None: "l\<^sub>1 V = None" + hence "P \ \{V:T; e\<^sub>0},(h\<^sub>0,l\<^sub>0,sh\<^sub>0),b\<^sub>0\ \ \{V:T; e\<^sub>1},(h\<^sub>1, l\<^sub>1(V := l\<^sub>0 V),sh\<^sub>1),b\<^sub>1\" + using s\<^sub>0 s\<^sub>1 red by(simp add: BlockRedNone[OF _ _ unass]) + moreover + have "P \ \{V:T; e\<^sub>1},(h\<^sub>1, l\<^sub>1(V := l\<^sub>0 V),sh\<^sub>1),b\<^sub>1\ \* \e\<^sub>2,(h\<^sub>2, l\<^sub>2(V := l\<^sub>0 V),sh\<^sub>2),b\<^sub>2\" + using IH[of _ "l\<^sub>1(V := l\<^sub>0 V)"] s\<^sub>1 None by(simp add:fun_upd_idem) + ultimately show ?case by(rule converse_rtrancl_into_rtrancl) + next + fix v assume Some: "l\<^sub>1 V = Some v" + hence "P \ \{V:T;e\<^sub>0},(h\<^sub>0,l\<^sub>0,sh\<^sub>0),b\<^sub>0\ \ \{V:T := Val v; e\<^sub>1},(h\<^sub>1,l\<^sub>1(V := l\<^sub>0 V),sh\<^sub>1),b\<^sub>1\" + using s\<^sub>0 s\<^sub>1 red by(simp add: BlockRedSome[OF _ _ unass]) + moreover + have "P \ \{V:T := Val v; e\<^sub>1},(h\<^sub>1,l\<^sub>1(V:= l\<^sub>0 V),sh\<^sub>1),b\<^sub>1\ \* + \e\<^sub>2,(h\<^sub>2,l\<^sub>2(V:=l\<^sub>0 V),sh\<^sub>2),b\<^sub>2\" + using InitBlockRedsFinal[OF _ fin,of _ _ "l\<^sub>1(V:=l\<^sub>0 V)" V] + Some reds s\<^sub>1 by(simp add:fun_upd_idem) + ultimately show ?case by(rule converse_rtrancl_into_rtrancl) + qed + qed +qed +(*>*) + + +subsubsection "try-catch" + +lemma TryReds: + "P \ \e,s,b\ \* \e',s',b'\ \ P \ \try e catch(C V) e\<^sub>2,s,b\ \* \try e' catch(C V) e\<^sub>2,s',b'\" +(*<*) +apply(erule rtrancl_induct3) + apply blast +apply(erule rtrancl_into_rtrancl) +apply(erule TryRed) +done +(*>*) + +lemma TryRedsVal: + "P \ \e,s,b\ \* \Val v,s',b'\ \ P \ \try e catch(C V) e\<^sub>2,s,b\ \* \Val v,s',b'\" +(*<*) +apply(rule rtrancl_into_rtrancl) + apply(erule TryReds) +apply(rule RedTry) +done +(*>*) + +lemma TryCatchRedsFinal: + "\ P \ \e\<^sub>1,s\<^sub>0,b\<^sub>0\ \* \Throw a,(h\<^sub>1,l\<^sub>1,sh\<^sub>1),b\<^sub>1\; h\<^sub>1 a = Some(D,fs); P \ D \\<^sup>* C; + P \ \e\<^sub>2, (h\<^sub>1, l\<^sub>1(V \ Addr a),sh\<^sub>1),b\<^sub>1\ \* \e\<^sub>2', (h\<^sub>2,l\<^sub>2,sh\<^sub>2), b\<^sub>2\; final e\<^sub>2' \ + \ P \ \try e\<^sub>1 catch(C V) e\<^sub>2, s\<^sub>0, b\<^sub>0\ \* \e\<^sub>2', (h\<^sub>2, l\<^sub>2(V := l\<^sub>1 V),sh\<^sub>2),b\<^sub>2\" +(*<*) +apply(rule rtrancl_trans) + apply(erule TryReds) +apply(rule converse_rtrancl_into_rtrancl) + apply(rule RedTryCatch) + apply fastforce + apply assumption +apply(rule InitBlockRedsFinal) + apply assumption +apply(simp) +done +(*>*) + +lemma TryRedsFail: + "\ P \ \e\<^sub>1,s,b\ \* \Throw a,(h,l,sh),b'\; h a = Some(D,fs); \ P \ D \\<^sup>* C \ + \ P \ \try e\<^sub>1 catch(C V) e\<^sub>2,s,b\ \* \Throw a,(h,l,sh),b'\" +(*<*) +apply(rule rtrancl_into_rtrancl) + apply(erule TryReds) +apply(fastforce intro!: RedTryFail) +done +(*>*) + +subsubsection "List" + +lemma ListReds1: + "P \ \e,s,b\ \* \e',s',b'\ \ P \ \e#es,s,b\ [\]* \e' # es,s',b'\" +(*<*) +apply(erule rtrancl_induct3) + apply blast +apply(erule rtrancl_into_rtrancl) +apply(erule ListRed1) +done +(*>*) + +lemma ListReds2: + "P \ \es,s,b\ [\]* \es',s',b'\ \ P \ \Val v # es,s,b\ [\]* \Val v # es',s',b'\" +(*<*) +apply(erule rtrancl_induct3) + apply blast +apply(erule rtrancl_into_rtrancl) +apply(erule ListRed2) +done +(*>*) + +lemma ListRedsVal: + "\ P \ \e,s\<^sub>0,b\<^sub>0\ \* \Val v,s\<^sub>1,b\<^sub>1\; P \ \es,s\<^sub>1,b\<^sub>1\ [\]* \es',s\<^sub>2,b\<^sub>2\ \ + \ P \ \e#es,s\<^sub>0,b\<^sub>0\ [\]* \Val v # es',s\<^sub>2,b\<^sub>2\" +(*<*) +apply(rule rtrancl_trans) + apply(erule ListReds1) +apply(erule ListReds2) +done +(*>*) + +subsubsection"Call" + +text\ First a few lemmas on what happens to free variables during redction. \ + +lemma assumes wf: "wwf_J_prog P" +shows Red_fv: "P \ \e,(h,l,sh),b\ \ \e',(h',l',sh'),b'\ \ fv e' \ fv e" + and "P \ \es,(h,l,sh),b\ [\] \es',(h',l',sh'),b'\ \ fvs es' \ fvs es" +(*<*) +proof (induct rule:red_reds_inducts) + case (RedCall h a C fs M Ts T pns body D vs l sh b) + hence "fv body \ {this} \ set pns" + using assms by(fastforce dest!:sees_wf_mdecl simp:wf_mdecl_def) + with RedCall.hyps show ?case by fastforce +next + case (RedSCall C M Ts T pns body D vs) + hence "fv body \ set pns" + using assms by(fastforce dest!:sees_wf_mdecl simp:wf_mdecl_def) + with RedSCall.hyps show ?case by fastforce +qed auto +(*>*) + + +lemma Red_dom_lcl: + "P \ \e,(h,l,sh),b\ \ \e',(h',l',sh'),b'\ \ dom l' \ dom l \ fv e" and + "P \ \es,(h,l,sh),b\ [\] \es',(h',l',sh'),b'\ \ dom l' \ dom l \ fvs es" +(*<*) +proof (induct rule:red_reds_inducts) + case RedLAss thus ?case by(force split:if_splits) +next + case CallParams thus ?case by(force split:if_splits) +next + case BlockRedNone thus ?case by clarsimp (fastforce split:if_splits) +next + case BlockRedSome thus ?case by clarsimp (fastforce split:if_splits) +next + case InitBlockRed thus ?case by clarsimp (fastforce split:if_splits) +qed auto +(*>*) + +lemma Reds_dom_lcl: + "\ wwf_J_prog P; P \ \e,(h,l,sh),b\ \* \e',(h',l',sh'),b'\ \ \ dom l' \ dom l \ fv e" +(*<*) +apply(erule converse_rtrancl_induct_red) + apply blast +apply(blast dest: Red_fv Red_dom_lcl) +done +(*>*) + +text\ Now a few lemmas on the behaviour of blocks during reduction. \ + +lemma override_on_upd_lemma: + "(override_on f (g(a\b)) A)(a := g a) = override_on f g (insert a A)" +(*<*) +apply(rule ext) +apply(simp add:override_on_def) +done + +declare fun_upd_apply[simp del] map_upds_twist[simp del] +(*>*) + + +lemma blocksReds: + "\l. \ length Vs = length Ts; length vs = length Ts; distinct Vs; + P \ \e, (h,l(Vs [\] vs),sh),b\ \* \e', (h',l',sh'),b'\ \ + \ P \ \blocks(Vs,Ts,vs,e), (h,l,sh),b\ \* \blocks(Vs,Ts,map (the \ l') Vs,e'), (h',override_on l' l (set Vs),sh'),b'\" +(*<*) +proof(induct Vs Ts vs e rule:blocks_induct) + case (1 V Vs T Ts v vs e) show ?case + using InitBlockReds[OF "1.hyps"[of "l(V\v)"]] "1.prems" + by(auto simp:override_on_upd_lemma) +qed auto +(*>*) + + +lemma blocksFinal: + "\l. \ length Vs = length Ts; length vs = length Ts; final e \ \ + P \ \blocks(Vs,Ts,vs,e), (h,l,sh),b\ \* \e, (h,l,sh),b\" +(*<*) +proof(induct Vs Ts vs e rule:blocks_induct) + case 1 + show ?case using "1.prems" InitBlockReds[OF "1.hyps"] + by(fastforce elim!:finalE elim: rtrancl_into_rtrancl[OF _ RedInitBlock] + rtrancl_into_rtrancl[OF _ InitBlockThrow]) +qed auto +(*>*) + + +lemma blocksRedsFinal: +assumes wf: "length Vs = length Ts" "length vs = length Ts" "distinct Vs" + and reds: "P \ \e, (h,l(Vs [\] vs),sh),b\ \* \e', (h',l',sh'),b'\" + and fin: "final e'" and l'': "l'' = override_on l' l (set Vs)" +shows "P \ \blocks(Vs,Ts,vs,e), (h,l,sh),b\ \* \e', (h',l'',sh'),b'\" +(*<*) +proof - + let ?bv = "blocks(Vs,Ts,map (the o l') Vs,e')" + have "P \ \blocks(Vs,Ts,vs,e), (h,l,sh),b\ \* \?bv, (h',l'',sh'),b'\" + using l'' by simp (rule blocksReds[OF wf reds]) + also have "P \ \?bv, (h',l'',sh'),b'\ \* \e', (h',l'',sh'),b'\" + using wf by(fastforce intro:blocksFinal fin) + finally show ?thesis . +qed +(*>*) + +text\ An now the actual method call reduction lemmas. \ + +lemma CallRedsObj: + "P \ \e,s,b\ \* \e',s',b'\ \ P \ \e\M(es),s,b\ \* \e'\M(es),s',b'\" +(*<*) +apply(erule rtrancl_induct3) + apply blast +apply(erule rtrancl_into_rtrancl) +apply(erule CallObj) +done +(*>*) + + +lemma CallRedsParams: + "P \ \es,s,b\ [\]* \es',s',b'\ \ P \ \(Val v)\M(es),s,b\ \* \(Val v)\M(es'),s',b'\" +(*<*) +apply(erule rtrancl_induct3) + apply blast +apply(erule rtrancl_into_rtrancl) +apply(erule CallParams) +done +(*>*) + + +lemma CallRedsFinal: +assumes wwf: "wwf_J_prog P" +and "P \ \e,s\<^sub>0,b\<^sub>0\ \* \addr a,s\<^sub>1,b\<^sub>1\" + "P \ \es,s\<^sub>1,b\<^sub>1\ [\]* \map Val vs,(h\<^sub>2,l\<^sub>2,sh\<^sub>2),b\<^sub>2\" + "h\<^sub>2 a = Some(C,fs)" "P \ C sees M,NonStatic:Ts\T = (pns,body) in D" + "size vs = size pns" +and l\<^sub>2': "l\<^sub>2' = [this \ Addr a, pns[\]vs]" +and body: "P \ \body,(h\<^sub>2,l\<^sub>2',sh\<^sub>2),b\<^sub>2\ \* \ef,(h\<^sub>3,l\<^sub>3,sh\<^sub>3),b\<^sub>3\" +and "final ef" +shows "P \ \e\M(es), s\<^sub>0,b\<^sub>0\ \* \ef,(h\<^sub>3,l\<^sub>2,sh\<^sub>3),b\<^sub>3\" +(*<*) +proof - + have wf: "size Ts = size pns \ distinct pns \ this \ set pns" + and wt: "fv body \ {this} \ set pns" + using assms by(fastforce dest!:sees_wf_mdecl simp:wf_mdecl_def)+ + from body[THEN Red_lcl_add, of l\<^sub>2] + have body': "P \ \body,(h\<^sub>2,l\<^sub>2(this\ Addr a, pns[\]vs),sh\<^sub>2),b\<^sub>2\ \* \ef,(h\<^sub>3,l\<^sub>2++l\<^sub>3,sh\<^sub>3),b\<^sub>3\" + by (simp add:l\<^sub>2') + have "dom l\<^sub>3 \ {this} \ set pns" + using Reds_dom_lcl[OF wwf body] wt l\<^sub>2' set_take_subset by force + hence eql\<^sub>2: "override_on (l\<^sub>2++l\<^sub>3) l\<^sub>2 ({this} \ set pns) = l\<^sub>2" + by(fastforce simp add:map_add_def override_on_def fun_eq_iff) + have "P \ \e\M(es),s\<^sub>0,b\<^sub>0\ \* \(addr a)\M(es),s\<^sub>1,b\<^sub>1\" by(rule CallRedsObj)(rule assms(2)) + also have "P \ \(addr a)\M(es),s\<^sub>1,b\<^sub>1\ \* + \(addr a)\M(map Val vs),(h\<^sub>2,l\<^sub>2,sh\<^sub>2),b\<^sub>2\" + by(rule CallRedsParams)(rule assms(3)) + also have "P \ \(addr a)\M(map Val vs), (h\<^sub>2,l\<^sub>2,sh\<^sub>2),b\<^sub>2\ \ + \blocks(this#pns, Class D#Ts, Addr a#vs, body), (h\<^sub>2,l\<^sub>2,sh\<^sub>2),b\<^sub>2\" + by(rule RedCall)(auto simp: assms wf, rule assms(5)) + also (rtrancl_into_rtrancl) have "P \ \blocks(this#pns, Class D#Ts, Addr a#vs, body), (h\<^sub>2,l\<^sub>2,sh\<^sub>2),b\<^sub>2\ + \* \ef,(h\<^sub>3,override_on (l\<^sub>2++l\<^sub>3) l\<^sub>2 ({this} \ set pns),sh\<^sub>3),b\<^sub>3\" + by(rule blocksRedsFinal, insert assms wf body', simp_all) + finally show ?thesis using eql\<^sub>2 by simp +qed +(*>*) + + +lemma CallRedsThrowParams: + "\ P \ \e,s\<^sub>0,b\<^sub>0\ \* \Val v,s\<^sub>1,b\<^sub>1\; P \ \es,s\<^sub>1,b\<^sub>1\ [\]* \map Val vs\<^sub>1 @ throw a # es\<^sub>2,s\<^sub>2,b\<^sub>2\ \ + \ P \ \e\M(es),s\<^sub>0,b\<^sub>0\ \* \throw a,s\<^sub>2,b\<^sub>2\" +(*<*) +apply(rule rtrancl_trans) + apply(erule CallRedsObj) +apply(rule rtrancl_into_rtrancl) + apply(erule CallRedsParams) +apply(rule CallThrowParams) +apply simp +done +(*>*) + + +lemma CallRedsThrowObj: + "P \ \e,s\<^sub>0,b\<^sub>0\ \* \throw a,s\<^sub>1,b\<^sub>1\ \ P \ \e\M(es),s\<^sub>0,b\<^sub>0\ \* \throw a,s\<^sub>1,b\<^sub>1\" +(*<*) +apply(rule rtrancl_into_rtrancl) + apply(erule CallRedsObj) +apply(rule CallThrowObj) +done +(*>*) + + +lemma CallRedsNull: + "\ P \ \e,s\<^sub>0,b\<^sub>0\ \* \null,s\<^sub>1,b\<^sub>1\; P \ \es,s\<^sub>1,b\<^sub>1\ [\]* \map Val vs,s\<^sub>2,b\<^sub>2\ \ + \ P \ \e\M(es),s\<^sub>0,b\<^sub>0\ \* \THROW NullPointer,s\<^sub>2,b\<^sub>2\" +(*<*) +apply(rule rtrancl_trans) + apply(erule CallRedsObj) +apply(rule rtrancl_into_rtrancl) + apply(erule CallRedsParams) +apply(rule RedCallNull) +done +(*>*) + +lemma CallRedsNone: + "\ P \ \e,s,b\ \* \addr a,s\<^sub>1,b\<^sub>1\; P \ \es,s\<^sub>1,b\<^sub>1\ [\]* \map Val vs,s\<^sub>2,b\<^sub>2\; + hp s\<^sub>2 a = Some(C,fs); + \(\b Ts T m D. P \ C sees M,b:Ts\T = m in D) \ + \ P \ \e\M(es),s,b\ \* \THROW NoSuchMethodError,s\<^sub>2,b\<^sub>2\" +(*<*) +apply(rule rtrancl_trans) + apply(erule CallRedsObj) +apply(rule rtrancl_into_rtrancl) + apply(erule CallRedsParams) +apply(cases s\<^sub>2,simp) +apply(erule RedCallNone, simp) +done +(*>*) + +lemma CallRedsStatic: + "\ P \ \e,s,b\ \* \addr a,s\<^sub>1,b\<^sub>1\; P \ \es,s\<^sub>1,b\<^sub>1\ [\]* \map Val vs,s\<^sub>2,b\<^sub>2\; + hp s\<^sub>2 a = Some(C,fs); + P \ C sees M,Static:Ts\T = m in D \ + \ P \ \e\M(es),s,b\ \* \THROW IncompatibleClassChangeError,s\<^sub>2,b\<^sub>2\" +(*<*) +apply(rule rtrancl_trans) + apply(erule CallRedsObj) +apply(rule rtrancl_into_rtrancl) + apply(erule CallRedsParams) +apply(cases s\<^sub>2,simp) +apply(erule RedCallStatic, simp) +done +(*>*) + +subsection\SCall\ + +lemma SCallRedsParams: + "P \ \es,s,b\ [\]* \es',s',b'\ \ P \ \C\\<^sub>sM(es),s,b\ \* \C\\<^sub>sM(es'),s',b'\" +(*<*) +apply(erule rtrancl_induct3) + apply blast +apply(erule rtrancl_into_rtrancl) +apply(erule SCallParams) +done +(*>*) + +lemma SCallRedsFinal: +assumes wwf: "wwf_J_prog P" +and "P \ \es,s\<^sub>0,b\<^sub>0\ [\]* \map Val vs,(h\<^sub>2,l\<^sub>2,sh\<^sub>2),b\<^sub>2\" + "P \ C sees M,Static:Ts\T = (pns,body) in D" + "sh\<^sub>2 D = Some(sfs,Done) \ (M = clinit \ sh\<^sub>2 D = \(sfs, Processing)\)" + "size vs = size pns" +and l\<^sub>2': "l\<^sub>2' = [pns[\]vs]" +and body: "P \ \body,(h\<^sub>2,l\<^sub>2',sh\<^sub>2),False\ \* \ef,(h\<^sub>3,l\<^sub>3,sh\<^sub>3),b\<^sub>3\" +and "final ef" +shows "P \ \C\\<^sub>sM(es), s\<^sub>0,b\<^sub>0\ \* \ef,(h\<^sub>3,l\<^sub>2,sh\<^sub>3),b\<^sub>3\" +(*<*) +proof - + have wf: "size Ts = size pns \ distinct pns" + and wt: "fv body \ set pns" + using assms by(fastforce dest!:sees_wf_mdecl simp:wf_mdecl_def)+ + from body[THEN Red_lcl_add, of l\<^sub>2] + have body': "P \ \body,(h\<^sub>2,l\<^sub>2(pns[\]vs),sh\<^sub>2),False\ \* \ef,(h\<^sub>3,l\<^sub>2++l\<^sub>3,sh\<^sub>3),b\<^sub>3\" + by (simp add:l\<^sub>2') + have "dom l\<^sub>3 \ set pns" + using Reds_dom_lcl[OF wwf body] wt l\<^sub>2' set_take_subset by force + hence eql\<^sub>2: "override_on (l\<^sub>2++l\<^sub>3) l\<^sub>2 (set pns) = l\<^sub>2" + by(fastforce simp add:map_add_def override_on_def fun_eq_iff) + have b2T: "P \ \C\\<^sub>sM(map Val vs), (h\<^sub>2,l\<^sub>2,sh\<^sub>2),b\<^sub>2\ \* \C\\<^sub>sM(map Val vs), (h\<^sub>2,l\<^sub>2,sh\<^sub>2),True\" + proof(cases b\<^sub>2) + case True then show ?thesis by simp + next + case False then show ?thesis using assms(3,4) by(auto elim: SCallInitDoneRed) + qed + have "P \ \C\\<^sub>sM(es),s\<^sub>0,b\<^sub>0\ \* \C\\<^sub>sM(map Val vs),(h\<^sub>2,l\<^sub>2,sh\<^sub>2),b\<^sub>2\" + by(rule SCallRedsParams)(rule assms(2)) + also have "P \ \C\\<^sub>sM(map Val vs), (h\<^sub>2,l\<^sub>2,sh\<^sub>2),b\<^sub>2\ \* \blocks(pns, Ts, vs, body), (h\<^sub>2,l\<^sub>2,sh\<^sub>2),False\" + by(auto intro!: rtrancl_into_rtrancl[OF b2T] RedSCall assms(3) simp: assms wf) + also (rtrancl_trans) have "P \ \blocks(pns, Ts, vs, body), (h\<^sub>2,l\<^sub>2,sh\<^sub>2),False\ + \* \ef,(h\<^sub>3,override_on (l\<^sub>2++l\<^sub>3) l\<^sub>2 (set pns),sh\<^sub>3),b\<^sub>3\" + by(rule blocksRedsFinal, insert assms wf body', simp_all) + finally show ?thesis using eql\<^sub>2 by simp +qed +(*>*) + +lemma SCallRedsThrowParams: + "\ P \ \es,s\<^sub>0,b\<^sub>0\ [\]* \map Val vs\<^sub>1 @ throw a # es\<^sub>2,s\<^sub>2,b\<^sub>2\ \ + \ P \ \C\\<^sub>sM(es),s\<^sub>0,b\<^sub>0\ \* \throw a,s\<^sub>2,b\<^sub>2\" +(*<*) +apply(rule rtrancl_into_rtrancl) + apply(erule SCallRedsParams) +apply(rule SCallThrowParams) +apply simp +done +(*>*) + +lemma SCallRedsNone: + "\ P \ \es,s,b\ [\]* \map Val vs,s\<^sub>2,False\; + \(\b Ts T m D. P \ C sees M,b:Ts\T = m in D) \ + \ P \ \C\\<^sub>sM(es),s,b\ \* \THROW NoSuchMethodError,s\<^sub>2,False\" +(*<*) +apply(rule rtrancl_into_rtrancl) + apply(erule SCallRedsParams) +apply(cases s\<^sub>2,simp) +apply(rule RedSCallNone, simp) +done +(*>*) + +lemma SCallRedsNonStatic: + "\ P \ \es,s,b\ [\]* \map Val vs,s\<^sub>2,False\; + P \ C sees M,NonStatic:Ts\T = m in D \ + \ P \ \C\\<^sub>sM(es),s,b\ \* \THROW IncompatibleClassChangeError,s\<^sub>2,False\" +(*<*) +apply(rule rtrancl_into_rtrancl) + apply(erule SCallRedsParams) +apply(cases s\<^sub>2,simp) +apply(rule RedSCallNonStatic, simp) +done +(*>*) + +lemma SCallInitThrowReds: +assumes wwf: "wwf_J_prog P" +and "P \ \es,s\<^sub>0,b\<^sub>0\ [\]* \map Val vs,(h\<^sub>1,l\<^sub>1,sh\<^sub>1),False\" + "P \ C sees M,Static:Ts\T = (pns,body) in D" + "\sfs. sh\<^sub>1 D = Some(sfs,Done)" + "M \ clinit" +and "P \ \INIT D ([D],False) \ unit,(h\<^sub>1,l\<^sub>1,sh\<^sub>1),False\ \* \throw a,(h\<^sub>2,l\<^sub>2,sh\<^sub>2),b\<^sub>2\" +shows "P \ \C\\<^sub>sM(es), s\<^sub>0,b\<^sub>0\ \* \throw a,(h\<^sub>2,l\<^sub>2,sh\<^sub>2),b\<^sub>2\" +(*<*) +proof - + have "P \ \C\\<^sub>sM(es),s\<^sub>0,b\<^sub>0\ \* \C\\<^sub>sM(map Val vs),(h\<^sub>1,l\<^sub>1,sh\<^sub>1),False\" + by(rule SCallRedsParams)(rule assms(2)) + also have "P \ \C\\<^sub>sM(map Val vs),(h\<^sub>1,l\<^sub>1,sh\<^sub>1),False\ \ \INIT D ([D],False) \ C\\<^sub>sM(map Val vs),(h\<^sub>1,l\<^sub>1,sh\<^sub>1),False\" + using SCallInitRed[OF assms(3)] assms(4-5) by auto + also (rtrancl_into_rtrancl) have "P \ \INIT D ([D],False) \ C\\<^sub>sM(map Val vs),(h\<^sub>1,l\<^sub>1,sh\<^sub>1),False\ + \* \throw a,(h\<^sub>2,l\<^sub>2,sh\<^sub>2),b\<^sub>2\" + by(rule InitSeqThrowReds[OF assms(6)]) + finally show ?thesis by simp +qed +(*>*) + +lemma SCallInitReds: +assumes wwf: "wwf_J_prog P" +and "P \ \es,s\<^sub>0,b\<^sub>0\ [\]* \map Val vs,(h\<^sub>1,l\<^sub>1,sh\<^sub>1),False\" + "P \ C sees M,Static:Ts\T = (pns,body) in D" + "\sfs. sh\<^sub>1 D = Some(sfs,Done)" + "M \ clinit" +and "P \ \INIT D ([D],False) \ unit,(h\<^sub>1,l\<^sub>1,sh\<^sub>1),False\ \* \Val v',(h\<^sub>2,l\<^sub>2,sh\<^sub>2),b\<^sub>2\" +and "size vs = size pns" +and l\<^sub>2': "l\<^sub>2' = [pns[\]vs]" +and body: "P \ \body,(h\<^sub>2,l\<^sub>2',sh\<^sub>2),False\ \* \ef,(h\<^sub>3,l\<^sub>3,sh\<^sub>3),b\<^sub>3\" +and "final ef" +shows "P \ \C\\<^sub>sM(es),s\<^sub>0,b\<^sub>0\ \* \ef,(h\<^sub>3,l\<^sub>2,sh\<^sub>3),b\<^sub>3\" +(*<*) +proof - + have wf: "size Ts = size pns \ distinct pns" + and wt: "fv body \ set pns" + using assms by(fastforce dest!:sees_wf_mdecl simp:wf_mdecl_def)+ + from body[THEN Red_lcl_add, of l\<^sub>2] + have body': "P \ \body,(h\<^sub>2,l\<^sub>2(pns[\]vs),sh\<^sub>2),False\ \* \ef,(h\<^sub>3,l\<^sub>2++l\<^sub>3,sh\<^sub>3),b\<^sub>3\" + by (simp add:l\<^sub>2') + have "dom l\<^sub>3 \ set pns" + using Reds_dom_lcl[OF wwf body] wt l\<^sub>2' set_take_subset by force + hence eql\<^sub>2: "override_on (l\<^sub>2++l\<^sub>3) l\<^sub>2 (set pns) = l\<^sub>2" + by(fastforce simp add:map_add_def override_on_def fun_eq_iff) + have "icheck P D (C\\<^sub>sM(map Val vs)::'a exp)" using assms(3) by auto + then have "P \ \C\\<^sub>sM(map Val vs),(h\<^sub>2, l\<^sub>2, sh\<^sub>2),icheck P D (C\\<^sub>sM(map Val vs))\ + \ \blocks(pns, Ts, vs, body), (h\<^sub>2, l\<^sub>2, sh\<^sub>2), False\" + by (metis (full_types) assms(3) assms(7) local.wf red_reds.RedSCall) + also have "P \ \blocks(pns, Ts, vs, body), (h\<^sub>2, l\<^sub>2, sh\<^sub>2), False\ + \* \ef,(h\<^sub>3,override_on (l\<^sub>2++l\<^sub>3) l\<^sub>2 (set pns),sh\<^sub>3),b\<^sub>3\" + by(rule blocksRedsFinal, insert assms wf body', simp_all) + finally have trueReds: "P \ \C\\<^sub>sM(map Val vs),(h\<^sub>2, l\<^sub>2, sh\<^sub>2),icheck P D (C\\<^sub>sM(map Val vs))\ + \* \ef,(h\<^sub>3,override_on (l\<^sub>2++l\<^sub>3) l\<^sub>2 (set pns),sh\<^sub>3),b\<^sub>3\" by simp + have "P \ \C\\<^sub>sM(es),s\<^sub>0,b\<^sub>0\ \* \C\\<^sub>sM(map Val vs),(h\<^sub>1,l\<^sub>1,sh\<^sub>1),False\" + by(rule SCallRedsParams)(rule assms(2)) + also have "P \ \C\\<^sub>sM(map Val vs),(h\<^sub>1,l\<^sub>1,sh\<^sub>1),False\ \ \INIT D ([D],False) \ C\\<^sub>sM(map Val vs),(h\<^sub>1,l\<^sub>1,sh\<^sub>1),False\" + using SCallInitRed[OF assms(3)] assms(4-5) by auto + also (rtrancl_into_rtrancl) have "P \ \INIT D ([D],False) \ C\\<^sub>sM(map Val vs),(h\<^sub>1,l\<^sub>1,sh\<^sub>1),False\ + \* \ef,(h\<^sub>3,override_on (l\<^sub>2++l\<^sub>3) l\<^sub>2 (set pns),sh\<^sub>3),b\<^sub>3\" + using InitSeqReds[OF assms(6) trueReds] assms(5) by simp + finally show ?thesis using eql\<^sub>2 by simp +qed +(*>*) + +lemma SCallInitProcessingReds: +assumes wwf: "wwf_J_prog P" +and "P \ \es,s\<^sub>0,b\<^sub>0\ [\]* \map Val vs,(h\<^sub>2,l\<^sub>2,sh\<^sub>2),b\<^sub>2\" + "P \ C sees M,Static:Ts\T = (pns,body) in D" + "sh\<^sub>2 D = Some(sfs,Processing)" +and "size vs = size pns" +and l\<^sub>2': "l\<^sub>2' = [pns[\]vs]" +and body: "P \ \body,(h\<^sub>2,l\<^sub>2',sh\<^sub>2),False\ \* \ef,(h\<^sub>3,l\<^sub>3,sh\<^sub>3),b\<^sub>3\" +and "final ef" +shows "P \ \C\\<^sub>sM(es),s\<^sub>0,b\<^sub>0\ \* \ef,(h\<^sub>3,l\<^sub>2,sh\<^sub>3),b\<^sub>3\" +(*<*) +proof - + have wf: "size Ts = size pns \ distinct pns" + and wt: "fv body \ set pns" + using assms by(fastforce dest!:sees_wf_mdecl simp:wf_mdecl_def)+ + from body[THEN Red_lcl_add, of l\<^sub>2] + have body': "P \ \body,(h\<^sub>2,l\<^sub>2(pns[\]vs),sh\<^sub>2),False\ \* \ef,(h\<^sub>3,l\<^sub>2++l\<^sub>3,sh\<^sub>3),b\<^sub>3\" + by (simp add:l\<^sub>2') + have "dom l\<^sub>3 \ set pns" + using Reds_dom_lcl[OF wwf body] wt l\<^sub>2' set_take_subset by force + hence eql\<^sub>2: "override_on (l\<^sub>2++l\<^sub>3) l\<^sub>2 (set pns) = l\<^sub>2" + by(fastforce simp add:map_add_def override_on_def fun_eq_iff) + have b2T: "P \ \C\\<^sub>sM(map Val vs), (h\<^sub>2,l\<^sub>2,sh\<^sub>2),b\<^sub>2\ \* \C\\<^sub>sM(map Val vs), (h\<^sub>2,l\<^sub>2,sh\<^sub>2),True\" + proof(cases b\<^sub>2) + case True then show ?thesis by simp + next + case False + show ?thesis + proof(cases "M = clinit") + case True then show ?thesis using False assms(3) red_reds.SCallInitDoneRed assms(4) + by (simp add: r_into_rtrancl) + next + case nclinit: False + have icheck: "icheck P D (C\\<^sub>sM(map Val vs))" using assms(3) by auto + have "P \ \C\\<^sub>sM(map Val vs),(h\<^sub>2, l\<^sub>2, sh\<^sub>2),b\<^sub>2\ + \ \INIT D ([D],False) \ C\\<^sub>sM(map Val vs),(h\<^sub>2, l\<^sub>2, sh\<^sub>2),False\" + using SCallInitRed[OF assms(3)] assms(4) False nclinit by simp + also have "P \ \INIT D ([D],False) \ C\\<^sub>sM(map Val vs),(h\<^sub>2, l\<^sub>2, sh\<^sub>2),False\ + \ \INIT D (Nil,True) \ C\\<^sub>sM(map Val vs),(h\<^sub>2, l\<^sub>2, sh\<^sub>2),False\" + using RedInitProcessing assms(4) by simp + also have "P \ \INIT D (Nil,True) \ C\\<^sub>sM(map Val vs),(h\<^sub>2, l\<^sub>2, sh\<^sub>2),False\ + \ \C\\<^sub>sM(map Val vs),(h\<^sub>2, l\<^sub>2, sh\<^sub>2),True\" + using RedInit[of "C\\<^sub>sM(map Val vs)" D _ _ _ P] icheck nclinit + by (metis (full_types) nsub_RI_Vals sub_RI.simps(12)) + finally show ?thesis by simp + qed + qed + have "P \ \C\\<^sub>sM(es),s\<^sub>0,b\<^sub>0\ \* \C\\<^sub>sM(map Val vs),(h\<^sub>2,l\<^sub>2,sh\<^sub>2),b\<^sub>2\" + by(rule SCallRedsParams)(rule assms(2)) + also have "P \ \C\\<^sub>sM(map Val vs), (h\<^sub>2,l\<^sub>2,sh\<^sub>2),b\<^sub>2\ \* \blocks(pns, Ts, vs, body), (h\<^sub>2,l\<^sub>2,sh\<^sub>2),False\" + by(auto intro!: rtrancl_into_rtrancl[OF b2T] RedSCall assms(3) simp: assms wf) + also (rtrancl_trans) have "P \ \blocks(pns, Ts, vs, body), (h\<^sub>2,l\<^sub>2,sh\<^sub>2),False\ + \* \ef,(h\<^sub>3,override_on (l\<^sub>2++l\<^sub>3) l\<^sub>2 (set pns),sh\<^sub>3),b\<^sub>3\" + by(rule blocksRedsFinal, insert assms wf body', simp_all) + finally show ?thesis using eql\<^sub>2 by simp +qed +(*>*) + +(***********************************) + +subsubsection "The main Theorem" + +lemma assumes wwf: "wwf_J_prog P" +shows big_by_small: "P \ \e,s\ \ \e',s'\ + \ (\b. iconf (shp s) e \ P,shp s \\<^sub>b (e,b) \ \ P \ \e,s,b\ \* \e',s',False\)" +and bigs_by_smalls: "P \ \es,s\ [\] \es',s'\ + \ (\b. iconfs (shp s) es \ P,shp s \\<^sub>b (es,b) \ \ P \ \es,s,b\ [\]* \es',s',False\)" +(*<*) +proof (induct rule: eval_evals.inducts) + case New show ?case + proof(cases b) + case True then show ?thesis using RedNew[OF New.hyps(2-4)] by auto + next + case False then show ?thesis using New.hyps(1) NewInitDoneReds[OF _ New.hyps(2-4)] by auto + qed +next + case NewFail show ?case + proof(cases b) + case True then show ?thesis using RedNewFail[OF NewFail.hyps(2)] NewFail.hyps(3) by fastforce + next + case False + then show ?thesis using NewInitDoneReds2[OF _ NewFail.hyps(2)] NewFail by fastforce + qed +next + case (NewInit sh C h l v' h' l' sh' a FDTs h'') show ?case + proof(cases b) + case True + then obtain sfs where shC: "sh C = \(sfs, Processing)\" + using NewInit.hyps(1) NewInit.prems by(clarsimp simp: bconf_def initPD_def) + then have s': "(h',l',sh') = (h,l,sh)" using NewInit.hyps(2) init_ProcessingE by clarsimp + then show ?thesis using RedNew[OF NewInit.hyps(4-6)] True by auto + next + case False + then have init: "P \ \INIT C ([C],False) \ unit,(h, l, sh),False\ \* \Val v',(h', l', sh'),False\" + using NewInit.hyps(3) by(auto simp: bconf_def) + then show ?thesis using NewInit NewInitReds[OF _ init NewInit.hyps(4-6)] False + has_fields_is_class[OF NewInit.hyps(5)] by auto + qed +next + case (NewInitOOM sh C h l v' h' l' sh') show ?case + proof(cases b) + case True + then obtain sfs where shC: "sh C = \(sfs, Processing)\" + using NewInitOOM.hyps(1) NewInitOOM.prems by(clarsimp simp: bconf_def initPD_def) + then have s': "(h',l',sh') = (h,l,sh)" using NewInitOOM.hyps(2) init_ProcessingE by clarsimp + then show ?thesis using RedNewFail[OF NewInitOOM.hyps(4)] True r_into_rtrancl NewInitOOM.hyps(5) + by auto + next + case False + then have init: "P \ \INIT C ([C],False) \ unit,(h, l, sh),False\ \* \Val v',(h', l', sh'),False\" + using NewInitOOM.hyps(3) by(auto simp: bconf_def) + then show ?thesis using NewInitOOM.hyps(1) NewInitOOMReds[OF _ init NewInitOOM.hyps(4)] False + NewInitOOM.hyps(5) by auto + qed +next + case (NewInitThrow sh C h l a s') show ?case + proof(cases b) + case True + then obtain sfs where shC: "sh C = \(sfs, Processing)\" + using NewInitThrow.hyps(1) NewInitThrow.prems by(clarsimp simp: bconf_def initPD_def) + then show ?thesis using NewInitThrow.hyps(2) init_ProcessingE by blast + next + case False + then have init: "P \ \INIT C ([C],False) \ unit,(h, l, sh),b\ \* \throw a,s',False\" + using NewInitThrow.hyps(3) by(auto simp: bconf_def) + then show ?thesis using NewInitThrow NewInitThrowReds[of "(h,l,sh)" C P a s'] False by auto + qed +next + case Cast then show ?case by(fastforce intro:CastRedsAddr) +next + case CastNull then show ?case by(fastforce intro: CastRedsNull) +next + case CastFail thus ?case by(fastforce intro!:CastRedsFail) +next + case CastThrow thus ?case by(fastforce dest!:eval_final intro:CastRedsThrow) +next + case Val then show ?case using exI[of _ b] by(simp add: bconf_def) +next + case (BinOp e\<^sub>1 s\<^sub>0 v\<^sub>1 s\<^sub>1 e\<^sub>2 v\<^sub>2 s\<^sub>2 bop v) + show ?case + proof(cases "val_of e\<^sub>1") + case None + then have iconf: "iconf (shp s\<^sub>0) e\<^sub>1" using None BinOp.prems by auto + have bconf: "P,shp s\<^sub>0 \\<^sub>b (e\<^sub>1,b) \" using None BinOp.prems by auto + then have b1: "P \ \e\<^sub>1,s\<^sub>0,b\ \* \Val v\<^sub>1,s\<^sub>1,False\" using iconf BinOp.hyps(2) by auto + have binop: "P \ \e\<^sub>1 \bop\ e\<^sub>2,s\<^sub>0,b\ \* \Val v\<^sub>1 \bop\ e\<^sub>2,s\<^sub>1,False\" by(rule BinOp1Reds[OF b1]) + then have iconf2': "iconf (shp s\<^sub>1) e\<^sub>2" using Red_preserves_iconf[OF wwf binop] None BinOp by auto + have "P,shp s\<^sub>1 \\<^sub>b (e\<^sub>2,False) \" by(simp add: bconf_def) + then have b2: "P \ \e\<^sub>2,s\<^sub>1,False\ \* \Val v\<^sub>2,s\<^sub>2,False\" using BinOp.hyps(4)[OF iconf2'] by auto + then show ?thesis using BinOpRedsVal[OF b1 b2 BinOp.hyps(5)] by fast + next + case (Some a) + then obtain b1 where b1: "P \ \e\<^sub>1,s\<^sub>0,b\ \* \Val v\<^sub>1,s\<^sub>1,b1\" + by (metis (no_types, lifting) BinOp.hyps(1) eval_cases(3) rtrancl.rtrancl_refl val_of_spec) + have binop: "P \ \e\<^sub>1 \bop\ e\<^sub>2,s\<^sub>0,b\ \* \Val v\<^sub>1 \bop\ e\<^sub>2,s\<^sub>1,b1\" by(rule BinOp1Reds[OF b1]) + then have iconf2': "iconf (shp s\<^sub>1) e\<^sub>2" using Red_preserves_iconf[OF wwf binop] BinOp by auto + have bconf2: "P,shp s\<^sub>0 \\<^sub>b (e\<^sub>2,b) \" using BinOp.prems Some by simp + then have "P,shp s\<^sub>1 \\<^sub>b (e\<^sub>2,b1) \" using Red_preserves_bconf[OF wwf binop BinOp.prems] by simp + then have b2: "P \ \e\<^sub>2,s\<^sub>1,b1\ \* \Val v\<^sub>2,s\<^sub>2,False\" using BinOp.hyps(4)[OF iconf2'] by auto + then show ?thesis using BinOpRedsVal[OF b1 b2 BinOp.hyps(5)] by fast + qed +next + case (BinOpThrow1 e\<^sub>1 s\<^sub>0 e s\<^sub>1 bop e\<^sub>2) show ?case + proof(cases "val_of e\<^sub>1") + case None + then have "iconf (shp s\<^sub>0) e\<^sub>1" and "P,shp s\<^sub>0 \\<^sub>b (e\<^sub>1,b) \" using BinOpThrow1.prems by auto + then have b1: "P \ \e\<^sub>1,s\<^sub>0,b\ \* \throw e,s\<^sub>1,False\" using BinOpThrow1.hyps(2) by auto + then have "P \ \e\<^sub>1 \bop\ e\<^sub>2,s\<^sub>0,b\ \* \throw e,s\<^sub>1,False\" + using BinOpThrow1 None by(auto dest!:eval_final simp: BinOpRedsThrow1[OF b1]) + then show ?thesis by fast + next + case (Some a) + then show ?thesis using eval_final_same[OF BinOpThrow1.hyps(1)] val_of_spec[OF Some] by auto + qed +next + case (BinOpThrow2 e\<^sub>1 s\<^sub>0 v\<^sub>1 s\<^sub>1 e\<^sub>2 e s\<^sub>2 bop) + show ?case + proof(cases "val_of e\<^sub>1") + case None + then have iconf: "iconf (shp s\<^sub>0) e\<^sub>1" using None BinOpThrow2.prems by auto + have bconf: "P,shp s\<^sub>0 \\<^sub>b (e\<^sub>1,b) \" using None BinOpThrow2.prems by auto + then have b1: "P \ \e\<^sub>1,s\<^sub>0,b\ \* \Val v\<^sub>1,s\<^sub>1,False\" using iconf BinOpThrow2.hyps(2) by auto + have binop: "P \ \e\<^sub>1 \bop\ e\<^sub>2,s\<^sub>0,b\ \* \Val v\<^sub>1 \bop\ e\<^sub>2,s\<^sub>1,False\" by(rule BinOp1Reds[OF b1]) + then have iconf2': "iconf (shp s\<^sub>1) e\<^sub>2" using Red_preserves_iconf[OF wwf binop] None BinOpThrow2 by auto + have "P,shp s\<^sub>1 \\<^sub>b (e\<^sub>2,False) \" by(simp add: bconf_def) + then have b2: "P \ \e\<^sub>2,s\<^sub>1,False\ \* \throw e,s\<^sub>2,False\" using BinOpThrow2.hyps(4)[OF iconf2'] by auto + then show ?thesis using BinOpRedsThrow2[OF b1 b2] by fast + next + case (Some a) + then obtain b1 where b1: "P \ \e\<^sub>1,s\<^sub>0,b\ \* \Val v\<^sub>1,s\<^sub>1,b1\" + by (metis (no_types, lifting) BinOpThrow2.hyps(1) eval_cases(3) rtrancl.rtrancl_refl val_of_spec) + have binop: "P \ \e\<^sub>1 \bop\ e\<^sub>2,s\<^sub>0,b\ \* \Val v\<^sub>1 \bop\ e\<^sub>2,s\<^sub>1,b1\" by(rule BinOp1Reds[OF b1]) + then have iconf2': "iconf (shp s\<^sub>1) e\<^sub>2" using Red_preserves_iconf[OF wwf binop] BinOpThrow2 by auto + have bconf2: "P,shp s\<^sub>0 \\<^sub>b (e\<^sub>2,b) \" using BinOpThrow2.prems Some by simp + then have "P,shp s\<^sub>1 \\<^sub>b (e\<^sub>2,b1) \" using Red_preserves_bconf[OF wwf binop BinOpThrow2.prems] by simp + then have b2: "P \ \e\<^sub>2,s\<^sub>1,b1\ \* \throw e,s\<^sub>2,False\" using BinOpThrow2.hyps(4)[OF iconf2'] by auto + then show ?thesis using BinOpRedsThrow2[OF b1 b2] by fast + qed +next + case Var thus ?case by(auto dest:RedVar simp: bconf_def) +next + case LAss thus ?case by(auto dest: LAssRedsVal) +next + case LAssThrow thus ?case by(auto dest!:eval_final dest: LAssRedsThrow) +next + case FAcc thus ?case by(fastforce intro:FAccRedsVal) +next + case FAccNull thus ?case by(auto dest:FAccRedsNull) +next + case FAccThrow thus ?case by(auto dest!:eval_final dest:FAccRedsThrow) +next + case FAccNone then show ?case by(fastforce intro: FAccRedsNone) +next + case FAccStatic then show ?case by(fastforce intro: FAccRedsStatic) +next + case SFAcc show ?case + proof(cases b) + case True then show ?thesis using RedSFAcc SFAcc.hyps by auto + next + case False then show ?thesis using SFAcc.hyps SFAccInitDoneReds[OF SFAcc.hyps(1)] by auto + qed +next + case (SFAccInit C F t D sh h l v' h' l' sh' sfs i v) show ?case + proof(cases b) + case True + then obtain sfs where shC: "sh D = \(sfs, Processing)\" + using SFAccInit.hyps(2) SFAccInit.prems by(clarsimp simp: bconf_def initPD_def) + then have s': "(h',l',sh') = (h,l,sh)" using SFAccInit.hyps(3) init_ProcessingE by clarsimp + then show ?thesis using RedSFAcc SFAccInit.hyps True by auto + next + case False + then have init: "P \ \INIT D ([D],False) \ unit,(h, l, sh),False\ \* \Val v',(h', l', sh'),False\" + using SFAccInit.hyps(4) by(auto simp: bconf_def) + then show ?thesis using SFAccInit SFAccInitReds[OF _ _ init] False by auto + qed +next + case (SFAccInitThrow C F t D sh h l a s') show ?case + proof(cases b) + case True + then obtain sfs where shC: "sh D = \(sfs, Processing)\" + using SFAccInitThrow.hyps(2) SFAccInitThrow.prems(2) by(clarsimp simp: bconf_def initPD_def) + then show ?thesis using SFAccInitThrow.hyps(3) init_ProcessingE by blast + next + case False + then have init: "P \ \INIT D ([D],False) \ unit,(h, l, sh),b\ \* \throw a,s',False\" + using SFAccInitThrow.hyps(4) by(auto simp: bconf_def) + then show ?thesis using SFAccInitThrow SFAccInitThrowReds False by auto + qed +next + case SFAccNone then show ?case by(fastforce intro: SFAccRedsNone) +next + case SFAccNonStatic then show ?case by(fastforce intro: SFAccRedsNonStatic) +next + case (FAss e\<^sub>1 s\<^sub>0 a s\<^sub>1 e\<^sub>2 v h\<^sub>2 l\<^sub>2 sh\<^sub>2 C fs F t D fs' h\<^sub>2') + show ?case + proof(cases "val_of e\<^sub>1") + case None + then have iconf: "iconf (shp s\<^sub>0) e\<^sub>1" using None FAss.prems by auto + have bconf: "P,shp s\<^sub>0 \\<^sub>b (e\<^sub>1,b) \" using None FAss.prems by auto + then have b1: "P \ \e\<^sub>1,s\<^sub>0,b\ \* \addr a,s\<^sub>1,False\" using iconf FAss.hyps(2) by auto + have fass: "P \ \e\<^sub>1\F{D} := e\<^sub>2,s\<^sub>0,b\ \* \addr a\F{D} := e\<^sub>2,s\<^sub>1,False\" by(rule FAssReds1[OF b1]) + then have iconf2': "iconf (shp s\<^sub>1) e\<^sub>2" using Red_preserves_iconf[OF wwf fass] None FAss by auto + have "P,shp s\<^sub>1 \\<^sub>b (e\<^sub>2,False) \" by(simp add: bconf_def) + then have b2: "P \ \e\<^sub>2,s\<^sub>1,False\ \* \Val v,(h\<^sub>2, l\<^sub>2, sh\<^sub>2),False\" using FAss.hyps(4)[OF iconf2'] by auto + then show ?thesis using FAssRedsVal[OF b1 b2 FAss.hyps(6) FAss.hyps(5)[THEN sym]] FAss.hyps(7,8) by fast + next + case (Some a') + then obtain b1 where b1: "P \ \e\<^sub>1,s\<^sub>0,b\ \* \addr a,s\<^sub>1,b1\" + by (metis (no_types, lifting) FAss.hyps(1) eval_cases(3) rtrancl.rtrancl_refl val_of_spec) + have fass: "P \ \e\<^sub>1\F{D} := e\<^sub>2,s\<^sub>0,b\ \* \addr a\F{D} := e\<^sub>2,s\<^sub>1,b1\" by(rule FAssReds1[OF b1]) + then have iconf2': "iconf (shp s\<^sub>1) e\<^sub>2" using Red_preserves_iconf[OF wwf fass] FAss by auto + have bconf2: "P,shp s\<^sub>0 \\<^sub>b (e\<^sub>2,b) \" using FAss.prems Some by simp + then have "P,shp s\<^sub>1 \\<^sub>b (e\<^sub>2,b1) \" using Red_preserves_bconf[OF wwf fass FAss.prems] by simp + then have b2: "P \ \e\<^sub>2,s\<^sub>1,b1\ \* \Val v,(h\<^sub>2, l\<^sub>2, sh\<^sub>2),False\" using FAss.hyps(4)[OF iconf2'] by auto + then show ?thesis using FAssRedsVal[OF b1 b2] FAss.hyps(5)[THEN sym] FAss.hyps(6-8) by fast + qed +next + case (FAssNull e\<^sub>1 s\<^sub>0 s\<^sub>1 e\<^sub>2 v s\<^sub>2 F D) + show ?case + proof(cases "val_of e\<^sub>1") + case None + then have iconf: "iconf (shp s\<^sub>0) e\<^sub>1" using FAssNull.prems(1) by simp + have bconf: "P,shp s\<^sub>0 \\<^sub>b (e\<^sub>1,b) \" using FAssNull.prems(2) None by simp + then have b1: "P \ \e\<^sub>1,s\<^sub>0,b\ \* \null,s\<^sub>1,False\" using FAssNull.hyps(2)[OF iconf] by auto + have fass: "P \ \e\<^sub>1\F{D} := e\<^sub>2,s\<^sub>0,b\ \* \null\F{D} := e\<^sub>2,s\<^sub>1,False\" by(rule FAssReds1[OF b1]) + then have iconf2': "iconf (shp s\<^sub>1) e\<^sub>2" using Red_preserves_iconf[OF wwf fass] None FAssNull by auto + have "P,shp s\<^sub>1 \\<^sub>b (e\<^sub>2,False) \" by(simp add: bconf_def) + then have b2: "P \ \e\<^sub>2,s\<^sub>1,False\ \* \Val v,s\<^sub>2,False\" using FAssNull.hyps(4)[OF iconf2'] by auto + then show ?thesis using FAssRedsNull[OF b1 b2] by fast + next + case (Some a') + then obtain b1 where b1: "P \ \e\<^sub>1,s\<^sub>0,b\ \* \null,s\<^sub>1,b1\" + by (metis (no_types, lifting) FAssNull.hyps(1) eval_cases(3) rtrancl.rtrancl_refl val_of_spec) + have fass: "P \ \e\<^sub>1\F{D} := e\<^sub>2,s\<^sub>0,b\ \* \null\F{D} := e\<^sub>2,s\<^sub>1,b1\" by(rule FAssReds1[OF b1]) + then have iconf2': "iconf (shp s\<^sub>1) e\<^sub>2" using Red_preserves_iconf[OF wwf fass] FAssNull by auto + have bconf2: "P,shp s\<^sub>0 \\<^sub>b (e\<^sub>2,b) \" using FAssNull.prems Some by simp + then have "P,shp s\<^sub>1 \\<^sub>b (e\<^sub>2,b1) \" using Red_preserves_bconf[OF wwf fass FAssNull.prems] by simp + then have b2: "P \ \e\<^sub>2,s\<^sub>1,b1\ \* \Val v,s\<^sub>2,False\" using FAssNull.hyps(4)[OF iconf2'] by auto + then show ?thesis using FAssRedsNull[OF b1 b2] by fast + qed +next + case (FAssThrow1 e\<^sub>1 s\<^sub>0 e' s\<^sub>1 F D e\<^sub>2) show ?case + proof(cases "val_of e\<^sub>1") + case None + then have "iconf (shp s\<^sub>0) e\<^sub>1" and "P,shp s\<^sub>0 \\<^sub>b (e\<^sub>1,b) \" using FAssThrow1.prems by auto + then have b1: "P \ \e\<^sub>1,s\<^sub>0,b\ \* \throw e',s\<^sub>1,False\" using FAssThrow1.hyps(2) by auto + then have "P \ \e\<^sub>1\F{D} := e\<^sub>2,s\<^sub>0,b\ \* \throw e',s\<^sub>1,False\" + using FAssThrow1 None by(auto dest!:eval_final simp: FAssRedsThrow1[OF b1]) + then show ?thesis by fast + next + case (Some a) + then show ?thesis using eval_final_same[OF FAssThrow1.hyps(1)] val_of_spec[OF Some] by auto + qed +next + case (FAssThrow2 e\<^sub>1 s\<^sub>0 v s\<^sub>1 e\<^sub>2 e' s\<^sub>2 F D) + show ?case + proof(cases "val_of e\<^sub>1") + case None + then have iconf: "iconf (shp s\<^sub>0) e\<^sub>1" using None FAssThrow2.prems by auto + have bconf: "P,shp s\<^sub>0 \\<^sub>b (e\<^sub>1,b) \" using None FAssThrow2.prems by auto + then have b1: "P \ \e\<^sub>1,s\<^sub>0,b\ \* \Val v,s\<^sub>1,False\" using iconf FAssThrow2.hyps(2) by auto + have fass: "P \ \e\<^sub>1\F{D} := e\<^sub>2,s\<^sub>0,b\ \* \Val v\F{D} := e\<^sub>2,s\<^sub>1,False\" by(rule FAssReds1[OF b1]) + then have iconf2': "iconf (shp s\<^sub>1) e\<^sub>2" using Red_preserves_iconf[OF wwf fass] None FAssThrow2 by auto + have "P,shp s\<^sub>1 \\<^sub>b (e\<^sub>2,False) \" by(simp add: bconf_def) + then have b2: "P \ \e\<^sub>2,s\<^sub>1,False\ \* \throw e',s\<^sub>2,False\" using FAssThrow2.hyps(4)[OF iconf2'] by auto + then show ?thesis using FAssRedsThrow2[OF b1 b2] by fast + next + case (Some a') + then obtain b1 where b1: "P \ \e\<^sub>1,s\<^sub>0,b\ \* \Val v,s\<^sub>1,b1\" + by (metis (no_types, lifting) FAssThrow2.hyps(1) eval_cases(3) rtrancl.rtrancl_refl val_of_spec) + have fass: "P \ \e\<^sub>1\F{D} := e\<^sub>2,s\<^sub>0,b\ \* \Val v\F{D} := e\<^sub>2,s\<^sub>1,b1\" by(rule FAssReds1[OF b1]) + then have iconf2': "iconf (shp s\<^sub>1) e\<^sub>2" using Red_preserves_iconf[OF wwf fass] FAssThrow2 by auto + have bconf2: "P,shp s\<^sub>0 \\<^sub>b (e\<^sub>2,b) \" using FAssThrow2.prems Some by simp + then have "P,shp s\<^sub>1 \\<^sub>b (e\<^sub>2,b1) \" using Red_preserves_bconf[OF wwf fass FAssThrow2.prems] by simp + then have b2: "P \ \e\<^sub>2,s\<^sub>1,b1\ \* \throw e',s\<^sub>2,False\" using FAssThrow2.hyps(4)[OF iconf2'] by auto + then show ?thesis using FAssRedsThrow2[OF b1 b2] by fast + qed +next + case (FAssNone e\<^sub>1 s\<^sub>0 a s\<^sub>1 e\<^sub>2 v h\<^sub>2 l\<^sub>2 sh\<^sub>2 C fs F D) + show ?case + proof(cases "val_of e\<^sub>1") + case None + then have iconf: "iconf (shp s\<^sub>0) e\<^sub>1" using None FAssNone.prems by auto + have bconf: "P,shp s\<^sub>0 \\<^sub>b (e\<^sub>1,b) \" using None FAssNone.prems by auto + then have b1: "P \ \e\<^sub>1,s\<^sub>0,b\ \* \addr a,s\<^sub>1,False\" using iconf FAssNone.hyps(2) by auto + have fass: "P \ \e\<^sub>1\F{D} := e\<^sub>2,s\<^sub>0,b\ \* \addr a\F{D} := e\<^sub>2,s\<^sub>1,False\" by(rule FAssReds1[OF b1]) + then have iconf2': "iconf (shp s\<^sub>1) e\<^sub>2" using Red_preserves_iconf[OF wwf fass] None FAssNone by auto + have "P,shp s\<^sub>1 \\<^sub>b (e\<^sub>2,False) \" by(simp add: bconf_def) + then have b2: "P \ \e\<^sub>2,s\<^sub>1,False\ \* \Val v,(h\<^sub>2, l\<^sub>2, sh\<^sub>2),False\" using FAssNone.hyps(4)[OF iconf2'] by auto + then show ?thesis using FAssRedsNone[OF b1 b2 FAssNone.hyps(5,6)] by fast + next + case (Some a') + then obtain b1 where b1: "P \ \e\<^sub>1,s\<^sub>0,b\ \* \addr a,s\<^sub>1,b1\" + by (metis (no_types, lifting) FAssNone.hyps(1) eval_cases(3) rtrancl.rtrancl_refl val_of_spec) + have fass: "P \ \e\<^sub>1\F{D} := e\<^sub>2,s\<^sub>0,b\ \* \addr a\F{D} := e\<^sub>2,s\<^sub>1,b1\" by(rule FAssReds1[OF b1]) + then have iconf2': "iconf (shp s\<^sub>1) e\<^sub>2" using Red_preserves_iconf[OF wwf fass] FAssNone by auto + have bconf2: "P,shp s\<^sub>0 \\<^sub>b (e\<^sub>2,b) \" using FAssNone.prems Some by simp + then have "P,shp s\<^sub>1 \\<^sub>b (e\<^sub>2,b1) \" using Red_preserves_bconf[OF wwf fass FAssNone.prems] by simp + then have b2: "P \ \e\<^sub>2,s\<^sub>1,b1\ \* \Val v,(h\<^sub>2, l\<^sub>2, sh\<^sub>2),False\" using FAssNone.hyps(4)[OF iconf2'] by auto + then show ?thesis using FAssRedsNone[OF b1 b2 FAssNone.hyps(5,6)] by fast + qed +next + case (FAssStatic e\<^sub>1 s\<^sub>0 a s\<^sub>1 e\<^sub>2 v h\<^sub>2 l\<^sub>2 sh\<^sub>2 C fs F t D) + show ?case + proof(cases "val_of e\<^sub>1") + case None + then have iconf: "iconf (shp s\<^sub>0) e\<^sub>1" using None FAssStatic.prems by auto + have bconf: "P,shp s\<^sub>0 \\<^sub>b (e\<^sub>1,b) \" using None FAssStatic.prems by auto + then have b1: "P \ \e\<^sub>1,s\<^sub>0,b\ \* \addr a,s\<^sub>1,False\" using iconf FAssStatic.hyps(2) by auto + have fass: "P \ \e\<^sub>1\F{D} := e\<^sub>2,s\<^sub>0,b\ \* \addr a\F{D} := e\<^sub>2,s\<^sub>1,False\" by(rule FAssReds1[OF b1]) + then have iconf2': "iconf (shp s\<^sub>1) e\<^sub>2" using Red_preserves_iconf[OF wwf fass] None FAssStatic by auto + have "P,shp s\<^sub>1 \\<^sub>b (e\<^sub>2,False) \" by(simp add: bconf_def) + then have b2: "P \ \e\<^sub>2,s\<^sub>1,False\ \* \Val v,(h\<^sub>2, l\<^sub>2, sh\<^sub>2),False\" using FAssStatic.hyps(4)[OF iconf2'] by auto + then show ?thesis using FAssRedsStatic[OF b1 b2 FAssStatic.hyps(5,6)] by fast + next + case (Some a') + then obtain b1 where b1: "P \ \e\<^sub>1,s\<^sub>0,b\ \* \addr a,s\<^sub>1,b1\" + by (metis (no_types, lifting) FAssStatic.hyps(1) eval_cases(3) rtrancl.rtrancl_refl val_of_spec) + have fass: "P \ \e\<^sub>1\F{D} := e\<^sub>2,s\<^sub>0,b\ \* \addr a\F{D} := e\<^sub>2,s\<^sub>1,b1\" by(rule FAssReds1[OF b1]) + then have iconf2': "iconf (shp s\<^sub>1) e\<^sub>2" using Red_preserves_iconf[OF wwf fass] FAssStatic by auto + have bconf2: "P,shp s\<^sub>0 \\<^sub>b (e\<^sub>2,b) \" using FAssStatic.prems Some by simp + then have "P,shp s\<^sub>1 \\<^sub>b (e\<^sub>2,b1) \" using Red_preserves_bconf[OF wwf fass FAssStatic.prems] by simp + then have b2: "P \ \e\<^sub>2,s\<^sub>1,b1\ \* \Val v,(h\<^sub>2, l\<^sub>2, sh\<^sub>2),False\" using FAssStatic.hyps(4)[OF iconf2'] by auto + then show ?thesis using FAssRedsStatic[OF b1 b2 FAssStatic.hyps(5,6)] by fast + qed +next + case (SFAss e\<^sub>2 s\<^sub>0 v h\<^sub>1 l\<^sub>1 sh\<^sub>1 C F t D sfs sfs' sh\<^sub>1') + show ?case + proof(cases "val_of e\<^sub>2") + case None + then have bconf: "P,shp s\<^sub>0 \\<^sub>b (e\<^sub>2,b) \" using SFAss.prems(2) by simp + then have b1: "P \ \e\<^sub>2,s\<^sub>0,b\ \* \Val v,(h\<^sub>1, l\<^sub>1, sh\<^sub>1),False\" using SFAss by auto + thus ?thesis using SFAssRedsVal[OF b1 SFAss.hyps(3,4)] SFAss.hyps(5,6) by fast + next + case (Some a) + then obtain b1 where b1: "P \ \e\<^sub>2,s\<^sub>0,b\ \* \Val v,(h\<^sub>1, l\<^sub>1, sh\<^sub>1),b1\" + by (metis (no_types, lifting) SFAss.hyps(1) eval_cases(3) rtrancl.rtrancl_refl val_of_spec) + thus ?thesis using SFAssRedsVal[OF b1 SFAss.hyps(3,4)] SFAss.hyps(5,6) by fast + qed +next + case (SFAssInit e\<^sub>2 s\<^sub>0 v h\<^sub>1 l\<^sub>1 sh\<^sub>1 C F t D v' h' l' sh' sfs i sfs' sh'') + then have iconf: "iconf (shp s\<^sub>0) e\<^sub>2" by simp + show ?case + proof(cases "val_of e\<^sub>2") + case None + then have bconf: "P,shp s\<^sub>0 \\<^sub>b (e\<^sub>2,b) \" using SFAssInit.prems(2) by simp + then have reds: "P \ \e\<^sub>2,s\<^sub>0,b\ \* \Val v,(h\<^sub>1, l\<^sub>1, sh\<^sub>1),False\" + using SFAssInit.hyps(2)[OF iconf bconf] by auto + then have init: "P \ \INIT D ([D],False) \ unit,(h\<^sub>1, l\<^sub>1, sh\<^sub>1),False\ \* \Val v',(h', l', sh'),False\" + using SFAssInit.hyps(6) by(auto simp: bconf_def) + then show ?thesis using SFAssInit SFAssInitReds[OF reds SFAssInit.hyps(3) _ init] by auto + next + case (Some v2) show ?thesis + proof(cases b) + case False + then have bconf: "P,shp s\<^sub>0 \\<^sub>b (e\<^sub>2,b) \" by(simp add: bconf_def) + then have reds: "P \ \e\<^sub>2,s\<^sub>0,b\ \* \Val v,(h\<^sub>1, l\<^sub>1, sh\<^sub>1),False\" + using SFAssInit.hyps(2)[OF iconf bconf] by auto + then have init: "P \ \INIT D ([D],False) \ unit,(h\<^sub>1, l\<^sub>1, sh\<^sub>1),False\ \* \Val v',(h', l', sh'),False\" + using SFAssInit.hyps(6) by(auto simp: bconf_def) + then show ?thesis using SFAssInit SFAssInitReds[OF reds SFAssInit.hyps(3) _ init] by auto + next + case True + have e\<^sub>2: "e\<^sub>2 = Val v2" using val_of_spec[OF Some] by simp + then have vs: "v2 = v \ s\<^sub>0 = (h\<^sub>1, l\<^sub>1, sh\<^sub>1)" using eval_final_same[OF SFAssInit.hyps(1)] by simp + then obtain sfs where shC: "sh\<^sub>1 D = \(sfs, Processing)\" + using SFAssInit.hyps(3,4) SFAssInit.prems(2) Some True + by(cases e\<^sub>2, auto simp: bconf_def initPD_def dest: sees_method_fun) + then have s': "(h',l',sh') = (h\<^sub>1, l\<^sub>1, sh\<^sub>1)" using SFAssInit.hyps(5) init_ProcessingE by clarsimp + then show ?thesis using SFAssInit.hyps(3,7-9) True e\<^sub>2 red_reds.RedSFAss vs by auto + qed + qed +next + case (SFAssInitThrow e\<^sub>2 s\<^sub>0 v h\<^sub>1 l\<^sub>1 sh\<^sub>1 C F t D a s') + then have iconf: "iconf (shp s\<^sub>0) e\<^sub>2" by simp + show ?case + proof(cases "val_of e\<^sub>2") + case None + then have bconf: "P,shp s\<^sub>0 \\<^sub>b (e\<^sub>2,b) \" using SFAssInitThrow.prems(2) by simp + then have reds: "P \ \e\<^sub>2,s\<^sub>0,b\ \* \Val v,(h\<^sub>1, l\<^sub>1, sh\<^sub>1),False\" + using SFAssInitThrow.hyps(2)[OF iconf bconf] by auto + then have init: "P \ \INIT D ([D],False) \ unit,(h\<^sub>1, l\<^sub>1, sh\<^sub>1),False\ \* \throw a,s',False\" + using SFAssInitThrow.hyps(6) by(auto simp: bconf_def) + then show ?thesis using SFAssInitThrow SFAssInitThrowReds[OF reds _ _ init] by auto + next + case (Some v2) show ?thesis + proof(cases b) + case False + then have bconf: "P,shp s\<^sub>0 \\<^sub>b (e\<^sub>2,b) \" by(simp add: bconf_def) + then have reds: "P \ \e\<^sub>2,s\<^sub>0,b\ \* \Val v,(h\<^sub>1, l\<^sub>1, sh\<^sub>1),False\" + using SFAssInitThrow.hyps(2)[OF iconf bconf] by auto + then have init: "P \ \INIT D ([D],False) \ unit,(h\<^sub>1, l\<^sub>1, sh\<^sub>1),False\ \* \throw a,s',False\" + using SFAssInitThrow.hyps(6) by(auto simp: bconf_def) + then show ?thesis using SFAssInitThrow SFAssInitThrowReds[OF reds _ _ init] by auto + next + case True + obtain v2 where e\<^sub>2: "e\<^sub>2 = Val v2" using val_of_spec[OF Some] by simp + then have vs: "v2 = v \ s\<^sub>0 = (h\<^sub>1, l\<^sub>1, sh\<^sub>1)" + using eval_final_same[OF SFAssInitThrow.hyps(1)] by simp + then obtain sfs where shC: "sh\<^sub>1 D = \(sfs, Processing)\" + using SFAssInitThrow.hyps(4) SFAssInitThrow.prems(2) Some True + by(cases e\<^sub>2, auto simp: bconf_def initPD_def dest: sees_method_fun) + then show ?thesis using SFAssInitThrow.hyps(5) init_ProcessingE by blast + qed + qed +next + case (SFAssThrow e\<^sub>2 s\<^sub>0 e' s\<^sub>2 C F D) + show ?case + proof(cases "val_of e\<^sub>2") + case None + then have bconf: "P,shp s\<^sub>0 \\<^sub>b (e\<^sub>2,b) \" using SFAssThrow.prems(2) None by simp + then have b1: "P \ \e\<^sub>2,s\<^sub>0,b\ \* \throw e',s\<^sub>2,False\" using SFAssThrow by auto + thus ?thesis using SFAssRedsThrow[OF b1] by fast + next + case (Some a) + then show ?thesis using eval_final_same[OF SFAssThrow.hyps(1)] val_of_spec[OF Some] by auto + qed +next + case (SFAssNone e\<^sub>2 s\<^sub>0 v h\<^sub>2 l\<^sub>2 sh\<^sub>2 C F D) + show ?case + proof(cases "val_of e\<^sub>2") + case None + then have iconf: "iconf (shp s\<^sub>0) e\<^sub>2" using SFAssNone by simp + then have bconf: "P,shp s\<^sub>0 \\<^sub>b (e\<^sub>2,b) \" using SFAssNone.prems(2) None by simp + then have b1: "P \ \e\<^sub>2,s\<^sub>0,b\ \* \Val v,(h\<^sub>2, l\<^sub>2, sh\<^sub>2),False\" using SFAssNone.hyps(2) iconf by auto + thus ?thesis using SFAssRedsNone[OF b1 SFAssNone.hyps(3)] by fast + next + case (Some a) + then obtain b1 where b1: "P \ \e\<^sub>2,s\<^sub>0,b\ \* \Val v,(h\<^sub>2, l\<^sub>2, sh\<^sub>2),b1\" + by (metis (no_types, lifting) SFAssNone.hyps(1) eval_cases(3) rtrancl.rtrancl_refl val_of_spec) + thus ?thesis using SFAssRedsNone[OF b1 SFAssNone.hyps(3)] by fast + qed +next + case (SFAssNonStatic e\<^sub>2 s\<^sub>0 v h\<^sub>2 l\<^sub>2 sh\<^sub>2 C F t D) show ?case + proof(cases "val_of e\<^sub>2") + case None + then have iconf: "iconf (shp s\<^sub>0) e\<^sub>2" using SFAssNonStatic by simp + then have bconf: "P,shp s\<^sub>0 \\<^sub>b (e\<^sub>2,b) \" using SFAssNonStatic.prems(2) None by simp + then have b1: "P \ \e\<^sub>2,s\<^sub>0,b\ \* \Val v,(h\<^sub>2, l\<^sub>2, sh\<^sub>2),False\" using SFAssNonStatic.hyps(2) iconf by auto + thus ?thesis using SFAssRedsNonStatic[OF b1 SFAssNonStatic.hyps(3)] by fast + next + case (Some a) + then obtain b' where b1: "P \ \e\<^sub>2,s\<^sub>0,b\ \* \Val v,(h\<^sub>2, l\<^sub>2, sh\<^sub>2),b'\" + by (metis (no_types, lifting) SFAssNonStatic.hyps(1) eval_cases(3) rtrancl.rtrancl_refl val_of_spec) + thus ?thesis using SFAssRedsNonStatic[OF b1 SFAssNonStatic.hyps(3)] by fast + qed +next + case (CallObjThrow e s\<^sub>0 e' s\<^sub>1 M ps) show ?case + proof(cases "val_of e") + case None + then have "iconf (shp s\<^sub>0) e" and "P,shp s\<^sub>0 \\<^sub>b (e,b) \" using CallObjThrow.prems by auto + then have b1: "P \ \e,s\<^sub>0,b\ \* \throw e',s\<^sub>1,False\" using CallObjThrow.hyps(2) by auto + then have "P \ \e\M(ps),s\<^sub>0,b\ \* \throw e',s\<^sub>1,False\" + using CallObjThrow None by(auto dest!:eval_final simp: CallRedsThrowObj[OF b1]) + then show ?thesis by fast + next + case (Some a) + then show ?thesis using eval_final_same[OF CallObjThrow.hyps(1)] val_of_spec[OF Some] by auto + qed +next + case (CallNull e s\<^sub>0 s\<^sub>1 ps vs s\<^sub>2 M) show ?case + proof(cases "val_of e") + case None + then have iconf: "iconf (shp s\<^sub>0) e" using CallNull.prems(1) by simp + have bconf: "P,shp s\<^sub>0 \\<^sub>b (e,b) \" using CallNull.prems(2) None by simp + then have b1: "P \ \e,s\<^sub>0,b\ \* \null,s\<^sub>1,False\" using CallNull.hyps(2)[OF iconf] by auto + have call: "P \ \e\M(ps),s\<^sub>0,b\ \* \null\M(ps),s\<^sub>1,False\" by(rule CallRedsObj[OF b1]) + then have iconf2': "iconfs (shp s\<^sub>1) ps" using Red_preserves_iconf[OF wwf call] None CallNull by auto + have "P,shp s\<^sub>1 \\<^sub>b (ps,False) \" by(simp add: bconfs_def) + then have b2: "P \ \ps,s\<^sub>1,False\ [\]* \map Val vs,s\<^sub>2,False\" using CallNull.hyps(4)[OF iconf2'] by auto + then show ?thesis using CallRedsNull[OF b1 b2] by fast + next + case (Some a') + then obtain b1 where b1: "P \ \e,s\<^sub>0,b\ \* \null,s\<^sub>1,b1\" + by (metis (no_types, lifting) CallNull.hyps(1) eval_cases(3) rtrancl.rtrancl_refl val_of_spec) + have fass: "P \ \e\M(ps),s\<^sub>0,b\ \* \null\M(ps),s\<^sub>1,b1\" by(rule CallRedsObj[OF b1]) + then have iconf2': "iconfs (shp s\<^sub>1) ps" using Red_preserves_iconf[OF wwf fass] CallNull by auto + have bconf2: "P,shp s\<^sub>0 \\<^sub>b (ps,b) \" using CallNull.prems Some by simp + then have "P,shp s\<^sub>1 \\<^sub>b (ps,b1) \" using Red_preserves_bconf[OF wwf fass CallNull.prems] by simp + then have b2: "P \ \ps,s\<^sub>1,b1\ [\]* \map Val vs,s\<^sub>2,False\" using CallNull.hyps(4)[OF iconf2'] by auto + then show ?thesis using CallRedsNull[OF b1 b2] by fast + qed +next + case (CallParamsThrow e s\<^sub>0 v s\<^sub>1 es vs ex es' s\<^sub>2 M) show ?case + proof(cases "val_of e") + case None + then have iconf: "iconf (shp s\<^sub>0) e" using CallParamsThrow.prems(1) by simp + have bconf: "P,shp s\<^sub>0 \\<^sub>b (e,b) \" using CallParamsThrow.prems(2) None by simp + then have b1: "P \ \e,s\<^sub>0,b\ \* \Val v,s\<^sub>1,False\" using CallParamsThrow.hyps(2)[OF iconf] by auto + have call: "P \ \e\M(es),s\<^sub>0,b\ \* \Val v\M(es),s\<^sub>1,False\" by(rule CallRedsObj[OF b1]) + then have iconf2': "iconfs (shp s\<^sub>1) es" using Red_preserves_iconf[OF wwf call] None CallParamsThrow by auto + have "P,shp s\<^sub>1 \\<^sub>b (es,False) \" by(simp add: bconfs_def) + then have b2: "P \ \es,s\<^sub>1,False\ [\]* \map Val vs @ throw ex # es',s\<^sub>2,False\" + using CallParamsThrow.hyps(4)[OF iconf2'] by auto + then show ?thesis using CallRedsThrowParams[OF b1 b2] by fast + next + case (Some a') + then obtain b1 where b1: "P \ \e,s\<^sub>0,b\ \* \Val v,s\<^sub>1,b1\" + by (metis (no_types, lifting) CallParamsThrow.hyps(1) eval_cases(3) rtrancl.rtrancl_refl val_of_spec) + have fass: "P \ \e\M(es),s\<^sub>0,b\ \* \Val v\M(es),s\<^sub>1,b1\" by(rule CallRedsObj[OF b1]) + then have iconf2': "iconfs (shp s\<^sub>1) es" using Red_preserves_iconf[OF wwf fass] CallParamsThrow by auto + have bconf2: "P,shp s\<^sub>0 \\<^sub>b (es,b) \" using CallParamsThrow.prems Some by simp + then have "P,shp s\<^sub>1 \\<^sub>b (es,b1) \" using Red_preserves_bconf[OF wwf fass CallParamsThrow.prems] by simp + then have b2: "P \ \es,s\<^sub>1,b1\ [\]* \map Val vs @ throw ex # es',s\<^sub>2,False\" + using CallParamsThrow.hyps(4)[OF iconf2'] by auto + then show ?thesis using CallRedsThrowParams[OF b1 b2] by fast + qed +next + case (CallNone e s\<^sub>0 a s\<^sub>1 ps vs h\<^sub>2 l\<^sub>2 sh\<^sub>2 C fs M) show ?case + proof(cases "val_of e") + case None + then have iconf: "iconf (shp s\<^sub>0) e" using CallNone.prems(1) by simp + have bconf: "P,shp s\<^sub>0 \\<^sub>b (e,b) \" using CallNone.prems(2) None by simp + then have b1: "P \ \e,s\<^sub>0,b\ \* \addr a,s\<^sub>1,False\" using CallNone.hyps(2)[OF iconf] by auto + have call: "P \ \e\M(ps),s\<^sub>0,b\ \* \addr a\M(ps),s\<^sub>1,False\" by(rule CallRedsObj[OF b1]) + then have iconf2': "iconfs (shp s\<^sub>1) ps" using Red_preserves_iconf[OF wwf call] None CallNone by auto + have "P,shp s\<^sub>1 \\<^sub>b (ps,False) \" by(simp add: bconfs_def) + then have b2: "P \ \ps,s\<^sub>1,False\ [\]* \map Val vs,(h\<^sub>2, l\<^sub>2, sh\<^sub>2),False\" + using CallNone.hyps(4)[OF iconf2'] by auto + then show ?thesis using CallRedsNone[OF b1 b2 _ CallNone.hyps(6)] CallNone.hyps(5) by fastforce + next + case (Some a') + then obtain b1 where b1: "P \ \e,s\<^sub>0,b\ \* \addr a,s\<^sub>1,b1\" + by (metis (no_types, lifting) CallNone.hyps(1) eval_cases(3) rtrancl.rtrancl_refl val_of_spec) + have fass: "P \ \e\M(ps),s\<^sub>0,b\ \* \addr a\M(ps),s\<^sub>1,b1\" by(rule CallRedsObj[OF b1]) + then have iconf2': "iconfs (shp s\<^sub>1) ps" using Red_preserves_iconf[OF wwf fass] CallNone by auto + have bconf2: "P,shp s\<^sub>0 \\<^sub>b (ps,b) \" using CallNone.prems Some by simp + then have "P,shp s\<^sub>1 \\<^sub>b (ps,b1) \" using Red_preserves_bconf[OF wwf fass CallNone.prems] by simp + then have b2: "P \ \ps,s\<^sub>1,b1\ [\]* \map Val vs,(h\<^sub>2, l\<^sub>2, sh\<^sub>2),False\" + using CallNone.hyps(4)[OF iconf2'] by auto + then show ?thesis using CallRedsNone[OF b1 b2 _ CallNone.hyps(6)] CallNone.hyps(5) by fastforce + qed +next + case (CallStatic e s\<^sub>0 a s\<^sub>1 ps vs h\<^sub>2 l\<^sub>2 sh\<^sub>2 C fs M Ts T m D) show ?case + proof(cases "val_of e") + case None + then have iconf: "iconf (shp s\<^sub>0) e" using CallStatic.prems(1) by simp + have bconf: "P,shp s\<^sub>0 \\<^sub>b (e,b) \" using CallStatic.prems(2) None by simp + then have b1: "P \ \e,s\<^sub>0,b\ \* \addr a,s\<^sub>1,False\" using CallStatic.hyps(2)[OF iconf] by auto + have call: "P \ \e\M(ps),s\<^sub>0,b\ \* \addr a\M(ps),s\<^sub>1,False\" by(rule CallRedsObj[OF b1]) + then have iconf2': "iconfs (shp s\<^sub>1) ps" using Red_preserves_iconf[OF wwf call] None CallStatic by auto + have "P,shp s\<^sub>1 \\<^sub>b (ps,False) \" by(simp add: bconfs_def) + then have b2: "P \ \ps,s\<^sub>1,False\ [\]* \map Val vs,(h\<^sub>2, l\<^sub>2, sh\<^sub>2),False\" + using CallStatic.hyps(4)[OF iconf2'] by auto + then show ?thesis using CallRedsStatic[OF b1 b2 _ CallStatic.hyps(6)] CallStatic.hyps(5) by fastforce + next + case (Some a') + then obtain b1 where b1: "P \ \e,s\<^sub>0,b\ \* \addr a,s\<^sub>1,b1\" + by (metis (no_types, lifting) CallStatic.hyps(1) eval_cases(3) rtrancl.rtrancl_refl val_of_spec) + have call: "P \ \e\M(ps),s\<^sub>0,b\ \* \addr a\M(ps),s\<^sub>1,b1\" by(rule CallRedsObj[OF b1]) + then have iconf2': "iconfs (shp s\<^sub>1) ps" using Red_preserves_iconf[OF wwf call] CallStatic by auto + have bconf2: "P,shp s\<^sub>0 \\<^sub>b (ps,b) \" using CallStatic.prems Some by simp + then have "P,shp s\<^sub>1 \\<^sub>b (ps,b1) \" using Red_preserves_bconf[OF wwf call CallStatic.prems] by simp + then have b2: "P \ \ps,s\<^sub>1,b1\ [\]* \map Val vs,(h\<^sub>2, l\<^sub>2, sh\<^sub>2),False\" + using CallStatic.hyps(4)[OF iconf2'] by auto + then show ?thesis using CallRedsStatic[OF b1 b2 _ CallStatic.hyps(6)] CallStatic.hyps(5) by fastforce + qed +next + case (Call e s\<^sub>0 a s\<^sub>1 ps vs h\<^sub>2 l\<^sub>2 sh\<^sub>2 C fs M Ts T pns body D l\<^sub>2' e' h\<^sub>3 l\<^sub>3 sh\<^sub>3) show ?case + proof(cases "val_of e") + case None + then have iconf: "iconf (shp s\<^sub>0) e" using Call.prems(1) by simp + have bconf: "P,shp s\<^sub>0 \\<^sub>b (e,b) \" using Call.prems(2) None by simp + then have b1: "P \ \e,s\<^sub>0,b\ \* \addr a,s\<^sub>1,False\" using Call.hyps(2)[OF iconf] by auto + have call: "P \ \e\M(ps),s\<^sub>0,b\ \* \addr a\M(ps),s\<^sub>1,False\" by(rule CallRedsObj[OF b1]) + then have iconf2: "iconfs (shp s\<^sub>1) ps" using Red_preserves_iconf[OF wwf call] None Call by auto + have "P,shp s\<^sub>1 \\<^sub>b (ps,False) \" by(simp add: bconfs_def) + then have b2: "P \ \ps,s\<^sub>1,False\ [\]* \map Val vs,(h\<^sub>2, l\<^sub>2, sh\<^sub>2),False\" + using Call.hyps(4)[OF iconf2] by simp + have iconf3: "iconf (shp (h\<^sub>2, l\<^sub>2', sh\<^sub>2)) body" + by(rule nsub_RI_iconf[OF sees_wwf_nsub_RI[OF wwf Call.hyps(6)]]) + have "P,shp (h\<^sub>2, l\<^sub>2', sh\<^sub>2) \\<^sub>b (body,False) \" by(simp add: bconf_def) + then have b3: "P \ \body,(h\<^sub>2, l\<^sub>2', sh\<^sub>2),False\ \* \e',(h\<^sub>3, l\<^sub>3, sh\<^sub>3),False\" + using Call.hyps(10)[OF iconf3] by simp + show ?thesis by(rule CallRedsFinal[OF wwf b1 b2 Call.hyps(5-8) b3 eval_final[OF Call.hyps(9)]]) + next + case (Some a') + then obtain b1 where b1: "P \ \e,s\<^sub>0,b\ \* \addr a,s\<^sub>1,b1\" + by (metis (no_types, lifting) Call.hyps(1) eval_cases(3) rtrancl.rtrancl_refl val_of_spec) + have call: "P \ \e\M(ps),s\<^sub>0,b\ \* \addr a\M(ps),s\<^sub>1,b1\" by(rule CallRedsObj[OF b1]) + then have iconf2': "iconfs (shp s\<^sub>1) ps" using Red_preserves_iconf[OF wwf call] Call by auto + have bconf2: "P,shp s\<^sub>0 \\<^sub>b (ps,b) \" using Call.prems Some by simp + then have "P,shp s\<^sub>1 \\<^sub>b (ps,b1) \" using Red_preserves_bconf[OF wwf call Call.prems] by simp + then have b2: "P \ \ps,s\<^sub>1,b1\ [\]* \map Val vs,(h\<^sub>2, l\<^sub>2, sh\<^sub>2),False\" + using Call.hyps(4)[OF iconf2'] by auto + have iconf3: "iconf (shp (h\<^sub>2, l\<^sub>2', sh\<^sub>2)) body" + by(rule nsub_RI_iconf[OF sees_wwf_nsub_RI[OF wwf Call.hyps(6)]]) + have "P,shp (h\<^sub>2, l\<^sub>2', sh\<^sub>2) \\<^sub>b (body,False) \" by(simp add: bconf_def) + then have b3: "P \ \body,(h\<^sub>2, l\<^sub>2', sh\<^sub>2),False\ \* \e',(h\<^sub>3, l\<^sub>3, sh\<^sub>3),False\" + using Call.hyps(10)[OF iconf3] by simp + show ?thesis by(rule CallRedsFinal[OF wwf b1 b2 Call.hyps(5-8) b3 eval_final[OF Call.hyps(9)]]) + qed +next + case (SCallParamsThrow es s\<^sub>0 vs ex es' s\<^sub>2 C M) show ?case + proof(cases "map_vals_of es") + case None + then have iconf: "iconfs (shp s\<^sub>0) es" using SCallParamsThrow.prems(1) by simp + have bconf: "P,shp s\<^sub>0 \\<^sub>b (es,b) \" using SCallParamsThrow.prems(2) None by simp + then have b1: "P \ \es,s\<^sub>0,b\ [\]* \map Val vs @ throw ex # es',s\<^sub>2,False\" + using SCallParamsThrow.hyps(2)[OF iconf] by simp + show ?thesis using SCallRedsThrowParams[OF b1] by simp + next + case (Some vs') + then have "es = map Val vs'" by(rule map_vals_of_spec) + then show ?thesis using evals_finals_same[OF _ SCallParamsThrow.hyps(1)] map_Val_nthrow_neq + by auto + qed +next + case (SCallNone ps s\<^sub>0 vs s\<^sub>2 C M) show ?case + proof(cases "map_vals_of ps") + case None + then have iconf: "iconfs (shp s\<^sub>0) ps" using SCallNone.prems(1) by simp + have bconf: "P,shp s\<^sub>0 \\<^sub>b (ps,b) \" using SCallNone.prems(2) None by simp + then have b1: "P \ \ps,s\<^sub>0,b\ [\]* \map Val vs,s\<^sub>2,False\" using SCallNone.hyps(2)[OF iconf] by auto + then show ?thesis using SCallRedsNone[OF b1 SCallNone.hyps(3)] SCallNone.hyps(1) by simp + next + case (Some vs') + then have ps: "ps = map Val vs'" by(rule map_vals_of_spec) + then have s\<^sub>0: "s\<^sub>0 = s\<^sub>2" using SCallNone.hyps(1) evals_finals_same by blast + then show ?thesis using RedSCallNone[OF SCallNone.hyps(3)] ps by(cases s\<^sub>2, auto) + qed +next + case (SCallNonStatic ps s\<^sub>0 vs s\<^sub>2 C M Ts T m D) show ?case + proof(cases "map_vals_of ps") + case None + then have iconf: "iconfs (shp s\<^sub>0) ps" using SCallNonStatic.prems(1) by simp + have bconf: "P,shp s\<^sub>0 \\<^sub>b (ps,b) \" using SCallNonStatic.prems(2) None by simp + then have b1: "P \ \ps,s\<^sub>0,b\ [\]* \map Val vs,s\<^sub>2,False\" using SCallNonStatic.hyps(2)[OF iconf] by auto + then show ?thesis using SCallRedsNonStatic[OF b1 SCallNonStatic.hyps(3)] SCallNonStatic.hyps(1) by simp + next + case (Some vs') + then have ps: "ps = map Val vs'" by(rule map_vals_of_spec) + then have s\<^sub>0: "s\<^sub>0 = s\<^sub>2" using SCallNonStatic.hyps(1) evals_finals_same by blast + then show ?thesis using RedSCallNonStatic[OF SCallNonStatic.hyps(3)] ps by(cases s\<^sub>2, auto) + qed +next + case (SCallInitThrow ps s\<^sub>0 vs h\<^sub>1 l\<^sub>1 sh\<^sub>1 C M Ts T pns body D a s') show ?case + proof(cases "map_vals_of ps") + case None + then have iconf: "iconfs (shp s\<^sub>0) ps" using SCallInitThrow.prems(1) by simp + have bconf: "P,shp s\<^sub>0 \\<^sub>b (ps,b) \" using SCallInitThrow.prems(2) None by simp + then have b1: "P \ \ps,s\<^sub>0,b\ [\]* \map Val vs,(h\<^sub>1, l\<^sub>1, sh\<^sub>1),False\" + using SCallInitThrow.hyps(2)[OF iconf] by auto + have bconf2: "P,shp (h\<^sub>1, l\<^sub>1, sh\<^sub>1) \\<^sub>b (INIT D ([D],False) \ unit,False) \" by(simp add: bconf_def) + then have b2: "P \ \INIT D ([D],False) \ unit,(h\<^sub>1, l\<^sub>1, sh\<^sub>1),False\ \* \throw a,s',False\" + using SCallInitThrow.hyps(7) by auto + then show ?thesis using SCallInitThrowReds[OF wwf b1 SCallInitThrow.hyps(3-5)] + by(cases s', auto) + next + case (Some vs') + have ps: "ps = map Val vs'" by(rule map_vals_of_spec[OF Some]) + then have vs: "vs = vs' \ s\<^sub>0 = (h\<^sub>1, l\<^sub>1, sh\<^sub>1)" + using evals_finals_same[OF _ SCallInitThrow.hyps(1)] map_Val_eq by auto + show ?thesis + proof(cases b) + case True + obtain sfs where shC: "sh\<^sub>1 D = \(sfs, Processing)\" + using SCallInitThrow.hyps(3,4) SCallInitThrow.prems(2) True Some vs + by(auto simp: bconf_def initPD_def dest: sees_method_fun) + then show ?thesis using init_ProcessingE[OF _ SCallInitThrow.hyps(6)] by blast + next + case False + then have b1: "P \ \ps,s\<^sub>0,b\ [\]* \map Val vs,(h\<^sub>1, l\<^sub>1, sh\<^sub>1),False\" using ps vs by simp + have bconf2: "P,shp (h\<^sub>1, l\<^sub>1, sh\<^sub>1) \\<^sub>b (INIT D ([D],False) \ unit,False) \" by(simp add: bconf_def) + then have b2: "P \ \INIT D ([D],False) \ unit,(h\<^sub>1, l\<^sub>1, sh\<^sub>1),False\ \* \throw a,s',False\" + using SCallInitThrow.hyps(7) by auto + then show ?thesis using SCallInitThrowReds[OF wwf b1 SCallInitThrow.hyps(3-5)] by(cases s', auto) + qed + qed +next + case (SCallInit ps s\<^sub>0 vs h\<^sub>1 l\<^sub>1 sh\<^sub>1 C M Ts T pns body D v' h\<^sub>2 l\<^sub>2 sh\<^sub>2 l\<^sub>2' e' h\<^sub>3 l\<^sub>3 sh\<^sub>3) show ?case + proof(cases "map_vals_of ps") + case None + then have iconf: "iconfs (shp s\<^sub>0) ps" using SCallInit.prems(1) by simp + have bconf: "P,shp s\<^sub>0 \\<^sub>b (ps,b) \" using SCallInit.prems(2) None by simp + then have b1: "P \ \ps,s\<^sub>0,b\ [\]* \map Val vs,(h\<^sub>1, l\<^sub>1, sh\<^sub>1),False\" + using SCallInit.hyps(2)[OF iconf] by auto + have bconf2: "P,shp (h\<^sub>1, l\<^sub>1, sh\<^sub>1) \\<^sub>b (INIT D ([D],False) \ unit,False) \" by(simp add: bconf_def) + then have b2: "P \ \INIT D ([D],False) \ unit,(h\<^sub>1, l\<^sub>1, sh\<^sub>1),False\ \* \Val v',(h\<^sub>2, l\<^sub>2, sh\<^sub>2),False\" + using SCallInit.hyps(7) by auto + have iconf3: "iconf (shp (h\<^sub>2, l\<^sub>2', sh\<^sub>2)) body" + by(rule nsub_RI_iconf[OF sees_wwf_nsub_RI[OF wwf SCallInit.hyps(3)]]) + have "P,shp (h\<^sub>2, l\<^sub>2', sh\<^sub>2) \\<^sub>b (body,False) \" by(simp add: bconf_def) + then have b3: "P \ \body,(h\<^sub>2, l\<^sub>2', sh\<^sub>2),False\ \* \e',(h\<^sub>3, l\<^sub>3, sh\<^sub>3),False\" + using SCallInit.hyps(11)[OF iconf3] by simp + show ?thesis by(rule SCallInitReds[OF wwf b1 SCallInit.hyps(3-5) b2 SCallInit.hyps(8-9) + b3 eval_final[OF SCallInit.hyps(10)]]) + next + case (Some vs') + then have ps: "ps = map Val vs'" by(rule map_vals_of_spec) + then have vs: "vs = vs' \ s\<^sub>0 = (h\<^sub>1, l\<^sub>1, sh\<^sub>1)" + using evals_finals_same[OF _ SCallInit.hyps(1)] map_Val_eq by auto + show ?thesis + proof(cases b) + case True + then have b1: "P \ \ps,s\<^sub>0,b\ [\]* \map Val vs,(h\<^sub>1, l\<^sub>1, sh\<^sub>1),b\" using ps vs by simp + obtain sfs where shC: "sh\<^sub>1 D = \(sfs, Processing)\" + using SCallInit.hyps(3,4) SCallInit.prems(2) True Some vs + by(auto simp: bconf_def initPD_def dest: sees_method_fun) + then have s': "(h\<^sub>1, l\<^sub>1, sh\<^sub>1) = (h\<^sub>2, l\<^sub>2, sh\<^sub>2)" using init_ProcessingE[OF _ SCallInit.hyps(6)] by simp + have iconf3: "iconf (shp (h\<^sub>2, l\<^sub>2', sh\<^sub>2)) body" + by(rule nsub_RI_iconf[OF sees_wwf_nsub_RI[OF wwf SCallInit.hyps(3)]]) + have "P,shp (h\<^sub>2, l\<^sub>2', sh\<^sub>2) \\<^sub>b (body,False) \" by(simp add: bconf_def) + then have b3: "P \ \body,(h\<^sub>2, l\<^sub>2', sh\<^sub>2),False\ \* \e',(h\<^sub>3, l\<^sub>3, sh\<^sub>3),False\" + using SCallInit.hyps(11)[OF iconf3] by simp + then have b3': "P \ \body,(h\<^sub>1, l\<^sub>2', sh\<^sub>1),False\ \* \e',(h\<^sub>3, l\<^sub>3, sh\<^sub>3),False\" + using s' by simp + then show ?thesis using SCallInitProcessingReds[OF wwf b1 SCallInit.hyps(3) shC + SCallInit.hyps(8-9) b3' eval_final[OF SCallInit.hyps(10)]] s' by simp + next + case False + then have b1: "P \ \ps,s\<^sub>0,b\ [\]* \map Val vs,(h\<^sub>1, l\<^sub>1, sh\<^sub>1),False\" using ps vs by simp + have bconf2: "P,shp (h\<^sub>1, l\<^sub>1, sh\<^sub>1) \\<^sub>b (INIT D ([D],False) \ unit,False) \" by(simp add: bconf_def) + then have b2: "P \ \INIT D ([D],False) \ unit,(h\<^sub>1, l\<^sub>1, sh\<^sub>1),False\ \* \Val v',(h\<^sub>2, l\<^sub>2, sh\<^sub>2),False\" + using SCallInit.hyps(7) by auto + have iconf3: "iconf (shp (h\<^sub>2, l\<^sub>2', sh\<^sub>2)) body" + by(rule nsub_RI_iconf[OF sees_wwf_nsub_RI[OF wwf SCallInit.hyps(3)]]) + have "P,shp (h\<^sub>2, l\<^sub>2', sh\<^sub>2) \\<^sub>b (body,False) \" by(simp add: bconf_def) + then have b3: "P \ \body,(h\<^sub>2, l\<^sub>2', sh\<^sub>2),False\ \* \e',(h\<^sub>3, l\<^sub>3, sh\<^sub>3),False\" + using SCallInit.hyps(11)[OF iconf3] by simp + show ?thesis by(rule SCallInitReds[OF wwf b1 SCallInit.hyps(3-5) b2 SCallInit.hyps(8-9) + b3 eval_final[OF SCallInit.hyps(10)]]) + qed + qed +next + case (SCall ps s\<^sub>0 vs h\<^sub>2 l\<^sub>2 sh\<^sub>2 C M Ts T pns body D sfs l\<^sub>2' e' h\<^sub>3 l\<^sub>3 sh\<^sub>3) show ?case + proof(cases "map_vals_of ps") + case None + then have iconf: "iconfs (shp s\<^sub>0) ps" using SCall.prems(1) by simp + have bconf: "P,shp s\<^sub>0 \\<^sub>b (ps,b) \" using SCall.prems(2) None by simp + then have b1: "P \ \ps,s\<^sub>0,b\ [\]* \map Val vs,(h\<^sub>2, l\<^sub>2, sh\<^sub>2),False\" + using SCall.hyps(2)[OF iconf] by auto + have iconf3: "iconf (shp (h\<^sub>2, l\<^sub>2', sh\<^sub>2)) body" + by(rule nsub_RI_iconf[OF sees_wwf_nsub_RI[OF wwf SCall.hyps(3)]]) + have "P,shp (h\<^sub>2, l\<^sub>2', sh\<^sub>2) \\<^sub>b (body,False) \" by(simp add: bconf_def) + then have b2: "P \ \body,(h\<^sub>2, l\<^sub>2', sh\<^sub>2),False\ \* \e',(h\<^sub>3, l\<^sub>3, sh\<^sub>3),False\" + using SCall.hyps(8)[OF iconf3] by simp + show ?thesis by(rule SCallRedsFinal[OF wwf b1 SCall.hyps(3-6) b2 eval_final[OF SCall.hyps(7)]]) + next + case (Some vs') + then have ps: "ps = map Val vs'" by(rule map_vals_of_spec) + then have vs: "vs = vs' \ s\<^sub>0 = (h\<^sub>2, l\<^sub>2, sh\<^sub>2)" + using evals_finals_same[OF _ SCall.hyps(1)] map_Val_eq by auto + then have b1: "P \ \ps,s\<^sub>0,b\ [\]* \map Val vs,(h\<^sub>2, l\<^sub>2, sh\<^sub>2),b\" using ps by simp + have iconf3: "iconf (shp (h\<^sub>2, l\<^sub>2', sh\<^sub>2)) body" + by(rule nsub_RI_iconf[OF sees_wwf_nsub_RI[OF wwf SCall.hyps(3)]]) + have "P,shp (h\<^sub>2, l\<^sub>2', sh\<^sub>2) \\<^sub>b (body,False) \" by(simp add: bconf_def) + then have b2: "P \ \body,(h\<^sub>2, l\<^sub>2', sh\<^sub>2),False\ \* \e',(h\<^sub>3, l\<^sub>3, sh\<^sub>3),False\" + using SCall.hyps(8)[OF iconf3] by simp + show ?thesis by(rule SCallRedsFinal[OF wwf b1 SCall.hyps(3-6) b2 eval_final[OF SCall.hyps(7)]]) + qed +next + case (Block e\<^sub>0 h\<^sub>0 l\<^sub>0 V sh\<^sub>0 e\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1 T) + have iconf: "iconf (shp (h\<^sub>0, l\<^sub>0(V := None), sh\<^sub>0)) e\<^sub>0" + using Block.prems(1) by (auto simp: assigned_def) + have bconf: "P,shp (h\<^sub>0, l\<^sub>0(V := None), sh\<^sub>0) \\<^sub>b (e\<^sub>0,b) \" using Block.prems(2) + by(auto simp: bconf_def) + then have b': "P \ \e\<^sub>0,(h\<^sub>0, l\<^sub>0(V := None), sh\<^sub>0),b\ \* \e\<^sub>1,(h\<^sub>1, l\<^sub>1, sh\<^sub>1),False\" + using Block.hyps(2)[OF iconf] by auto + have fin: "final e\<^sub>1" using Block by(auto dest: eval_final) + thus ?case using BlockRedsFinal[OF b' fin] by simp +next + case (Seq e\<^sub>0 s\<^sub>0 v s\<^sub>1 e\<^sub>1 e\<^sub>2 s\<^sub>2) + then have iconf: "iconf (shp s\<^sub>0) e\<^sub>0" using Seq.prems(1) + by(auto dest: val_of_spec lass_val_of_spec) + have b1: "\b1. P \ \e\<^sub>0,s\<^sub>0,b\ \* \Val v,s\<^sub>1,b1\" + proof(cases "val_of e\<^sub>0") + case None show ?thesis + proof(cases "lass_val_of e\<^sub>0") + case lNone:None + then have bconf: "P,shp s\<^sub>0 \\<^sub>b (e\<^sub>0,b) \" using Seq.prems(2) None by simp + then have "P \ \e\<^sub>0,s\<^sub>0,b\ \* \Val v,s\<^sub>1,False\" using iconf Seq.hyps(2) by auto + then show ?thesis by fast + next + case (Some p) + obtain V' v' where p: "p = (V',v')" and e\<^sub>0: "e\<^sub>0 = V':=Val v'" + using lass_val_of_spec[OF Some] by(cases p, auto) + obtain h l sh h' l' sh' where s\<^sub>0: "s\<^sub>0 = (h,l,sh)" and s\<^sub>1: "s\<^sub>1 = (h',l',sh')" by(cases s\<^sub>0, cases s\<^sub>1) + then have eval: "P \ \e\<^sub>0,(h,l,sh)\ \ \Val v,(h',l',sh')\" using Seq.hyps(1) by simp + then have s\<^sub>1': "Val v = unit \ h' = h \ l' = l(V' \ v') \ sh' = sh" + using lass_val_of_eval[OF Some eval] p e\<^sub>0 by simp + then have "P \ \e\<^sub>0,s\<^sub>0,b\ \ \Val v,s\<^sub>1,b\" using e\<^sub>0 s\<^sub>0 s\<^sub>1 by(auto intro: RedLAss) + then show ?thesis by auto + qed + next + case (Some a) + then have "e\<^sub>0 = Val v" and "s\<^sub>0 = s\<^sub>1" using Seq.hyps(1) eval_cases(3) val_of_spec by blast+ + then show ?thesis using Seq by auto + qed + then obtain b1 where b1': "P \ \e\<^sub>0,s\<^sub>0,b\ \* \Val v,s\<^sub>1,b1\" by clarsimp + have seq: "P \ \e\<^sub>0;;e\<^sub>1,s\<^sub>0,b\ \* \Val v;;e\<^sub>1,s\<^sub>1,b1\" by(rule SeqReds[OF b1']) + then have iconf2: "iconf (shp s\<^sub>1) e\<^sub>1" using Red_preserves_iconf[OF wwf seq] Seq nsub_RI_iconf + by auto + have "P,shp s\<^sub>1 \\<^sub>b (Val v;; e\<^sub>1,b1) \" by(rule Red_preserves_bconf[OF wwf seq Seq.prems]) + then have bconf2: "P,shp s\<^sub>1 \\<^sub>b (e\<^sub>1,b1) \" by simp + have b2: "P \ \e\<^sub>1,s\<^sub>1,b1\ \* \e\<^sub>2,s\<^sub>2,False\" by(rule Seq.hyps(4)[OF iconf2 bconf2]) + then show ?case using SeqReds2[OF b1' b2] by fast +next + case (SeqThrow e\<^sub>0 s\<^sub>0 a s\<^sub>1 e\<^sub>1 b) + have notVal: "val_of e\<^sub>0 = None" "lass_val_of e\<^sub>0 = None" + using SeqThrow.hyps(1) eval_throw_nonVal eval_throw_nonLAss by auto + thus ?case using SeqThrow notVal by(auto dest!:eval_final dest: SeqRedsThrow) +next + case (CondT e s\<^sub>0 s\<^sub>1 e\<^sub>1 e' s\<^sub>2 e\<^sub>2) + then have iconf: "iconf (shp s\<^sub>0) e" using CondT.prems(1) by auto + have bconf: "P,shp s\<^sub>0 \\<^sub>b (e,b) \" using CondT.prems(2) by auto + then have b1: "P \ \e,s\<^sub>0,b\ \* \true,s\<^sub>1,False\" using iconf CondT.hyps(2) by auto + have cond: "P \ \if (e) e\<^sub>1 else e\<^sub>2,s\<^sub>0,b\ \* \if (true) e\<^sub>1 else e\<^sub>2,s\<^sub>1,False\" by(rule CondReds[OF b1]) + then have iconf2': "iconf (shp s\<^sub>1) e\<^sub>1" using Red_preserves_iconf[OF wwf cond] CondT nsub_RI_iconf + by auto + have "P,shp s\<^sub>1 \\<^sub>b (e\<^sub>1,False) \" by(simp add: bconf_def) + then have b2: "P \ \e\<^sub>1,s\<^sub>1,False\ \* \e',s\<^sub>2,False\" using CondT.hyps(4)[OF iconf2'] by auto + then show ?case using CondReds2T[OF b1 b2] by fast +next + case (CondF e s\<^sub>0 s\<^sub>1 e\<^sub>2 e' s\<^sub>2 e\<^sub>1) + then have iconf: "iconf (shp s\<^sub>0) e" using CondF.prems(1) by auto + have bconf: "P,shp s\<^sub>0 \\<^sub>b (e,b) \" using CondF.prems(2) by auto + then have b1: "P \ \e,s\<^sub>0,b\ \* \false,s\<^sub>1,False\" using iconf CondF.hyps(2) by auto + have cond: "P \ \if (e) e\<^sub>1 else e\<^sub>2,s\<^sub>0,b\ \* \if (false) e\<^sub>1 else e\<^sub>2,s\<^sub>1,False\" by(rule CondReds[OF b1]) + then have iconf2': "iconf (shp s\<^sub>1) e\<^sub>2" using Red_preserves_iconf[OF wwf cond] CondF nsub_RI_iconf + by auto + have "P,shp s\<^sub>1 \\<^sub>b (e\<^sub>2,False) \" by(simp add: bconf_def) + then have b2: "P \ \e\<^sub>2,s\<^sub>1,False\ \* \e',s\<^sub>2,False\" using CondF.hyps(4)[OF iconf2'] by auto + then show ?case using CondReds2F[OF b1 b2] by fast +next + case CondThrow thus ?case by(auto dest!:eval_final dest:CondRedsThrow) +next + case (WhileF e s\<^sub>0 s\<^sub>1 c) + then have iconf: "iconf (shp s\<^sub>0) e" using nsub_RI_iconf by auto + then have bconf: "P,shp s\<^sub>0 \\<^sub>b (e,b) \" using WhileF.prems(2) by(simp add: bconf_def) + then have b': "P \ \e,s\<^sub>0,b\ \* \false,s\<^sub>1,False\" using WhileF.hyps(2) iconf by auto + thus ?case using WhileFReds[OF b'] by fast +next + case (WhileT e s\<^sub>0 s\<^sub>1 c v\<^sub>1 s\<^sub>2 e\<^sub>3 s\<^sub>3) + then have iconf: "iconf (shp s\<^sub>0) e" using nsub_RI_iconf by auto + then have bconf: "P,shp s\<^sub>0 \\<^sub>b (e,b) \" using WhileT.prems(2) by(simp add: bconf_def) + then have b1: "P \ \e,s\<^sub>0,b\ \* \true,s\<^sub>1,False\" using WhileT.hyps(2) iconf by auto + have iconf2: "iconf (shp s\<^sub>1) c" using WhileT.prems(1) nsub_RI_iconf by auto + have bconf2: "P,shp s\<^sub>1 \\<^sub>b (c,False) \" by(simp add: bconf_def) + then have b2: "P \ \c,s\<^sub>1,False\ \* \Val v\<^sub>1,s\<^sub>2,False\" using WhileT.hyps(4) iconf2 by auto + have iconf3: "iconf (shp s\<^sub>2) (while (e) c)" using WhileT.prems(1) by auto + have "P,shp s\<^sub>2 \\<^sub>b (while (e) c,False) \" by(simp add: bconf_def) + then have b3: "P \ \while (e) c,s\<^sub>2,False\ \* \e\<^sub>3,s\<^sub>3,False\" using WhileT.hyps(6) iconf3 by auto + show ?case using WhileTReds[OF b1 b2 b3] by fast +next + case WhileCondThrow thus ?case + by (metis (no_types, lifting) WhileRedsThrow iconf.simps(16) bconf_While bconf_def nsub_RI_iconf) +next + case (WhileBodyThrow e s\<^sub>0 s\<^sub>1 c e' s\<^sub>2) + then have iconf: "iconf (shp s\<^sub>0) e" using nsub_RI_iconf by auto + then have bconf: "P,shp s\<^sub>0 \\<^sub>b (e,b) \" using WhileBodyThrow.prems(2) by(simp add: bconf_def) + then have b1: "P \ \e,s\<^sub>0,b\ \* \true,s\<^sub>1,False\" using WhileBodyThrow.hyps(2) iconf by auto + have iconf2: "iconf (shp s\<^sub>1) c" using WhileBodyThrow.prems(1) nsub_RI_iconf by auto + have bconf2: "P,shp s\<^sub>1 \\<^sub>b (c,False) \" by(simp add: bconf_def) + then have b2: "P \ \c,s\<^sub>1,False\ \* \throw e',s\<^sub>2,False\" using WhileBodyThrow.hyps(4) iconf2 by auto + show ?case using WhileTRedsThrow[OF b1 b2] by fast +next + case Throw thus ?case by (meson ThrowReds iconf.simps(17) bconf_Throw) +next + case ThrowNull thus ?case by (meson ThrowRedsNull iconf.simps(17) bconf_Throw) +next + case ThrowThrow thus ?case by (meson ThrowRedsThrow iconf.simps(17) bconf_Throw) +next + case Try thus ?case by (meson TryRedsVal iconf.simps(18) bconf_Try) +next + case (TryCatch e\<^sub>1 s\<^sub>0 a h\<^sub>1 l\<^sub>1 sh\<^sub>1 D fs C e\<^sub>2 V e\<^sub>2' h\<^sub>2 l\<^sub>2 sh\<^sub>2) + then have b1: "P \ \e\<^sub>1,s\<^sub>0,b\ \* \Throw a,(h\<^sub>1, l\<^sub>1, sh\<^sub>1),False\" by auto + have Try: "P \ \try e\<^sub>1 catch(C V) e\<^sub>2,s\<^sub>0,b\ \* \try (Throw a) catch(C V) e\<^sub>2,(h\<^sub>1, l\<^sub>1, sh\<^sub>1),False\" + by(rule TryReds[OF b1]) + have iconf: "iconf sh\<^sub>1 e\<^sub>2" using Red_preserves_iconf[OF wwf Try] TryCatch nsub_RI_iconf + by auto + have bconf: "P,shp (h\<^sub>1, l\<^sub>1(V \ Addr a), sh\<^sub>1) \\<^sub>b (e\<^sub>2,False) \" by(simp add: bconf_def) + then have b2: "P \ \e\<^sub>2,(h\<^sub>1, l\<^sub>1(V \ Addr a), sh\<^sub>1),False\ \* \e\<^sub>2',(h\<^sub>2, l\<^sub>2, sh\<^sub>2),False\" + using TryCatch.hyps(6) iconf by auto + thus ?case using TryCatchRedsFinal[OF b1] TryCatch.hyps(3-5) by (meson eval_final) +next + case TryThrow thus ?case by (meson TryRedsFail iconf.simps(18) bconf_Try) +next + case Nil thus ?case by(auto simp: bconfs_def) +next + case (Cons e s\<^sub>0 v s\<^sub>1 es es' s\<^sub>2) show ?case + proof(cases "val_of e") + case None + then have iconf: "iconf (shp s\<^sub>0) e" using Cons.prems(1) by simp + have bconf: "P,shp s\<^sub>0 \\<^sub>b (e,b) \" using Cons.prems(2) None by simp + then have b1: "P \ \e,s\<^sub>0,b\ \* \Val v,s\<^sub>1,False\" using Cons.hyps(2) iconf by auto + have cons: "P \ \e # es,s\<^sub>0,b\ [\]* \Val v # es,s\<^sub>1,False\" by(rule ListReds1[OF b1]) + then have iconf2': "iconfs (shp s\<^sub>1) es" using Reds_preserves_iconf[OF wwf cons] None Cons by auto + have "P,shp s\<^sub>1 \\<^sub>b (es,False) \" by(simp add: bconfs_def) + then have b2: "P \ \es,s\<^sub>1,False\ [\]* \es',s\<^sub>2,False\" using Cons.hyps(4)[OF iconf2'] by auto + show ?thesis using ListRedsVal[OF b1 b2] by auto + next + case (Some a) + then obtain b1 where b1: "P \ \e,s\<^sub>0,b\ \* \Val v,s\<^sub>1,b1\" + by (metis (no_types, lifting) Cons.hyps(1) eval_cases(3) rtrancl.rtrancl_refl val_of_spec) + have cons: "P \ \e # es,s\<^sub>0,b\ [\]* \Val v # es,s\<^sub>1,b1\" by(rule ListReds1[OF b1]) + then have iconf2': "iconfs (shp s\<^sub>1) es" using Reds_preserves_iconf[OF wwf cons] Cons by auto + have bconf2: "P,shp s\<^sub>0 \\<^sub>b (es,b) \" using Cons.prems Some by simp + then have "P,shp s\<^sub>1 \\<^sub>b (es,b1) \" using Reds_preserves_bconf[OF wwf cons Cons.prems] by simp + then have b2: "P \ \es,s\<^sub>1,b1\ [\]* \es',s\<^sub>2,False\" using Cons.hyps(4)[OF iconf2'] by auto + show ?thesis using ListRedsVal[OF b1 b2] by auto + qed +next + case (ConsThrow e s\<^sub>0 e' s\<^sub>1 es) show ?case + proof(cases "val_of e") + case None + then have iconf: "iconf (shp s\<^sub>0) e" using ConsThrow.prems(1) by simp + have bconf: "P,shp s\<^sub>0 \\<^sub>b (e,b) \" using ConsThrow.prems(2) None by simp + then have b1: "P \ \e,s\<^sub>0,b\ \* \throw e',s\<^sub>1,False\" using ConsThrow.hyps(2) iconf by auto + have cons: "P \ \e # es,s\<^sub>0,b\ [\]* \throw e' # es,s\<^sub>1,False\" by(rule ListReds1[OF b1]) + then show ?thesis by fast + next + case (Some a) + then show ?thesis using eval_final_same[OF ConsThrow.hyps(1)] val_of_spec[OF Some] by auto + qed +next + case (InitFinal e s e' s' C b') + then have "\sub_RI e" by simp + then show ?case using InitFinal RedInit[of e C b' s b P] + by (meson converse_rtrancl_into_rtrancl nsub_RI_iconf red_preserves_bconf RedInit) +next + case (InitNone sh C C' Cs e h l e' s') + then have init: "P \ \INIT C' (C # Cs,False) \ e,(h, l, sh(C \ (sblank P C, Prepared))),b\ \* \e',s',False\" + by(simp add: bconf_def) + show ?case by(rule InitNoneReds[OF InitNone.hyps(1) init]) +next + case (InitDone sh C sfs C' Cs e h l e' s') + then have "iconf (shp (h, l, sh)) (INIT C' (Cs,True) \ e)" using InitDone.hyps(1) + proof(cases Cs) + case Nil + then have "C = C'" "\sub_RI e" using InitDone.prems(1) by simp+ + then show ?thesis using Nil InitDone.hyps(1) by(simp add: initPD_def) + qed(auto) + then have init: "P \ \INIT C' (Cs,True) \ e,(h, l, sh),b\ \* \e',s',False\" + using InitDone by(simp add: bconf_def) + show ?case by(rule InitDoneReds[OF InitDone.hyps(1) init]) +next + case (InitProcessing sh C sfs C' Cs e h l e' s') + then have "iconf (shp (h, l, sh)) (INIT C' (Cs,True) \ e)" using InitProcessing.hyps(1) + proof(cases Cs) + case Nil + then have "C = C'" "\sub_RI e" using InitProcessing.prems(1) by simp+ + then show ?thesis using Nil InitProcessing.hyps(1) by(simp add: initPD_def) + qed(auto) + then have init: "P \ \INIT C' (Cs,True) \ e,(h, l, sh),b\ \* \e',s',False\" + using InitProcessing by(simp add: bconf_def) + show ?case by(rule InitProcessingReds[OF InitProcessing.hyps(1) init]) +next + case InitError thus ?case by(fastforce intro: InitErrorReds simp: bconf_def) +next + case InitObject thus ?case by(fastforce intro: InitObjectReds simp: bconf_def) +next + case InitNonObject thus ?case by(fastforce intro: InitNonObjectReds simp: bconf_def) +next + case InitRInit thus ?case by(fastforce intro: RedsInitRInit simp: bconf_def) +next + case (RInit e s v h' l' sh' C sfs i sh'' C' Cs e' e\<^sub>1 s\<^sub>1) + then have iconf2: "iconf (shp (h', l', sh'')) (INIT C' (Cs,True) \ e')" + by(auto simp: initPD_def fun_upd_same list_nonempty_induct) + show ?case + proof(cases "val_of e") + case None + then have iconf: "iconf (shp s) e" using RInit.prems(1) by simp + have bconf: "P,shp s \\<^sub>b (e,b) \" using RInit.prems(2) None by simp + then have b1: "P \ \e,s,b\ \* \Val v,(h',l',sh'),False\" using RInit.hyps(2)[OF iconf] by auto + have "P,shp (h', l', sh'') \\<^sub>b (INIT C' (Cs,True) \ e',False) \" by(simp add: bconf_def) + then have b2: "P \ \INIT C' (Cs,True) \ e',(h',l',sh''),False\ \* \e\<^sub>1,s\<^sub>1,False\" + using RInit.hyps(7)[OF iconf2] by auto + then show ?thesis using RedsRInit[OF b1 RInit.hyps(3-5) b2] by fast + next + case (Some a') + then obtain b1 where b1: "P \ \e,s,b\ \* \Val v,(h',l',sh'),b1\" + by (metis (no_types, lifting) RInit.hyps(1) eval_cases(3) rtrancl.rtrancl_refl val_of_spec) + have fin: "final e" by(simp add: val_of_spec[OF Some]) + have "\b" using RInit.prems(2) Some by(simp add: bconf_def) + then have nb1: "\b1" using reds_final_same[OF b1 fin] by simp + have "P,shp (h', l', sh'') \\<^sub>b (INIT C' (Cs,True) \ e',b1) \" using nb1 + by(simp add: bconf_def) + then have b2: "P \ \INIT C' (Cs,True) \ e',(h', l', sh''),b1\ \* \e\<^sub>1,s\<^sub>1,False\" + using RInit.hyps(7)[OF iconf2] by auto + then show ?thesis using RedsRInit[OF b1 RInit.hyps(3-5) b2] by fast + qed +next + case (RInitInitFail e s a h' l' sh' C sfs i sh'' D Cs e' e\<^sub>1 s\<^sub>1) + have fin: "final (throw a)" using eval_final[OF RInitInitFail.hyps(1)] by simp + then obtain a' where a': "throw a = Throw a'" by auto + have iconf2: "iconf (shp (h', l', sh'')) (RI (D,Throw a') ; Cs \ e')" + using RInitInitFail.prems(1) by auto + show ?case + proof(cases "val_of e") + case None + then have iconf: "iconf (shp s) e" using RInitInitFail.prems(1) by simp + have bconf: "P,shp s \\<^sub>b (e,b) \" using RInitInitFail.prems(2) None by simp + then have b1: "P \ \e,s,b\ \* \Throw a',(h',l',sh'),False\" + using RInitInitFail.hyps(2)[OF iconf] a' by auto + have "P,shp (h', l', sh'') \\<^sub>b (RI (D,Throw a') ; Cs \ e',False) \" by(simp add: bconf_def) + then have b2: "P \ \RI (D,Throw a') ; Cs \ e',(h',l',sh''),False\ \* \e\<^sub>1,s\<^sub>1,False\" + using RInitInitFail.hyps(6) iconf2 a' by auto + show ?thesis using RInitInitThrowReds[OF b1 RInitInitFail.hyps(3-4) b2] by fast + next + case (Some a1) + then obtain b1 where b1: "P \ \e,s,b\ \* \Throw a',(h',l',sh'),b1\" using a' + by (metis (no_types, lifting) RInitInitFail.hyps(1) eval_cases(3) rtrancl.rtrancl_refl val_of_spec) + have fin: "final e" by(simp add: val_of_spec[OF Some]) + have "\b" using RInitInitFail.prems(2) Some by(simp add: bconf_def) + then have nb1: "\b1" using reds_final_same[OF b1 fin] by simp + have "P,shp (h', l', sh'') \\<^sub>b (RI (D,Throw a') ; Cs \ e',b1) \" using nb1 + by(simp add: bconf_def) + then have b2: "P \ \RI (D,Throw a') ; Cs \ e',(h', l', sh''),b1\ \* \e\<^sub>1,s\<^sub>1,False\" + using RInitInitFail.hyps(6) iconf2 a' by auto + show ?thesis using RInitInitThrowReds[OF b1 RInitInitFail.hyps(3-4) b2] by fast + qed +next + case (RInitFailFinal e s a h' l' sh' C sfs i sh'' e') + have fin: "final (throw a)" using eval_final[OF RInitFailFinal.hyps(1)] by simp + then obtain a' where a': "throw a = Throw a'" by auto + show ?case + proof(cases "val_of e") + case None + then have iconf: "iconf (shp s) e" using RInitFailFinal.prems(1) by simp + have bconf: "P,shp s \\<^sub>b (e,b) \" using RInitFailFinal.prems(2) None by simp + then have b1: "P \ \e,s,b\ \* \Throw a',(h',l',sh'),False\" + using RInitFailFinal.hyps(2)[OF iconf] a' by auto + show ?thesis using RInitThrowReds[OF b1 RInitFailFinal.hyps(3-4)] a' by fast + next + case (Some a1) + then show ?thesis using eval_final_same[OF RInitFailFinal.hyps(1)] val_of_spec[OF Some] by auto + qed +qed +(*>*) + + +subsection\Big steps simulates small step\ + +text\ This direction was carried out by Norbert Schirmer and Daniel +Wasserrab (and modified to include statics and DCI by Susannah Mansky). \ + +text \ The big step equivalent of @{text RedWhile}: \ + +lemma unfold_while: + "P \ \while(b) c,s\ \ \e',s'\ = P \ \if(b) (c;;while(b) c) else (unit),s\ \ \e',s'\" +(*<*) +proof + assume "P \ \while (b) c,s\ \ \e',s'\" + thus "P \ \if (b) (c;; while (b) c) else unit,s\ \ \e',s'\" + by cases (fastforce intro: eval_evals.intros)+ +next + assume "P \ \if (b) (c;; while (b) c) else unit,s\ \ \e',s'\" + thus "P \ \while (b) c,s\ \ \e',s'\" + proof (cases) + fix a + assume e': "e' = throw a" + assume "P \ \b,s\ \ \throw a,s'\" + hence "P \ \while(b) c,s\ \ \throw a,s'\" by (rule WhileCondThrow) + with e' show ?thesis by simp + next + fix s\<^sub>1 + assume eval_false: "P \ \b,s\ \ \false,s\<^sub>1\" + and eval_unit: "P \ \unit,s\<^sub>1\ \ \e',s'\" + with eval_unit have "s' = s\<^sub>1" "e' = unit" by (auto elim: eval_cases) + moreover from eval_false have "P \ \while (b) c,s\ \ \unit,s\<^sub>1\" + by - (rule WhileF, simp) + ultimately show ?thesis by simp + next + fix s\<^sub>1 + assume eval_true: "P \ \b,s\ \ \true,s\<^sub>1\" + and eval_rest: "P \ \c;; while (b) c,s\<^sub>1\\\e',s'\" + from eval_rest show ?thesis + proof (cases) + fix s\<^sub>2 v\<^sub>1 + assume "P \ \c,s\<^sub>1\ \ \Val v\<^sub>1,s\<^sub>2\" "P \ \while (b) c,s\<^sub>2\ \ \e',s'\" + with eval_true show "P \ \while(b) c,s\ \ \e',s'\" by (rule WhileT) + next + fix a + assume "P \ \c,s\<^sub>1\ \ \throw a,s'\" "e' = throw a" + with eval_true show "P \ \while(b) c,s\ \ \e',s'\" + by (iprover intro: WhileBodyThrow) + qed + qed +qed +(*>*) + + +lemma blocksEval: + "\Ts vs l l'. \size ps = size Ts; size ps = size vs; P \ \blocks(ps,Ts,vs,e),(h,l,sh)\ \ \e',(h',l',sh')\ \ + \ \ l''. P \ \e,(h,l(ps[\]vs),sh)\ \ \e',(h',l'',sh')\" +(*<*) +proof (induct ps) + case Nil then show ?case by fastforce +next + case (Cons p ps') + have length_eqs: "length (p # ps') = length Ts" + "length (p # ps') = length vs" by fact+ + then obtain T Ts' where Ts: "Ts = T#Ts'" by (cases "Ts") simp + obtain v vs' where vs: "vs = v#vs'" using length_eqs by (cases "vs") simp + have "P \ \blocks (p # ps', Ts, vs, e),(h,l,sh)\ \ \e',(h', l',sh')\" by fact + with Ts vs + have "P \ \{p:T := Val v; blocks (ps', Ts', vs', e)},(h,l,sh)\ \ \e',(h', l',sh')\" + by simp + then obtain l''' where + eval_ps': "P \ \blocks (ps', Ts', vs', e),(h, l(p\v), sh)\ \ \e',(h', l''', sh')\" + and l''': "l'=l'''(p:=l p)" + by (auto elim!: eval_cases) + then obtain l'' where + hyp: "P \ \e,(h, l(p\v)(ps'[\]vs'), sh)\ \ \e',(h', l'', sh')\" + using length_eqs Ts vs Cons.hyps [OF _ _ eval_ps'] by auto + from hyp + show "\l''. P \ \e,(h, l(p # ps'[\]vs), sh)\ \ \e',(h', l'', sh')\" + using Ts vs by auto +qed +(*>*) + +lemma +assumes wf: "wwf_J_prog P" +shows eval_restrict_lcl: + "P \ \e,(h,l,sh)\ \ \e',(h',l',sh')\ \ (\W. fv e \ W \ P \ \e,(h,l|`W,sh)\ \ \e',(h',l'|`W,sh')\)" +and "P \ \es,(h,l,sh)\ [\] \es',(h',l',sh')\ \ (\W. fvs es \ W \ P \ \es,(h,l|`W,sh)\ [\] \es',(h',l'|`W,sh')\)" +(*<*) +proof(induct rule:eval_evals_inducts) + case (Block e\<^sub>0 h\<^sub>0 l\<^sub>0 V sh\<^sub>0 e\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1 T) + have IH: "\W. fv e\<^sub>0 \ W \ P \ \e\<^sub>0,(h\<^sub>0,l\<^sub>0(V:=None)|`W,sh\<^sub>0)\ \ \e\<^sub>1,(h\<^sub>1,l\<^sub>1|`W,sh\<^sub>1)\" by fact + have "fv({V:T; e\<^sub>0}) \ W" by fact+ + hence "fv e\<^sub>0 - {V} \ W" by simp_all + hence "fv e\<^sub>0 \ insert V W" by fast + from IH[OF this] + have "P \ \e\<^sub>0,(h\<^sub>0, (l\<^sub>0|`W)(V := None), sh\<^sub>0)\ \ \e\<^sub>1,(h\<^sub>1, l\<^sub>1|`insert V W, sh\<^sub>1)\" + by fastforce + from eval_evals.Block[OF this] show ?case by fastforce +next + case Seq thus ?case by simp (blast intro:eval_evals.Seq) +next + case New thus ?case by(simp add:eval_evals.intros) +next + case NewFail thus ?case by(simp add:eval_evals.intros) +next + case (NewInit sh C h l v' h' l' sh' a h'') + have "fv(INIT C ([C],False) \ unit) \ W" by simp + then have "P \ \INIT C ([C],False) \ unit,(h, l |` W, sh)\ \ \Val v',(h', l' |` W, sh')\" + by (simp add: NewInit.hyps(3)) + thus ?case using NewInit.hyps(1,4-6) eval_evals.NewInit by blast +next + case (NewInitOOM sh C h l v' h' l' sh') + have "fv(INIT C ([C],False) \ unit) \ W" by simp + then have "P \ \INIT C ([C],False) \ unit,(h, l |` W, sh)\ \ \Val v',(h', l' |` W, sh')\" + by (simp add: NewInitOOM.hyps(3)) + thus ?case + using NewInitOOM.hyps(1,4,5) eval_evals.NewInitOOM by auto +next + case NewInitThrow thus ?case by(simp add:eval_evals.intros) +next + case Cast thus ?case by simp (blast intro:eval_evals.Cast) +next + case CastNull thus ?case by simp (blast intro:eval_evals.CastNull) +next + case CastFail thus ?case by simp (blast intro:eval_evals.CastFail) +next + case CastThrow thus ?case by(simp add:eval_evals.intros) +next + case Val thus ?case by(simp add:eval_evals.intros) +next + case BinOp thus ?case by simp (blast intro:eval_evals.BinOp) +next + case BinOpThrow1 thus ?case by simp (blast intro:eval_evals.BinOpThrow1) +next + case BinOpThrow2 thus ?case by simp (blast intro:eval_evals.BinOpThrow2) +next + case Var thus ?case by(simp add:eval_evals.intros) +next + case (LAss e h\<^sub>0 l\<^sub>0 sh\<^sub>0 v h l sh l' V) + have IH: "\W. fv e \ W \ P \ \e,(h\<^sub>0,l\<^sub>0|`W,sh\<^sub>0)\ \ \Val v,(h,l|`W,sh)\" + and [simp]: "l' = l(V \ v)" by fact+ + have "fv (V:=e) \ W" by fact + hence fv: "fv e \ W" and VinW: "V \ W" by auto + from eval_evals.LAss[OF IH[OF fv] refl, of V] VinW + show ?case by simp +next + case LAssThrow thus ?case by(fastforce intro: eval_evals.LAssThrow) +next + case FAcc thus ?case by simp (blast intro: eval_evals.FAcc) +next + case FAccNull thus ?case by(fastforce intro: eval_evals.FAccNull) +next + case FAccThrow thus ?case by(fastforce intro: eval_evals.FAccThrow) +next + case FAccNone thus ?case by(metis eval_evals.FAccNone fv.simps(7)) +next + case FAccStatic thus ?case by(metis eval_evals.FAccStatic fv.simps(7)) +next + case SFAcc thus ?case by simp (blast intro: eval_evals.SFAcc) +next + case SFAccInit thus ?case by simp (blast intro: eval_evals.SFAccInit) +next + case SFAccInitThrow thus ?case by simp (blast intro: eval_evals.SFAccInitThrow) +next + case SFAccNone thus ?case by simp (blast intro: eval_evals.SFAccNone) +next + case SFAccNonStatic thus ?case by simp (blast intro: eval_evals.SFAccNonStatic) +next + case FAss thus ?case by simp (blast intro: eval_evals.FAss) +next + case FAssNull thus ?case by simp (blast intro: eval_evals.FAssNull) +next + case FAssThrow1 thus ?case by simp (blast intro: eval_evals.FAssThrow1) +next + case FAssThrow2 thus ?case by simp (blast intro: eval_evals.FAssThrow2) +next + case FAssNone thus ?case by simp (blast intro: eval_evals.FAssNone) +next + case FAssStatic thus ?case by simp (blast intro: eval_evals.FAssStatic) +next + case SFAss thus ?case by simp (blast intro: eval_evals.SFAss) +next + case SFAssInit thus ?case by simp (blast intro: eval_evals.SFAssInit) +next + case SFAssInitThrow thus ?case by simp (blast intro: eval_evals.SFAssInitThrow) +next + case SFAssThrow thus ?case by simp (blast intro: eval_evals.SFAssThrow) +next + case SFAssNone thus ?case by simp (blast intro: eval_evals.SFAssNone) +next + case SFAssNonStatic thus ?case by simp (blast intro: eval_evals.SFAssNonStatic) +next + case CallObjThrow thus ?case by simp (blast intro: eval_evals.intros) +next + case CallNull thus ?case by simp (blast intro: eval_evals.CallNull) +next + case (CallNone e h l sh a h' l' sh' ps vs h\<^sub>2 l\<^sub>2 sh\<^sub>2 C fs M) + have f1: "P \ \e,(h, l |` W, sh)\ \ \addr a,(h', l' |` W, sh')\" + by (metis (no_types) fv.simps(11) le_sup_iff local.CallNone(2) local.CallNone(7)) + have "P \ \ps,(h', l' |` W, sh')\ [\] \map Val vs, (h\<^sub>2, l\<^sub>2 |` W, sh\<^sub>2)\" + using local.CallNone(4) local.CallNone(7) by auto + then show ?case + using f1 eval_evals.CallNone local.CallNone(5) local.CallNone(6) by auto +next + case CallStatic thus ?case + by (metis (no_types, lifting) eval_evals.CallStatic fv.simps(11) le_sup_iff) +next + case CallParamsThrow thus ?case + by simp (blast intro: eval_evals.CallParamsThrow) +next + case (Call e h\<^sub>0 l\<^sub>0 sh\<^sub>0 a h\<^sub>1 l\<^sub>1 sh\<^sub>1 ps vs h\<^sub>2 l\<^sub>2 sh\<^sub>2 C fs M Ts T pns body + D l\<^sub>2' e' h\<^sub>3 l\<^sub>3 sh\<^sub>3) + have IHe: "\W. fv e \ W \ P \ \e,(h\<^sub>0,l\<^sub>0|`W,sh\<^sub>0)\ \ \addr a,(h\<^sub>1,l\<^sub>1|`W,sh\<^sub>1)\" + and IHps: "\W. fvs ps \ W \ P \ \ps,(h\<^sub>1,l\<^sub>1|`W,sh\<^sub>1)\ [\] \map Val vs,(h\<^sub>2,l\<^sub>2|`W,sh\<^sub>2)\" + and IHbd: "\W. fv body \ W \ P \ \body,(h\<^sub>2,l\<^sub>2'|`W,sh\<^sub>2)\ \ \e',(h\<^sub>3,l\<^sub>3|`W,sh\<^sub>3)\" + and h\<^sub>2a: "h\<^sub>2 a = Some (C, fs)" + and "method": "P \ C sees M,NonStatic: Ts\T = (pns, body) in D" + and same_len: "size vs = size pns" + and l\<^sub>2': "l\<^sub>2' = [this \ Addr a, pns [\] vs]" by fact+ + have "fv (e\M(ps)) \ W" by fact + hence fve: "fv e \ W" and fvps: "fvs(ps) \ W" by auto + have wfmethod: "size Ts = size pns \ this \ set pns" and + fvbd: "fv body \ {this} \ set pns" + using "method" wf by(fastforce dest!:sees_wf_mdecl simp:wf_mdecl_def)+ + show ?case + using IHbd[OF fvbd] l\<^sub>2' same_len wfmethod h\<^sub>2a + eval_evals.Call[OF IHe[OF fve] IHps[OF fvps] _ "method" same_len l\<^sub>2'] + by (simp add:subset_insertI) +next + case (SCallNone ps h l sh vs h' l' sh' C M) + have "P \ \ps,(h, l |` W, sh)\ [\] \map Val vs,(h', l' |` W, sh')\" + using SCallNone.hyps(2) SCallNone.prems by auto + then show ?case using SCallNone.hyps(3) eval_evals.SCallNone by auto +next + case SCallNonStatic thus ?case by (metis eval_evals.SCallNonStatic fv.simps(12)) +next + case SCallParamsThrow thus ?case + by simp (blast intro: eval_evals.SCallParamsThrow) +next + case SCallInitThrow thus ?case by simp (blast intro: eval_evals.SCallInitThrow) +next + case SCallInit thus ?case by simp (blast intro: eval_evals.SCallInit) +next + case (SCall ps h\<^sub>0 l\<^sub>0 sh\<^sub>0 vs h\<^sub>2 l\<^sub>2 sh\<^sub>2 C M Ts T pns body D sfs l\<^sub>2' e' h\<^sub>3 l\<^sub>3 sh\<^sub>3) + have IHps: "\W. fvs ps \ W \ P \ \ps,(h\<^sub>0,l\<^sub>0|`W,sh\<^sub>0)\ [\] \map Val vs,(h\<^sub>2,l\<^sub>2|`W,sh\<^sub>2)\" + and IHbd: "\W. fv body \ W \ P \ \body,(h\<^sub>2,l\<^sub>2'|`W,sh\<^sub>2)\ \ \e',(h\<^sub>3,l\<^sub>3|`W,sh\<^sub>3)\" + and sh\<^sub>2D: "sh\<^sub>2 D = Some (sfs, Done) \ M = clinit \ sh\<^sub>2 D = \(sfs, Processing)\" + and "method": "P \ C sees M,Static: Ts\T = (pns, body) in D" + and same_len: "size vs = size pns" + and l\<^sub>2': "l\<^sub>2' = [pns [\] vs]" by fact+ + have "fv (C\\<^sub>sM(ps)) \ W" by fact + hence fvps: "fvs(ps) \ W" by auto + have wfmethod: "size Ts = size pns" and fvbd: "fv body \ set pns" + using "method" wf by(fastforce dest!:sees_wf_mdecl simp:wf_mdecl_def)+ + show ?case + using IHbd[OF fvbd] l\<^sub>2' same_len wfmethod sh\<^sub>2D + eval_evals.SCall[OF IHps[OF fvps] "method" _ same_len l\<^sub>2'] + by (simp add:subset_insertI) +next + case SeqThrow thus ?case by simp (blast intro: eval_evals.SeqThrow) +next + case CondT thus ?case by simp (blast intro: eval_evals.CondT) +next + case CondF thus ?case by simp (blast intro: eval_evals.CondF) +next + case CondThrow thus ?case by simp (blast intro: eval_evals.CondThrow) +next + case WhileF thus ?case by simp (blast intro: eval_evals.WhileF) +next + case WhileT thus ?case by simp (blast intro: eval_evals.WhileT) +next + case WhileCondThrow thus ?case by simp (blast intro: eval_evals.WhileCondThrow) +next + case WhileBodyThrow thus ?case by simp (blast intro: eval_evals.WhileBodyThrow) +next + case Throw thus ?case by simp (blast intro: eval_evals.Throw) +next + case ThrowNull thus ?case by simp (blast intro: eval_evals.ThrowNull) +next + case ThrowThrow thus ?case by simp (blast intro: eval_evals.ThrowThrow) +next + case Try thus ?case by simp (blast intro: eval_evals.Try) +next + case (TryCatch e\<^sub>1 h\<^sub>0 l\<^sub>0 sh\<^sub>0 a h\<^sub>1 l\<^sub>1 sh\<^sub>1 D fs C e\<^sub>2 V e\<^sub>2' h\<^sub>2 l\<^sub>2 sh\<^sub>2) + have IH\<^sub>1: "\W. fv e\<^sub>1 \ W \ P \ \e\<^sub>1,(h\<^sub>0,l\<^sub>0|`W,sh\<^sub>0)\ \ \Throw a,(h\<^sub>1,l\<^sub>1|`W,sh\<^sub>1)\" + and IH\<^sub>2: "\W. fv e\<^sub>2 \ W \ P \ \e\<^sub>2,(h\<^sub>1,l\<^sub>1(V\Addr a)|`W,sh\<^sub>1)\ \ \e\<^sub>2',(h\<^sub>2,l\<^sub>2|`W,sh\<^sub>2)\" + and lookup: "h\<^sub>1 a = Some(D, fs)" and subtype: "P \ D \\<^sup>* C" by fact+ + have "fv (try e\<^sub>1 catch(C V) e\<^sub>2) \ W" by fact + hence fv\<^sub>1: "fv e\<^sub>1 \ W" and fv\<^sub>2: "fv e\<^sub>2 \ insert V W" by auto + have IH\<^sub>2': "P \ \e\<^sub>2,(h\<^sub>1,(l\<^sub>1|`W)(V \ Addr a),sh\<^sub>1)\ \ \e\<^sub>2',(h\<^sub>2,l\<^sub>2|`insert V W,sh\<^sub>2)\" + using IH\<^sub>2[OF fv\<^sub>2] fun_upd_restrict[of l\<^sub>1 W] (*FIXME just l|W instead of l|(W-V) in simp rule??*) by simp + with eval_evals.TryCatch[OF IH\<^sub>1[OF fv\<^sub>1] _ subtype IH\<^sub>2'] lookup + show ?case by fastforce +next + case TryThrow thus ?case by simp (blast intro: eval_evals.TryThrow) +next + case Nil thus ?case by (simp add: eval_evals.Nil) +next + case Cons thus ?case by simp (blast intro: eval_evals.Cons) +next + case ConsThrow thus ?case by simp (blast intro: eval_evals.ConsThrow) +next + case InitFinal thus ?case by (simp add: eval_evals.InitFinal) +next + case InitNone thus ?case by(blast intro: eval_evals.InitNone) +next + case InitDone thus ?case + by (simp add: InitDone.hyps(2) InitDone.prems eval_evals.InitDone) +next + case InitProcessing thus ?case by (simp add: eval_evals.InitProcessing) +next + case InitError thus ?case using eval_evals.InitError by auto +next + case InitObject thus ?case by(simp add: eval_evals.InitObject) +next + case InitNonObject thus ?case by(simp add: eval_evals.InitNonObject) +next + case InitRInit thus ?case by(simp add: eval_evals.InitRInit) +next + case (RInit e h l sh v h' l' sh' C sfs i sh'' C' Cs e' e\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1) + have f1: "fv e \ W \ fv (INIT C' (Cs,True) \ e') \ W" + using RInit.prems by auto + then have f2: "P \ \e,(h, l |` W, sh)\ \ \Val v,(h', l' |` W, sh')\" + using RInit.hyps(2) by blast + have "P \ \INIT C' (Cs,True) \ e', (h', l' |` W, sh'')\ \ \e\<^sub>1,(h\<^sub>1, l\<^sub>1 |` W, sh\<^sub>1)\" + using f1 by (meson RInit.hyps(7)) + then show ?case + using f2 RInit.hyps(3) RInit.hyps(4) RInit.hyps(5) eval_evals.RInit by blast +next + case (RInitInitFail e h l sh a h' l' sh' C sfs i sh'' D Cs e' e\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1) + have f1: "fv e \ W" "fv e' \ W" + using RInitInitFail.prems by auto + then have f2: "P \ \e,(h, l |` W, sh)\ \ \throw a,(h', l' |` W, sh')\" + using RInitInitFail.hyps(2) by blast + then have f2': "fv (throw a) \ W" + using eval_final[OF f2] by auto + then have f1': "fv (RI (D,throw a);Cs \ e') \ W" + using f1 by auto + have "P \ \RI (D,throw a);Cs \ e', (h', l' |` W, sh'')\ \ \e\<^sub>1,(h\<^sub>1, l\<^sub>1 |` W, sh\<^sub>1)\" + using f1' by (meson RInitInitFail.hyps(6)) + then show ?case + using f2 by (simp add: RInitInitFail.hyps(3,4) eval_evals.RInitInitFail) +next + case (RInitFailFinal e h l sh a h' l' sh' sh'' C) + have f1: "fv e \ W" + using RInitFailFinal.prems by auto + then have f2: "P \ \e,(h, l |` W, sh)\ \ \throw a,(h', l' |` W, sh')\" + using RInitFailFinal.hyps(2) by blast + then have f2': "fv (throw a) \ W" + using eval_final[OF f2] by auto + then show ?case using f2 RInitFailFinal.hyps(3,4) eval_evals.RInitFailFinal by blast +qed +(*>*) + + +lemma eval_notfree_unchanged: + "P \ \e,(h,l,sh)\ \ \e',(h',l',sh')\ \ (\V. V \ fv e \ l' V = l V)" +and "P \ \es,(h,l,sh)\ [\] \es',(h',l',sh')\ \ (\V. V \ fvs es \ l' V = l V)" +(*<*) +proof(induct rule:eval_evals_inducts) + case LAss thus ?case by(simp add:fun_upd_apply) +next + case Block thus ?case + by (simp only:fun_upd_apply split:if_splits) fastforce +next + case TryCatch thus ?case + by (simp only:fun_upd_apply split:if_splits) fastforce +next + case (RInitInitFail e h l sh a h' l' sh' C sfs i sh'' D Cs e\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1) + have "fv (throw a) = {}" + using RInitInitFail.hyps(1) eval_final final_fv by blast + then have "fv e \ fv (RI (D,throw a) ; Cs \ unit) \ fv (RI (C,e) ; D#Cs \ unit)" + by auto + then show ?case using RInitInitFail.hyps(2,6) RInitInitFail.prems by fastforce +qed simp_all +(*>*) + + +lemma eval_closed_lcl_unchanged: + "\ P \ \e,(h,l,sh)\ \ \e',(h',l',sh')\; fv e = {} \ \ l' = l" +(*<*)by(fastforce dest:eval_notfree_unchanged simp add:fun_eq_iff [where 'b="val option"])(*>*) + + +lemma list_eval_Throw: +assumes eval_e: "P \ \throw x,s\ \ \e',s'\" +shows "P \ \map Val vs @ throw x # es',s\ [\] \map Val vs @ e' # es',s'\" +(*<*) +proof - + from eval_e + obtain a where e': "e' = Throw a" + by (cases) (auto dest!: eval_final) + { + fix es + have "\vs. es = map Val vs @ throw x # es' + \ P \ \es,s\[\]\map Val vs @ e' # es',s'\" + proof (induct es type: list) + case Nil thus ?case by simp + next + case (Cons e es vs) + have e_es: "e # es = map Val vs @ throw x # es'" by fact + show "P \ \e # es,s\ [\] \map Val vs @ e' # es',s'\" + proof (cases vs) + case Nil + with e_es obtain "e=throw x" "es=es'" by simp + moreover from eval_e e' + have "P \ \throw x # es,s\ [\] \Throw a # es,s'\" + by (iprover intro: ConsThrow) + ultimately show ?thesis using Nil e' by simp + next + case (Cons v vs') + have vs: "vs = v # vs'" by fact + with e_es obtain + e: "e=Val v" and es:"es= map Val vs' @ throw x # es'" + by simp + from e + have "P \ \e,s\ \ \Val v,s\" + by (iprover intro: eval_evals.Val) + moreover from es + have "P \ \es,s\ [\] \map Val vs' @ e' # es',s'\" + by (rule Cons.hyps) + ultimately show + "P \ \e#es,s\ [\] \map Val vs @ e' # es',s'\" + using vs by (auto intro: eval_evals.Cons) + qed + qed + } + thus ?thesis + by simp +qed +(*>*) + +\ \ separate evaluation of first subexp of a sequence \ +lemma seq_ext: +assumes IH: "\e' s'. P \ \e'',s''\ \ \e',s'\ \ P \ \e,s\ \ \e',s'\" + and seq: "P \ \e'' ;; e\<^sub>0,s''\ \ \e',s'\" +shows "P \ \e ;; e\<^sub>0,s\ \ \e',s'\" +proof(rule eval_cases(14)[OF seq]) \ \ Seq \ + fix v' s\<^sub>1 assume e'': "P \ \e'',s''\ \ \Val v',s\<^sub>1\" and estep: "P \ \e\<^sub>0,s\<^sub>1\ \ \e',s'\" + have "P \ \e,s\ \ \Val v',s\<^sub>1\" using e'' IH by simp + then show ?thesis using estep Seq by simp +next + fix e\<^sub>t assume e'': "P \ \e'',s''\ \ \throw e\<^sub>t,s'\" and e': "e' = throw e\<^sub>t" + have "P \ \e,s\ \ \throw e\<^sub>t,s'\" using e'' IH by simp + then show ?thesis using eval_evals.SeqThrow e' by simp +qed + +\ \ separate evaluation of @{text RI} subexp, val case \ +lemma rinit_Val_ext: +assumes ri: "P \ \RI (C,e'') ; Cs \ e\<^sub>0,s''\ \ \Val v',s\<^sub>1\" + and IH: "\e' s'. P \ \e'',s''\ \ \e',s'\ \ P \ \e,s\ \ \e',s'\" +shows "P \ \RI (C,e) ; Cs \ e\<^sub>0,s\ \ \Val v',s\<^sub>1\" +proof(rule eval_cases(20)[OF ri]) \ \ RI \ + fix v'' h' l' sh' sfs i + assume e''step: "P \ \e'',s''\ \ \Val v'',(h', l', sh')\" + and shC: "sh' C = \(sfs, i)\" + and init: "P \ \INIT (if Cs = [] then C else last Cs) (Cs,True) \ e\<^sub>0,(h', l', sh'(C \ (sfs, Done)))\ \ + \Val v',s\<^sub>1\" + have "P \ \e,s\ \ \Val v'',(h', l', sh')\" using IH[OF e''step] by simp + then show ?thesis using RInit init shC by auto +next + fix a h' l' sh' sfs i D Cs' + assume e''step: "P \ \e'',s''\ \ \throw a,(h', l', sh')\" + and riD: "P \ \RI (D,throw a) ; Cs' \ e\<^sub>0,(h', l', sh'(C \ (sfs, Error)))\ \ \Val v',s\<^sub>1\" + have "P \ \e,s\ \ \throw a,(h', l', sh')\" using IH[OF e''step] by simp + then show ?thesis using riD rinit_throwE by blast +qed(simp) + +\ \ separate evaluation of @{text RI} subexp, throw case \ +lemma rinit_throw_ext: +assumes ri: "P \ \RI (C,e'') ; Cs \ e\<^sub>0,s''\ \ \throw e\<^sub>t,s'\" + and IH: "\e' s'. P \ \e'',s''\ \ \e',s'\ \ P \ \e,s\ \ \e',s'\" +shows "P \ \RI (C,e) ; Cs \ e\<^sub>0,s\ \ \throw e\<^sub>t,s'\" +proof(rule eval_cases(20)[OF ri]) \ \ RI \ + fix v h' l' sh' sfs i + assume e''step: "P \ \e'',s''\ \ \Val v,(h', l', sh')\" + and shC: "sh' C = \(sfs, i)\" + and init: "P \ \INIT (if Cs = [] then C else last Cs) (Cs,True) \ e\<^sub>0,(h', l', sh'(C \ (sfs, Done)))\ \ + \throw e\<^sub>t,s'\" + have "P \ \e,s\ \ \Val v,(h', l', sh')\" using IH[OF e''step] by simp + then show ?thesis using RInit init shC by auto +next + fix a h' l' sh' sfs i D Cs' + assume e''step: "P \ \e'',s''\ \ \throw a,(h', l', sh')\" + and shC: "sh' C = \(sfs, i)\" + and riD: "P \ \RI (D,throw a) ; Cs' \ e\<^sub>0,(h', l', sh'(C \ (sfs, Error)))\ \ \throw e\<^sub>t,s'\" + and cons: "Cs = D # Cs'" + have estep': "P \ \e,s\ \ \throw a,(h', l', sh')\" using IH[OF e''step] by simp + then show ?thesis using RInitInitFail cons riD shC by simp +next + fix a h' l' sh' sfs i + assume "throw e\<^sub>t = throw a" + and "s' = (h', l', sh'(C \ (sfs, Error)))" + and "P \ \e'',s''\ \ \throw a,(h', l', sh')\" + and "sh' C = \(sfs, i)\" + and "Cs = []" + then show ?thesis using RInitFailFinal IH by auto +qed + +\ \ separate evaluation of @{text RI} subexp \ +lemma rinit_ext: +assumes IH: "\e' s'. P \ \e'',s''\ \ \e',s'\ \ P \ \e,s\ \ \e',s'\" +shows "\e' s'. P \ \RI (C,e'') ; Cs \ e\<^sub>0,s''\ \ \e',s'\ + \ P \ \RI (C,e) ; Cs \ e\<^sub>0,s\ \ \e',s'\" +proof - + fix e' s' assume ri'': "P \ \RI (C,e'') ; Cs \ e\<^sub>0,s''\ \ \e',s'\" + then have "final e'" using eval_final by simp + then show "P \ \RI (C,e) ; Cs \ e\<^sub>0,s\ \ \e',s'\" + proof(rule finalE) + fix v assume "e' = Val v" then show ?thesis using rinit_Val_ext[OF _ IH] ri'' by simp + next + fix a assume "e' = throw a" then show ?thesis using rinit_throw_ext[OF _ IH] ri'' by simp + qed +qed + +\ \ @{text INIT} and @{text RI} return either @{text Val} with @{text Done} or + @{text Processing} flag or @{text Throw} with @{text Error} flag \ +lemma +shows eval_init_return: "P \ \e,s\ \ \e',s'\ + \ iconf (shp s) e + \ (\Cs b. e = INIT C' (Cs,b) \ unit) \ (\C e\<^sub>0 Cs e\<^sub>i. e = RI(C,e\<^sub>0);Cs@[C'] \ unit) + \ (\e\<^sub>0. e = RI(C',e\<^sub>0);Nil \ unit) + \ (val_of e' = Some v \ (\sfs i. shp s' C' = \(sfs,i)\ \ (i = Done \ i = Processing))) + \ (throw_of e' = Some a \ (\sfs i. shp s' C' = \(sfs,Error)\))" +and "P \ \es,s\ [\] \es',s'\ \ True" +proof(induct rule: eval_evals.inducts) + case (InitFinal e s e' s' C b) then show ?case + by(fastforce simp: initPD_def dest: eval_final_same) +next + case (InitDone sh C sfs C' Cs e h l e' s') + then have "final e'" using eval_final by simp + then show ?case + proof(rule finalE) + fix v assume e': "e' = Val v" then show ?thesis using InitDone initPD_def + proof(cases Cs) qed(auto) + next + fix a assume e': "e' = throw a" then show ?thesis using InitDone initPD_def + proof(cases Cs) qed(auto) + qed +next + case (InitProcessing sh C sfs C' Cs e h l e' s') + then have "final e'" using eval_final by simp + then show ?case + proof(rule finalE) + fix v assume e': "e' = Val v" then show ?thesis using InitProcessing initPD_def + proof(cases Cs) qed(auto) + next + fix a assume e': "e' = throw a" then show ?thesis using InitProcessing initPD_def + proof(cases Cs) qed(auto) + qed +next + case (InitError sh C sfs Cs e h l e' s' C') show ?case + proof(cases Cs) + case Nil then show ?thesis using InitError by simp + next + case (Cons C2 list) + then have "final e'" using InitError eval_final by simp + then show ?thesis + proof(rule finalE) + fix v assume e': "e' = Val v" then show ?thesis + using InitError + proof - + obtain ccss :: "char list list" and bb :: bool where + "INIT C' (C # Cs,False) \ e = INIT C' (ccss,bb) \ unit" + using InitError.prems(2) by blast + then show ?thesis using InitError.hyps(2) e' by(auto dest!: rinit_throwE) + qed + next + fix a assume e': "e' = throw a" + then show ?thesis using Cons InitError cons_to_append[of list] by clarsimp + qed + qed +next + case (InitRInit C Cs h l sh e' s' C') show ?case + proof(cases Cs) + case Nil then show ?thesis using InitRInit by simp + next + case (Cons C' list) then show ?thesis + using InitRInit Cons cons_to_append[of list] by clarsimp + qed +next + case (RInit e s v h' l' sh' C sfs i sh'' C' Cs e' e\<^sub>1 s\<^sub>1) + then have final: "final e\<^sub>1" using eval_final by simp + then show ?case + proof(cases Cs) + case Nil show ?thesis using final + proof(rule finalE) + fix v assume e': "e\<^sub>1 = Val v" show ?thesis + using RInit Nil by(auto simp: fun_upd_same initPD_def) + next + fix a assume e': "e\<^sub>1 = throw a" show ?thesis + using RInit Nil by(auto simp: fun_upd_same initPD_def) + qed + next + case (Cons a list) show ?thesis + proof(rule finalE[OF final]) + fix v assume e': "e\<^sub>1 = Val v" then show ?thesis + using RInit Cons by clarsimp (metis last.simps last_appendR list.distinct(1)) + next + fix a assume e': "e\<^sub>1 = throw a" then show ?thesis + using RInit Cons by clarsimp (metis last.simps last_appendR list.distinct(1)) + qed + qed +next + case (RInitInitFail e s a h' l' sh' C sfs i sh'' D Cs e' e\<^sub>1 s\<^sub>1) + then have final: "final e\<^sub>1" using eval_final by simp + then show ?case + proof(rule finalE) + fix v assume e': "e\<^sub>1 = Val v" then show ?thesis + using RInitInitFail by clarsimp (meson exp.distinct(101) rinit_throwE) + next + fix a' assume e': "e\<^sub>1 = Throw a'" + then have "iconf (sh'(C \ (sfs, Error))) a" + using RInitInitFail.hyps(1) eval_final by fastforce + then show ?thesis using RInitInitFail e' + by clarsimp (meson Cons_eq_append_conv list.inject) + qed +qed(auto simp: fun_upd_same) + +lemma init_Val_PD: "P \ \INIT C' (Cs,b) \ unit,s\ \ \Val v,s'\ + \ iconf (shp s) (INIT C' (Cs,b) \ unit) + \ \sfs i. shp s' C' = \(sfs,i)\ \ (i = Done \ i = Processing)" + by(drule_tac v = v in eval_init_return, simp+) + +lemma init_throw_PD: "P \ \INIT C' (Cs,b) \ unit,s\ \ \throw a,s'\ + \ iconf (shp s) (INIT C' (Cs,b) \ unit) + \ \sfs i. shp s' C' = \(sfs,Error)\" + by(drule_tac a = a in eval_init_return, simp+) + +lemma rinit_Val_PD: "P \ \RI(C,e\<^sub>0);Cs \ unit,s\ \ \Val v,s'\ + \ iconf (shp s) (RI(C,e\<^sub>0);Cs \ unit) \ last(C#Cs) = C' + \ \sfs i. shp s' C' = \(sfs,i)\ \ (i = Done \ i = Processing)" +apply(drule_tac C' = C' and v = v in eval_init_return, simp_all) +apply (metis append_butlast_last_id) +done + +lemma rinit_throw_PD: "P \ \RI(C,e\<^sub>0);Cs \ unit,s\ \ \throw a,s'\ + \ iconf (shp s) (RI(C,e\<^sub>0);Cs \ unit) \ last(C#Cs) = C' + \ \sfs i. shp s' C' = \(sfs,Error)\" +apply(drule_tac C' = C' and a = a in eval_init_return, simp_all) +apply (metis append_butlast_last_id) +done + +\ \ combining the above to get evaluation of @{text INIT} in a sequence \ + +(* Hiermit kann man die ganze pair-Splitterei in den automatischen Taktiken +abschalten. Wieder anschalten siehe nach dem Beweis. *) +(*<*) +declare split_paired_All [simp del] split_paired_Ex [simp del] +(*>*) + +lemma eval_init_seq': "P \ \e,s\ \ \e',s'\ + \ (\C Cs b e\<^sub>i. e = INIT C (Cs,b) \ e\<^sub>i) \ (\C e\<^sub>0 Cs e\<^sub>i. e = RI(C,e\<^sub>0);Cs \ e\<^sub>i) + \ (\C Cs b e\<^sub>i. e = INIT C (Cs,b) \ e\<^sub>i \ P \ \(INIT C (Cs,b) \ unit);; e\<^sub>i,s\ \ \e',s'\) + \ (\C e\<^sub>0 Cs e\<^sub>i. e = RI(C,e\<^sub>0);Cs \ e\<^sub>i \ P \ \(RI(C,e\<^sub>0);Cs \ unit);; e\<^sub>i,s\ \ \e',s'\)" +and "P \ \es,s\ [\] \es',s'\ \ True" +proof(induct rule: eval_evals.inducts) + case InitFinal then show ?case by(auto simp: Seq[OF eval_evals.InitFinal[OF Val[where v=Unit]]]) +next + case (InitNone sh) then show ?case + using seq_ext[OF eval_evals.InitNone[where sh=sh and e=unit, OF InitNone.hyps(1)]] by fastforce +next + case (InitDone sh) then show ?case + using seq_ext[OF eval_evals.InitDone[where sh=sh and e=unit, OF InitDone.hyps(1)]] by fastforce +next + case (InitProcessing sh) then show ?case + using seq_ext[OF eval_evals.InitProcessing[where sh=sh and e=unit, OF InitProcessing.hyps(1)]] + by fastforce +next + case (InitError sh) then show ?case + using seq_ext[OF eval_evals.InitError[where sh=sh and e=unit, OF InitError.hyps(1)]] by fastforce +next + case (InitObject sh) then show ?case + using seq_ext[OF eval_evals.InitObject[where sh=sh and e=unit, OF InitObject.hyps(1)]] + by fastforce +next + case (InitNonObject sh) then show ?case + using seq_ext[OF eval_evals.InitNonObject[where sh=sh and e=unit, OF InitNonObject.hyps(1)]] + by fastforce +next + case (InitRInit C Cs e h l sh e' s' C') then show ?case + using seq_ext[OF eval_evals.InitRInit[where e=unit]] by fastforce +next + case RInit then show ?case + using seq_ext[OF eval_evals.RInit[where e=unit, OF RInit.hyps(1)]] by fastforce +next + case RInitInitFail then show ?case + using seq_ext[OF eval_evals.RInitInitFail[where e=unit, OF RInitInitFail.hyps(1)]] by fastforce +next + case RInitFailFinal + then show ?case using eval_evals.RInitFailFinal eval_evals.SeqThrow by auto +qed(auto) + +lemma eval_init_seq: "P \ \INIT C (Cs,b) \ e,(h, l, sh)\ \ \e',s'\ + \ P \ \(INIT C (Cs,b) \ unit);; e,(h, l, sh)\ \ \e',s'\" + by(auto dest: eval_init_seq') + + +text \ The key lemma: \ +lemma +assumes wf: "wwf_J_prog P" +shows extend_1_eval: "P \ \e,s,b\ \ \e'',s'',b''\ \ P,shp s \\<^sub>b (e,b) \ + \ (\s' e'. P \ \e'',s''\ \ \e',s'\ \ P \ \e,s\ \ \e',s'\)" +and extend_1_evals: "P \ \es,s,b\ [\] \es'',s'',b''\ \ P,shp s \\<^sub>b (es,b) \ + \ (\s' es'. P \ \es'',s''\ [\] \es',s'\ \ P \ \es,s\ [\] \es',s'\)" +proof (induct rule: red_reds.inducts) + case (RedNew h a C FDTs h' l sh) + then have e':"e' = addr a" and s':"s' = (h(a \ blank P C), l, sh)" + using eval_cases(3) by fastforce+ + obtain sfs i where shC: "sh C = \(sfs, i)\" and "i = Done \ i = Processing" + using RedNew by (clarsimp simp: bconf_def initPD_def) + then show ?case + proof(cases i) + case Done then show ?thesis using RedNew shC e' s' New by simp + next + case Processing + then have shC': "\sfs. sh C = Some(sfs,Done)" and shP: "sh C = Some(sfs,Processing)" + using shC by simp+ + then have init: "P \ \INIT C ([C],False) \ unit,(h,l,sh)\ \ \unit,(h,l,sh)\" + by(simp add: InitFinal InitProcessing Val) + have "P \ \new C,(h, l, sh)\ \ \addr a,(h(a \ blank P C),l,sh)\" + using RedNew shC' by(auto intro: NewInit[OF _ init]) + then show ?thesis using e' s' by simp + qed(auto) +next + case (RedNewFail h C l sh) + then have e':"e' = THROW OutOfMemory" and s':"s' = (h, l, sh)" + using eval_final_same final_def by fastforce+ + obtain sfs i where shC: "sh C = \(sfs, i)\" and "i = Done \ i = Processing" + using RedNewFail by (clarsimp simp: bconf_def initPD_def) + then show ?case + proof(cases i) + case Done then show ?thesis using RedNewFail shC e' s' NewFail by simp + next + case Processing + then have shC': "\sfs. sh C = Some(sfs,Done)" and shP: "sh C = Some(sfs,Processing)" + using shC by simp+ + then have init: "P \ \INIT C ([C],False) \ unit,(h,l,sh)\ \ \unit,(h,l,sh)\" + by(simp add: InitFinal InitProcessing Val) + have "P \ \new C,(h, l, sh)\ \ \THROW OutOfMemory,(h,l,sh)\" + using RedNewFail shC' by(auto intro: NewInitOOM[OF _ init]) + then show ?thesis using e' s' by simp + qed(auto) +next + case (NewInitRed sh C h l) + then have seq: "P \ \(INIT C ([C],False) \ unit);; new C,(h, l, sh)\ \ \e',s'\" + using eval_init_seq by simp + then show ?case + proof(rule eval_cases(14)) \ \ Seq \ + fix v s\<^sub>1 assume init: "P \ \INIT C ([C],False) \ unit,(h, l, sh)\ \ \Val v,s\<^sub>1\" + and new: "P \ \new C,s\<^sub>1\ \ \e',s'\" + obtain h\<^sub>1 l\<^sub>1 sh\<^sub>1 where s\<^sub>1: "s\<^sub>1 = (h\<^sub>1,l\<^sub>1,sh\<^sub>1)" by(cases s\<^sub>1) + then obtain sfs i where shC: "sh\<^sub>1 C = \(sfs, i)\" and iDP: "i = Done \ i = Processing" + using init_Val_PD[OF init] by auto + show ?thesis + proof(rule eval_cases(1)[OF new]) \ \ New \ + fix sha ha a FDTs la + assume s\<^sub>1a: "s\<^sub>1 = (ha, la, sha)" and e': "e' = addr a" + and s': "s' = (ha(a \ blank P C), la, sha)" + and addr: "new_Addr ha = \a\" and fields: "P \ C has_fields FDTs" + then show ?thesis using NewInit[OF _ _ addr fields] NewInitRed.hyps init by simp + next + fix sha ha la + assume "s\<^sub>1 = (ha, la, sha)" and "e' = THROW OutOfMemory" + and "s' = (ha, la, sha)" and "new_Addr ha = None" + then show ?thesis using NewInitOOM NewInitRed.hyps init by simp + next + fix sha ha la v' h' l' sh' a FDTs + assume s\<^sub>1a: "s\<^sub>1 = (ha, la, sha)" and e': "e' = addr a" + and s': "s' = (h'(a \ blank P C), l', sh')" + and shaC: "\sfs. sha C \ \(sfs, Done)\" + and init': "P \ \INIT C ([C],False) \ unit,(ha, la, sha)\ \ \Val v',(h', l', sh')\" + and addr: "new_Addr h' = \a\" and fields: "P \ C has_fields FDTs" + then have i: "i = Processing" using iDP shC s\<^sub>1 by simp + then have "(h', l', sh') = (ha, la, sha)" using init' init_ProcessingE s\<^sub>1 s\<^sub>1a shC by blast + then show ?thesis using NewInit NewInitRed.hyps s\<^sub>1a addr fields init shaC e' s' by auto + next + fix sha ha la v' h' l' sh' + assume s\<^sub>1a: "s\<^sub>1 = (ha, la, sha)" and e': "e' = THROW OutOfMemory" + and s': "s' = (h', l', sh')" and "\sfs. sha C \ \(sfs, Done)\" + and init': "P \ \INIT C ([C],False) \ unit,(ha, la, sha)\ \ \Val v',(h', l', sh')\" + and addr: "new_Addr h' = None" + then have i: "i = Processing" using iDP shC s\<^sub>1 by simp + then have "(h', l', sh') = (ha, la, sha)" using init' init_ProcessingE s\<^sub>1 s\<^sub>1a shC by blast + then show ?thesis + using NewInitOOM NewInitRed.hyps e' addr s' s\<^sub>1a init by auto + next + fix sha ha la a + assume s\<^sub>1a: "s\<^sub>1 = (ha, la, sha)" + and "\sfs. sha C \ \(sfs, Done)\" + and init': "P \ \INIT C ([C],False) \ unit,(ha, la, sha)\ \ \throw a,s'\" + then have i: "i = Processing" using iDP shC s\<^sub>1 by simp + then show ?thesis using init' init_ProcessingE s\<^sub>1 s\<^sub>1a shC by blast + qed + next + fix e assume e': "e' = throw e" + and init: "P \ \INIT C ([C],False) \ unit,(h, l, sh)\ \ \throw e,s'\" + obtain h' l' sh' where s': "s' = (h',l',sh')" by(cases s') + then obtain sfs i where shC: "sh' C = \(sfs, i)\" and iDP: "i = Error" + using init_throw_PD[OF init] by auto + then show ?thesis by (simp add: NewInitRed.hyps NewInitThrow e' init) + qed +next + case CastRed then show ?case + by(fastforce elim!: eval_cases intro: eval_evals.intros intro!: CastFail) +next + case RedCastNull + then show ?case + by simp (iprover elim: eval_cases intro: eval_evals.intros) +next + case RedCast + then show ?case + by (auto elim: eval_cases intro: eval_evals.intros) +next + case RedCastFail + then show ?case + by (auto elim!: eval_cases intro: eval_evals.intros) +next + case BinOpRed1 then show ?case + by(fastforce elim!: eval_cases intro: eval_evals.intros simp: val_no_step) +next + case BinOpRed2 + thus ?case + by (fastforce elim!: eval_cases intro: eval_evals.intros eval_finalId) +next + case RedBinOp + thus ?case + by simp (iprover elim: eval_cases intro: eval_evals.intros) +next + case RedVar + thus ?case + by (fastforce elim: eval_cases intro: eval_evals.intros) +next + case LAssRed thus ?case + by(fastforce elim: eval_cases intro: eval_evals.intros) +next + case RedLAss + thus ?case + by (fastforce elim: eval_cases intro: eval_evals.intros) +next + case FAccRed thus ?case + by(fastforce elim: eval_cases intro: eval_evals.intros) +next + case RedFAcc then show ?case + by (fastforce elim: eval_cases intro: eval_evals.intros) +next + case RedFAccNull then show ?case + by (fastforce elim!: eval_cases intro: eval_evals.intros) +next + case RedFAccNone thus ?case + by(fastforce elim: eval_cases intro: eval_evals.intros) +next + case RedFAccStatic thus ?case + by(fastforce elim: eval_cases intro: eval_evals.intros) +next + case (RedSFAcc C F t D sh sfs i v h l) + then have e':"e' = Val v" and s':"s' = (h, l, sh)" + using eval_cases(3) by fastforce+ + have "i = Done \ i = Processing" using RedSFAcc by (clarsimp simp: bconf_def initPD_def) + then show ?case + proof(cases i) + case Done then show ?thesis using RedSFAcc e' s' SFAcc by simp + next + case Processing + then have shC': "\sfs. sh D = Some(sfs,Done)" and shP: "sh D = Some(sfs,Processing)" + using RedSFAcc by simp+ + then have init: "P \ \INIT D ([D],False) \ unit,(h,l,sh)\ \ \unit,(h,l,sh)\" + by(simp add: InitFinal InitProcessing Val) + have "P \ \C\\<^sub>sF{D},(h, l, sh)\ \ \Val v,(h,l,sh)\" + by(rule SFAccInit[OF RedSFAcc.hyps(1) shC' init shP RedSFAcc.hyps(3)]) + then show ?thesis using e' s' by simp + qed(auto) +next + case (SFAccInitRed C F t D sh h l) + then have seq: "P \ \(INIT D ([D],False) \ unit);; C\\<^sub>sF{D},(h, l, sh)\ \ \e',s'\" + using eval_init_seq by simp + then show ?case + proof(rule eval_cases(14)) \ \ Seq \ + fix v s\<^sub>1 assume init: "P \ \INIT D ([D],False) \ unit,(h, l, sh)\ \ \Val v,s\<^sub>1\" + and acc: "P \ \C\\<^sub>sF{D},s\<^sub>1\ \ \e',s'\" + obtain h\<^sub>1 l\<^sub>1 sh\<^sub>1 where s\<^sub>1: "s\<^sub>1 = (h\<^sub>1,l\<^sub>1,sh\<^sub>1)" by(cases s\<^sub>1) + then obtain sfs i where shD: "sh\<^sub>1 D = \(sfs, i)\" and iDP: "i = Done \ i = Processing" + using init_Val_PD[OF init] by auto + show ?thesis + proof(rule eval_cases(8)[OF acc]) \ \ SFAcc \ + fix t sha sfs v ha la + assume "s\<^sub>1 = (ha, la, sha)" and "e' = Val v" + and "s' = (ha, la, sha)" and "P \ C has F,Static:t in D" + and "sha D = \(sfs, Done)\" and "sfs F = \v\" + then show ?thesis using SFAccInit SFAccInitRed.hyps(2) init by auto + next + fix t sha ha la v' h' l' sh' sfs i' v + assume s\<^sub>1a: "s\<^sub>1 = (ha, la, sha)" and e': "e' = Val v" + and s': "s' = (h', l', sh')" and field: "P \ C has F,Static:t in D" + and "\sfs. sha D \ \(sfs, Done)\" + and init': "P \ \INIT D ([D],False) \ unit,(ha, la, sha)\ \ \Val v',(h', l', sh')\" + and shD': "sh' D = \(sfs, i')\" and sfsF: "sfs F = \v\" + then have i: "i = Processing" using iDP shD s\<^sub>1 by simp + then have "(h', l', sh') = (ha, la, sha)" using init' init_ProcessingE s\<^sub>1 s\<^sub>1a shD by blast + then show ?thesis using SFAccInit SFAccInitRed.hyps(2) e' s' field init s\<^sub>1a sfsF shD' by auto + next + fix t sha ha la a + assume s\<^sub>1a: "s\<^sub>1 = (ha, la, sha)" and "e' = throw a" + and "P \ C has F,Static:t in D" and "\sfs. sha D \ \(sfs, Done)\" + and init': "P \ \INIT D ([D],False) \ unit,(ha, la, sha)\ \ \throw a,s'\" + then have i: "i = Processing" using iDP shD s\<^sub>1 by simp + then show ?thesis using init' init_ProcessingE s\<^sub>1 s\<^sub>1a shD by blast + next + assume "\b t. \ P \ C has F,b:t in D" + then show ?thesis using SFAccInitRed.hyps(1) by blast + next + fix t assume field: "P \ C has F,NonStatic:t in D" + then show ?thesis using has_field_fun[OF SFAccInitRed.hyps(1) field] by simp + qed + next + fix e assume e': "e' = throw e" + and init: "P \ \INIT D ([D],False) \ unit,(h, l, sh)\ \ \throw e,s'\" + obtain h' l' sh' where s': "s' = (h',l',sh')" by(cases s') + then obtain sfs i where shC: "sh' D = \(sfs, i)\" and iDP: "i = Error" + using init_throw_PD[OF init] by auto + then show ?thesis + using SFAccInitRed.hyps(1) SFAccInitRed.hyps(2) SFAccInitThrow e' init by auto + qed +next + case RedSFAccNone thus ?case + by(fastforce elim: eval_cases intro: eval_evals.intros) +next + case RedSFAccNonStatic thus ?case + by(fastforce elim: eval_cases intro: eval_evals.intros) +next + case (FAssRed1 e s b e1 s1 b1 F D e\<^sub>2) + obtain h' l' sh' where "s'=(h',l',sh')" by(cases s') + with FAssRed1 show ?case + by(fastforce elim!: eval_cases(9)[where e\<^sub>1=e1] intro: eval_evals.intros simp: val_no_step + intro!: FAss FAssNull FAssNone FAssStatic FAssThrow2) +next + case FAssRed2 + obtain h' l' sh' where "s'=(h',l',sh')" by(cases s') + with FAssRed2 show ?case + by(auto elim!: eval_cases intro: eval_evals.intros + intro!: FAss FAssNull FAssNone FAssStatic FAssThrow2 Val) +next + case RedFAss + thus ?case + by (fastforce elim!: eval_cases intro: eval_evals.intros) +next + case RedFAssNull + thus ?case + by (fastforce elim!: eval_cases intro: eval_evals.intros) +next + case RedFAssNone + then show ?case + by(auto elim!: eval_cases intro: eval_evals.intros eval_finalId) +next + case RedFAssStatic + then show ?case + by(auto elim!: eval_cases intro: eval_evals.intros eval_finalId) +next + case (SFAssRed e s b e'' s'' b'' C F D) + obtain h l sh where [simp]: "s = (h,l,sh)" by(cases s) + obtain h' l' sh' where [simp]: "s'=(h',l',sh')" by(cases s') + have "val_of e = None" using val_no_step SFAssRed.hyps(1) by(meson option.exhaust) + then have bconf: "P,sh \\<^sub>b (e,b) \" using SFAssRed by simp + show ?case using SFAssRed.prems(2) SFAssRed bconf + proof cases + case 2 with SFAssRed bconf show ?thesis by(auto intro!: SFAssInit) + next + case 3 with SFAssRed bconf show ?thesis by(auto intro!: SFAssInitThrow) + qed(auto intro: eval_evals.intros intro!: SFAss SFAssInit SFAssNone SFAssNonStatic) +next + case (RedSFAss C F t D sh sfs i sfs' v sh' h l) + let ?sfs' = "sfs(F \ v)" + have e':"e' = unit" and s':"s' = (h, l, sh(D \ (?sfs', i)))" + using RedSFAss eval_cases(3) by fastforce+ + have "i = Done \ i = Processing" using RedSFAss by(clarsimp simp: bconf_def initPD_def) + then show ?case + proof(cases i) + case Done then show ?thesis using RedSFAss e' s' SFAss Val by auto + next + case Processing + then have shC': "\sfs. sh D = Some(sfs,Done)" and shP: "sh D = Some(sfs,Processing)" + using RedSFAss by simp+ + then have init: "P \ \INIT D ([D],False) \ unit,(h,l,sh)\ \ \unit,(h,l,sh)\" + by(simp add: InitFinal InitProcessing Val) + have "P \ \C\\<^sub>sF{D} := Val v,(h, l, sh)\ \ \unit,(h,l,sh(D \ (?sfs', i)))\" + using Processing by(auto intro: SFAssInit[OF Val RedSFAss.hyps(1) shC' init shP]) + then show ?thesis using e' s' by simp + qed(auto) +next + case (SFAssInitRed C F t D sh v h l) + then have seq: "P \ \(INIT D ([D],False) \ unit);; C\\<^sub>sF{D} := Val v,(h, l, sh)\ \ \e',s'\" + using eval_init_seq by simp + then show ?case + proof(rule eval_cases(14)) \ \ Seq \ + fix v' s\<^sub>1 assume init: "P \ \INIT D ([D],False) \ unit,(h, l, sh)\ \ \Val v',s\<^sub>1\" + and acc: "P \ \C\\<^sub>sF{D} := Val v,s\<^sub>1\ \ \e',s'\" + obtain h\<^sub>1 l\<^sub>1 sh\<^sub>1 where s\<^sub>1: "s\<^sub>1 = (h\<^sub>1,l\<^sub>1,sh\<^sub>1)" by(cases s\<^sub>1) + then obtain sfs i where shD: "sh\<^sub>1 D = \(sfs, i)\" and iDP: "i = Done \ i = Processing" + using init_Val_PD[OF init] by auto + show ?thesis + proof(rule eval_cases(10)[OF acc]) \ \ SFAss \ + fix va h\<^sub>1 l\<^sub>1 sh\<^sub>1 t sfs + assume e': "e' = unit" and s': "s' = (h\<^sub>1, l\<^sub>1, sh\<^sub>1(D \ (sfs(F \ va), Done)))" + and val: "P \ \Val v,s\<^sub>1\ \ \Val va,(h\<^sub>1, l\<^sub>1, sh\<^sub>1)\" + and field: "P \ C has F,Static:t in D" and shD': "sh\<^sub>1 D = \(sfs, Done)\" + have "v = va" and "s\<^sub>1 = (h\<^sub>1, l\<^sub>1, sh\<^sub>1)" using eval_final_same[OF val] by auto + then show ?thesis using SFAssInit field SFAssInitRed.hyps(2) shD' e' s' init val + by (metis eval_final eval_finalId) + next + fix va h\<^sub>1 l\<^sub>1 sh\<^sub>1 t v' h' l' sh' sfs i' + assume e': "e' = unit" and s': "s' = (h', l', sh'(D \ (sfs(F \ va), i')))" + and val: "P \ \Val v,s\<^sub>1\ \ \Val va,(h\<^sub>1, l\<^sub>1, sh\<^sub>1)\" + and field: "P \ C has F,Static:t in D" and nDone: "\sfs. sh\<^sub>1 D \ \(sfs, Done)\" + and init': "P \ \INIT D ([D],False) \ unit,(h\<^sub>1, l\<^sub>1, sh\<^sub>1)\ \ \Val v',(h', l', sh')\" + and shD': "sh' D = \(sfs, i')\" + have v: "v = va" and s\<^sub>1a: "s\<^sub>1 = (h\<^sub>1, l\<^sub>1, sh\<^sub>1)" using eval_final_same[OF val] by auto + then have i: "i = Processing" using iDP shD s\<^sub>1 nDone by simp + then have "(h\<^sub>1, l\<^sub>1, sh\<^sub>1) = (h', l', sh')" using init' init_ProcessingE s\<^sub>1 s\<^sub>1a shD by blast + then show ?thesis using SFAssInit SFAssInitRed.hyps(2) e' s' field init v s\<^sub>1a shD' val + by (metis eval_final eval_finalId) + next + fix va h\<^sub>1 l\<^sub>1 sh\<^sub>1 t a + assume "e' = throw a" and val: "P \ \Val v,s\<^sub>1\ \ \Val va,(h\<^sub>1, l\<^sub>1, sh\<^sub>1)\" + and "P \ C has F,Static:t in D" and nDone: "\sfs. sh\<^sub>1 D \ \(sfs, Done)\" + and init': "P \ \INIT D ([D],False) \ unit,(h\<^sub>1, l\<^sub>1, sh\<^sub>1)\ \ \throw a,s'\" + have v: "v = va" and s\<^sub>1a: "s\<^sub>1 = (h\<^sub>1, l\<^sub>1, sh\<^sub>1)" using eval_final_same[OF val] by auto + then have i: "i = Processing" using iDP shD s\<^sub>1 nDone by simp + then have "(h\<^sub>1, l\<^sub>1, sh\<^sub>1) = s'" using init' init_ProcessingE s\<^sub>1 s\<^sub>1a shD by blast + then show ?thesis using init' init_ProcessingE s\<^sub>1 s\<^sub>1a shD i by blast + next + fix e'' assume val:"P \ \Val v,s\<^sub>1\ \ \throw e'',s'\" + then show ?thesis using eval_final_same[OF val] by simp + next + assume "\b t. \ P \ C has F,b:t in D" + then show ?thesis using SFAssInitRed.hyps(1) by blast + next + fix t assume field: "P \ C has F,NonStatic:t in D" + then show ?thesis using has_field_fun[OF SFAssInitRed.hyps(1) field] by simp + qed + next + fix e assume e': "e' = throw e" + and init: "P \ \INIT D ([D],False) \ unit,(h, l, sh)\ \ \throw e,s'\" + obtain h' l' sh' where s': "s' = (h',l',sh')" by(cases s') + then obtain sfs i where shC: "sh' D = \(sfs, i)\" and iDP: "i = Error" + using init_throw_PD[OF init] by auto + then show ?thesis using SFAssInitRed.hyps(1) SFAssInitRed.hyps(2) SFAssInitThrow Val + by (metis e' init) + qed +next + case (RedSFAssNone C F D v s b) then show ?case + by(cases s) (auto elim!: eval_cases intro: eval_evals.intros eval_finalId) +next + case (RedSFAssNonStatic C F t D v s b) then show ?case + by(cases s) (auto elim!: eval_cases intro: eval_evals.intros eval_finalId) +next + case CallObj + note val_no_step[simp] + from CallObj.prems(2) CallObj show ?case + proof cases + case 2 with CallObj show ?thesis by(fastforce intro!: CallParamsThrow) + next + case 3 with CallObj show ?thesis by(fastforce intro!: CallNull) + next + case 4 with CallObj show ?thesis by(fastforce intro!: CallNone) + next + case 5 with CallObj show ?thesis by(fastforce intro!: CallStatic) + qed(fastforce intro!: CallObjThrow Call)+ +next + case (CallParams es s b es'' s'' b'' v M s') + then obtain h' l' sh' where "s' = (h',l',sh')" by(cases s') + with CallParams show ?case + by(auto elim!: eval_cases intro!: CallNone eval_finalId CallStatic Val) + (auto intro!: CallParamsThrow CallNull Call Val) +next + case (RedCall h a C fs M Ts T pns body D vs l sh b) + have "P \ \addr a,(h,l,sh)\ \ \addr a,(h,l,sh)\" by (rule eval_evals.intros) + moreover + have finals: "finals(map Val vs)" by simp + with finals have "P \ \map Val vs,(h,l,sh)\ [\] \map Val vs,(h,l,sh)\" + by (iprover intro: eval_finalsId) + moreover have "h a = Some (C, fs)" using RedCall by simp + moreover have "method": "P \ C sees M,NonStatic: Ts\T = (pns, body) in D" by fact + moreover have same_len\<^sub>1: "length Ts = length pns" + and this_distinct: "this \ set pns" and fv: "fv (body) \ {this} \ set pns" + using "method" wf by (fastforce dest!:sees_wf_mdecl simp:wf_mdecl_def)+ + have same_len: "length vs = length pns" by fact + moreover + obtain l\<^sub>2' where l\<^sub>2': "l\<^sub>2' = [this\Addr a,pns[\]vs]" by simp + moreover + obtain h\<^sub>3 l\<^sub>3 sh\<^sub>3 where s': "s' = (h\<^sub>3,l\<^sub>3,sh\<^sub>3)" by (cases s') + have eval_blocks: + "P \ \(blocks (this # pns, Class D # Ts, Addr a # vs, body)),(h,l,sh)\ \ \e',s'\" by fact + hence id: "l\<^sub>3 = l" using fv s' same_len\<^sub>1 same_len + by(fastforce elim: eval_closed_lcl_unchanged) + from eval_blocks obtain l\<^sub>3' where "P \ \body,(h,l\<^sub>2',sh)\ \ \e',(h\<^sub>3,l\<^sub>3',sh\<^sub>3)\" + proof - + from same_len\<^sub>1 have "length(this#pns) = length(Class D#Ts)" by simp + moreover from same_len\<^sub>1 same_len + have same_len\<^sub>2: "length (this#pns) = length (Addr a#vs)" by simp + moreover from eval_blocks + have "P \ \blocks (this#pns,Class D#Ts,Addr a#vs,body),(h,l,sh)\ + \\e',(h\<^sub>3,l\<^sub>3,sh\<^sub>3)\" using s' same_len\<^sub>1 same_len\<^sub>2 by simp + ultimately obtain l'' + where "P \ \body,(h,l(this # pns[\]Addr a # vs),sh)\\\e',(h\<^sub>3, l'',sh\<^sub>3)\" + by (blast dest:blocksEval) + from eval_restrict_lcl[OF wf this fv] this_distinct same_len\<^sub>1 same_len + have "P \ \body,(h,[this # pns[\]Addr a # vs],sh)\ \ + \e',(h\<^sub>3, l''|`(set(this#pns)),sh\<^sub>3)\" using wf method + by(simp add:subset_insert_iff insert_Diff_if) + thus ?thesis by(fastforce intro!:that simp add: l\<^sub>2') + qed + ultimately + have "P \ \(addr a)\M(map Val vs),(h,l,sh)\ \ \e',(h\<^sub>3,l,sh\<^sub>3)\" by (rule Call) + with s' id show ?case by simp +next + case RedCallNull + thus ?case + by (fastforce elim: eval_cases intro: eval_evals.intros eval_finalsId) +next + case (RedCallNone h a C fs M vs l sh b) + then have tes: "THROW NoSuchMethodError = e' \ (h,l,sh) = s'" + using eval_final_same by simp + have "P \ \addr a,(h,l,sh)\ \ \addr a,(h,l,sh)\" and "P \ \map Val vs,(h,l,sh)\ [\] \map Val vs,(h,l,sh)\" + using eval_finalId eval_finalsId by auto + then show ?case using RedCallNone CallNone tes by auto +next + case (RedCallStatic h a C fs M Ts T m D vs l sh b) + then have tes: "THROW IncompatibleClassChangeError = e' \ (h,l,sh) = s'" + using eval_final_same by simp + have "P \ \addr a,(h,l,sh)\ \ \addr a,(h,l,sh)\" and "P \ \map Val vs,(h,l,sh)\ [\] \map Val vs,(h,l,sh)\" + using eval_finalId eval_finalsId by auto + then show ?case using RedCallStatic CallStatic tes by fastforce +next + case (SCallParams es s b es'' s'' b' C M s') + obtain h' l' sh' where s'[simp]: "s' = (h',l',sh')" by(cases s') + obtain h l sh where s[simp]: "s = (h,l,sh)" by(cases s) + have es: "map_vals_of es = None" using vals_no_step SCallParams.hyps(1) by (meson not_Some_eq) + have bconf: "P,sh \\<^sub>b (es,b) \" using s SCallParams.prems(1) by (simp add: bconf_SCall[OF es]) + from SCallParams.prems(2) SCallParams bconf show ?case + proof cases + case 2 with SCallParams bconf show ?thesis by(auto intro!: SCallNone) + next + case 3 with SCallParams bconf show ?thesis by(auto intro!: SCallNonStatic) + next + case 4 with SCallParams bconf show ?thesis by(auto intro!: SCallInitThrow) + next + case 5 with SCallParams bconf show ?thesis by(auto intro!: SCallInit) + qed(auto intro!: SCallParamsThrow SCall) +next + case (RedSCall C M Ts T pns body D vs s) + then obtain h l sh where s:"s = (h,l,sh)" by(cases s) + then obtain sfs i where shC: "sh D = \(sfs, i)\" and "i = Done \ i = Processing" + using RedSCall by(auto simp: bconf_def initPD_def dest: sees_method_fun) + have finals: "finals(map Val vs)" by simp + with finals have mVs: "P \ \map Val vs,(h,l,sh)\ [\] \map Val vs,(h,l,sh)\" + by (iprover intro: eval_finalsId) + obtain sfs i where shC: "sh D = \(sfs, i)\" + using RedSCall s by(auto simp: bconf_def initPD_def dest: sees_method_fun) + then have iDP: "i = Done \ i = Processing" using RedSCall s + by (auto simp: bconf_def initPD_def dest: sees_method_fun[OF RedSCall.hyps(1)]) + have "method": "P \ C sees M,Static: Ts\T = (pns, body) in D" by fact + have same_len\<^sub>1: "length Ts = length pns" and fv: "fv (body) \ set pns" + using "method" wf by (fastforce dest!:sees_wf_mdecl simp:wf_mdecl_def)+ + have same_len: "length vs = length pns" by fact + obtain l\<^sub>2' where l\<^sub>2': "l\<^sub>2' = [pns[\]vs]" by simp + obtain h\<^sub>3 l\<^sub>3 sh\<^sub>3 where s': "s' = (h\<^sub>3,l\<^sub>3,sh\<^sub>3)" by (cases s') + have eval_blocks: + "P \ \(blocks (pns, Ts, vs, body)),(h,l,sh)\ \ \e',s'\" using RedSCall.prems(2) s by simp + hence id: "l\<^sub>3 = l" using fv s' same_len\<^sub>1 same_len + by(fastforce elim: eval_closed_lcl_unchanged) + from eval_blocks obtain l\<^sub>3' where body: "P \ \body,(h,l\<^sub>2',sh)\ \ \e',(h\<^sub>3,l\<^sub>3',sh\<^sub>3)\" + proof - + from eval_blocks + have "P \ \blocks (pns,Ts,vs,body),(h,l,sh)\ + \\e',(h\<^sub>3,l\<^sub>3,sh\<^sub>3)\" using s' same_len same_len\<^sub>1 by simp + then obtain l'' + where "P \ \body,(h,l(pns[\]vs),sh)\ \ \e',(h\<^sub>3, l'',sh\<^sub>3)\" + by (blast dest:blocksEval[OF same_len\<^sub>1[THEN sym] same_len[THEN sym]]) + from eval_restrict_lcl[OF wf this fv] same_len\<^sub>1 same_len + have "P \ \body,(h,[pns[\]vs],sh)\ \ \e',(h\<^sub>3, l''|`(set(pns)),sh\<^sub>3)\" using wf method + by(simp add:subset_insert_iff insert_Diff_if) + thus ?thesis by(fastforce intro!:that simp add: l\<^sub>2') + qed + show ?case using iDP + proof(cases i) + case Done + then have shC': "sh D = \(sfs, Done)\ \ M = clinit \ sh D = \(sfs, Processing)\" + using shC by simp + have "P \ \C\\<^sub>sM(map Val vs),(h,l,sh)\ \ \e',(h\<^sub>3,l,sh\<^sub>3)\" + by (rule SCall[OF mVs method shC' same_len l\<^sub>2' body]) + with s s' id show ?thesis by simp + next + case Processing + then have shC': "\sfs. sh D = Some(sfs,Done)" and shP: "sh D = Some(sfs,Processing)" + using shC by simp+ + then have init: "P \ \INIT D ([D],False) \ unit,(h,l,sh)\ \ \unit,(h,l,sh)\" + by(simp add: InitFinal InitProcessing Val) + have "P \ \C\\<^sub>sM(map Val vs),(h,l,sh)\ \ \e',(h\<^sub>3,l,sh\<^sub>3)\" + proof(cases "M = clinit") + case False show ?thesis by(rule SCallInit[OF mVs method shC' False init same_len l\<^sub>2' body]) + next + case True + then have shC': "sh D = \(sfs, Done)\ \ M = clinit \ sh D = \(sfs, Processing)\" + using shC Processing by simp + have "P \ \C\\<^sub>sM(map Val vs),(h,l,sh)\ \ \e',(h\<^sub>3,l,sh\<^sub>3)\" + by (rule SCall[OF mVs method shC' same_len l\<^sub>2' body]) + with s s' id show ?thesis by simp + qed + with s s' id show ?thesis by simp + qed(auto) +next + case (SCallInitRed C M Ts T pns body D sh vs h l) + then have seq: "P \ \(INIT D ([D],False) \ unit);; C\\<^sub>sM(map Val vs),(h, l, sh)\ \ \e',s'\" + using eval_init_seq by simp + then show ?case + proof(rule eval_cases(14)) \ \ Seq \ + fix v' s\<^sub>1 assume init: "P \ \INIT D ([D],False) \ unit,(h, l, sh)\ \ \Val v',s\<^sub>1\" + and call: "P \ \C\\<^sub>sM(map Val vs),s\<^sub>1\ \ \e',s'\" + obtain h\<^sub>1 l\<^sub>1 sh\<^sub>1 where s\<^sub>1: "s\<^sub>1 = (h\<^sub>1,l\<^sub>1,sh\<^sub>1)" by(cases s\<^sub>1) + then obtain sfs i where shD: "sh\<^sub>1 D = \(sfs, i)\" and iDP: "i = Done \ i = Processing" + using init_Val_PD[OF init] by auto + show ?thesis + proof(rule eval_cases(12)[OF call]) \ \ SCall \ + fix vsa ex es' assume "P \ \map Val vs,s\<^sub>1\ [\] \map Val vsa @ throw ex # es',s'\" + then show ?thesis using evals_finals_same by (meson finals_def map_Val_nthrow_neq) + next + assume "\b Ts T a ba x. \ P \ C sees M, b : Ts\T = (a, ba) in x" + then show ?thesis using SCallInitRed.hyps(1) by auto + next + fix Ts T m D assume "P \ C sees M, NonStatic : Ts\T = m in D" + then show ?thesis using sees_method_fun[OF SCallInitRed.hyps(1)] by blast + next + fix vsa h1 l1 sh1 Ts T pns body D' a + assume "e' = throw a" and vals: "P \ \map Val vs,s\<^sub>1\ [\] \map Val vsa,(h1, l1, sh1)\" + and method: "P \ C sees M, Static : Ts\T = (pns, body) in D'" + and nDone: "\sfs. sh1 D' \ \(sfs, Done)\" + and init': "P \ \INIT D' ([D'],False) \ unit,(h1, l1, sh1)\ \ \throw a,s'\" + have vs: "vs = vsa" and s\<^sub>1a: "s\<^sub>1 = (h1, l1, sh1)" + using evals_finals_same[OF _ vals] map_Val_eq by auto + have D: "D = D'" using sees_method_fun[OF SCallInitRed.hyps(1) method] by simp + then have i: "i = Processing" using iDP shD s\<^sub>1 s\<^sub>1a nDone by simp + then show ?thesis using D init' init_ProcessingE s\<^sub>1 s\<^sub>1a shD by blast + next + fix vsa h1 l1 sh1 Ts T pns' body' D' v' h\<^sub>2 l\<^sub>2 sh\<^sub>2 h\<^sub>3 l\<^sub>3 sh\<^sub>3 + assume s': "s' = (h\<^sub>3, l\<^sub>2, sh\<^sub>3)" + and vals: "P \ \map Val vs,s\<^sub>1\ [\] \map Val vsa,(h1, l1, sh1)\" + and method: "P \ C sees M, Static : Ts\T = (pns', body') in D'" + and nDone: "\sfs. sh1 D' \ \(sfs, Done)\" + and init': "P \ \INIT D' ([D'],False) \ unit,(h1, l1, sh1)\ \ \Val v',(h\<^sub>2, l\<^sub>2, sh\<^sub>2)\" + and len: "length vsa = length pns'" + and bstep: "P \ \body',(h\<^sub>2, [pns' [\] vsa], sh\<^sub>2)\ \ \e',(h\<^sub>3, l\<^sub>3, sh\<^sub>3)\" + have vs: "vs = vsa" and s\<^sub>1a: "s\<^sub>1 = (h1, l1, sh1)" + using evals_finals_same[OF _ vals] map_Val_eq by auto + have D: "D = D'" and pns: "pns = pns'" and body: "body = body'" + using sees_method_fun[OF SCallInitRed.hyps(1) method] by auto + then have i: "i = Processing" using iDP shD s\<^sub>1 s\<^sub>1a nDone by simp + then have s2: "(h\<^sub>2, l\<^sub>2, sh\<^sub>2) = s\<^sub>1" using D init' init_ProcessingE s\<^sub>1 s\<^sub>1a shD by blast + then show ?thesis + using eval_finalId SCallInit[OF eval_finalsId[of "map Val vs" P "(h,l,sh)"] + SCallInitRed.hyps(1)] init init' len bstep nDone D pns body s' s\<^sub>1 s\<^sub>1a shD vals vs + SCallInitRed.hyps(2-3) s2 by auto + next + fix vsa h\<^sub>2 l\<^sub>2 sh\<^sub>2 Ts T pns' body' D' sfs h\<^sub>3 l\<^sub>3 sh\<^sub>3 + assume s': "s' = (h\<^sub>3, l\<^sub>2, sh\<^sub>3)" and vals: "P \ \map Val vs,s\<^sub>1\ [\] \map Val vsa,(h\<^sub>2, l\<^sub>2, sh\<^sub>2)\" + and method: "P \ C sees M, Static : Ts\T = (pns', body') in D'" + and "sh\<^sub>2 D' = \(sfs, Done)\ \ M = clinit \ sh\<^sub>2 D' = \(sfs, Processing)\" + and len: "length vsa = length pns'" + and bstep: "P \ \body',(h\<^sub>2, [pns' [\] vsa], sh\<^sub>2)\ \ \e',(h\<^sub>3, l\<^sub>3, sh\<^sub>3)\" + have vs: "vs = vsa" and s\<^sub>1a: "s\<^sub>1 = (h\<^sub>2, l\<^sub>2, sh\<^sub>2)" + using evals_finals_same[OF _ vals] map_Val_eq by auto + have D: "D = D'" and pns: "pns = pns'" and body: "body = body'" + using sees_method_fun[OF SCallInitRed.hyps(1) method] by auto + then show ?thesis using SCallInit[OF eval_finalsId[of "map Val vs" P "(h,l,sh)"] + SCallInitRed.hyps(1)] bstep SCallInitRed.hyps(2-3) len s' s\<^sub>1a vals vs init by auto + qed + next + fix e assume e': "e' = throw e" + and init: "P \ \INIT D ([D],False) \ unit,(h, l, sh)\ \ \throw e,s'\" + obtain h' l' sh' where s': "s' = (h',l',sh')" by(cases s') + then obtain sfs i where shC: "sh' D = \(sfs, i)\" and iDP: "i = Error" + using init_throw_PD[OF init] by auto + then show ?thesis using SCallInitRed.hyps(2-3) init e' + SCallInitThrow[OF eval_finalsId[of "map Val vs" _] SCallInitRed.hyps(1)] + by auto + qed +next + case (RedSCallNone C M vs s b) + then have tes: "THROW NoSuchMethodError = e' \ s = s'" + using eval_final_same by simp + have "P \ \map Val vs,s\ [\] \map Val vs,s\" using eval_finalsId by simp + then show ?case using RedSCallNone eval_evals.SCallNone tes by auto +next + case (RedSCallNonStatic C M Ts T m D vs s b) + then have tes: "THROW IncompatibleClassChangeError = e' \ s = s'" + using eval_final_same by simp + have "P \ \map Val vs,s\ [\] \map Val vs,s\" using eval_finalsId by simp + then show ?case using RedSCallNonStatic eval_evals.SCallNonStatic tes by auto +next + case InitBlockRed + thus ?case + by (fastforce elim!: eval_cases intro: eval_evals.intros eval_finalId + simp: assigned_def map_upd_triv fun_upd_same) +next + case (RedInitBlock V T v u s b) + then have "P \ \Val u,s\ \ \e',s'\" by simp + then obtain s': "s'=s" and e': "e'=Val u" by cases simp + obtain h l sh where s: "s=(h,l,sh)" by (cases s) + have "P \ \{V:T :=Val v; Val u},(h,l,sh)\ \ \Val u,(h, (l(V\v))(V:=l V), sh)\" + by (fastforce intro!: eval_evals.intros) + then have "P \ \{V:T := Val v; Val u},s\ \ \e',s'\" using s s' e' by simp + then show ?case by simp +next + case BlockRedNone + thus ?case + by (fastforce elim!: eval_cases intro: eval_evals.intros + simp add: fun_upd_same fun_upd_idem) +next + case BlockRedSome + thus ?case + by (fastforce elim!: eval_cases intro: eval_evals.intros + simp add: fun_upd_same fun_upd_idem) +next + case (RedBlock V T v s b) + then have "P \ \Val v,s\ \ \e',s'\" by simp + then obtain s': "s'=s" and e': "e'=Val v" + by cases simp + obtain h l sh where s: "s=(h,l,sh)" by (cases s) + have "P \ \Val v,(h,l(V:=None),sh)\ \ \Val v,(h,l(V:=None),sh)\" + by (rule eval_evals.intros) + hence "P \ \{V:T;Val v},(h,l,sh)\ \ \Val v,(h,(l(V:=None))(V:=l V),sh)\" + by (rule eval_evals.Block) + then have "P \ \{V:T; Val v},s\ \ \e',s'\" using s s' e' by simp + then show ?case by simp +next + case (SeqRed e s b e1 s1 b1 e\<^sub>2) show ?case + proof(cases "val_of e") + case None show ?thesis + proof(cases "lass_val_of e") + case lNone:None + then have bconf: "P,shp s \\<^sub>b (e,b) \" using SeqRed.prems(1) None by simp + then show ?thesis using SeqRed using seq_ext by fastforce + next + case (Some p) + obtain V' v' where p: "p = (V',v')" and e: "e = V':=Val v'" + using lass_val_of_spec[OF Some] by(cases p, auto) + obtain h l sh h' l' sh' where s: "s = (h,l,sh)" and s1: "s1 = (h',l',sh')" by(cases s, cases s1) + then have red: "P \ \e,(h,l,sh),b\ \ \e1,(h',l',sh'),b1\" using SeqRed.hyps(1) by simp + then have s\<^sub>1': "e1 = unit \ h' = h \ l' = l(V' \ v') \ sh' = sh" + using lass_val_of_red[OF Some red] p e by simp + then have eval: "P \ \e,s\ \ \e1,s1\" using e s s1 LAss Val by auto + then show ?thesis + by (metis SeqRed.prems(2) eval_final eval_final_same seq_ext) + qed + next + case (Some a) then show ?thesis using SeqRed.hyps(1) val_no_step by blast + qed +next + case RedSeq + thus ?case + by (fastforce elim: eval_cases intro: eval_evals.intros) +next + case CondRed + thus ?case + by (fastforce elim: eval_cases intro: eval_evals.intros simp: val_no_step) +next + case RedCondT + thus ?case + by (fastforce elim: eval_cases intro: eval_evals.intros) +next + case RedCondF + thus ?case + by (fastforce elim: eval_cases intro: eval_evals.intros) +next + case RedWhile + thus ?case + by (auto simp add: unfold_while intro:eval_evals.intros elim:eval_cases) +next + case ThrowRed then show ?case by(fastforce elim: eval_cases simp: eval_evals.intros) +next + case RedThrowNull + thus ?case + by (fastforce elim: eval_cases intro: eval_evals.intros) +next + case TryRed thus ?case + by(fastforce elim: eval_cases intro: eval_evals.intros) +next + case RedTryCatch + thus ?case + by (fastforce elim: eval_cases intro: eval_evals.intros) +next + case (RedTryFail s a D fs C V e\<^sub>2 b) + thus ?case + by (cases s)(auto elim!: eval_cases intro: eval_evals.intros) +next + case ListRed1 + thus ?case + by (fastforce elim: evals_cases intro: eval_evals.intros simp: val_no_step) +next + case ListRed2 + thus ?case + by (fastforce elim!: evals_cases eval_cases + intro: eval_evals.intros eval_finalId) +next + case (RedInit e1 C b s1 b') then show ?case using InitFinal by simp +next + case (InitNoneRed sh C C' Cs e h l b) + show ?case using InitNone InitNoneRed.hyps InitNoneRed.prems(2) by auto +next + case (RedInitDone sh C sfs C' Cs e h l b) + show ?case using InitDone RedInitDone.hyps RedInitDone.prems(2) by auto +next + case (RedInitProcessing sh C sfs C' Cs e h l b) + show ?case using InitProcessing RedInitProcessing.hyps RedInitProcessing.prems(2) by auto +next + case (RedInitError sh C sfs C' Cs e h l b) + show ?case using InitError RedInitError.hyps RedInitError.prems(2) by auto +next + case (InitObjectRed sh C sfs sh' C' Cs e h l b) show ?case using InitObject InitObjectRed by auto +next + case (InitNonObjectSuperRed sh C sfs D r sh' C' Cs e h l b) + show ?case using InitNonObject InitNonObjectSuperRed by auto +next + case (RedInitRInit C' C Cs e h l sh b) + show ?case using InitRInit RedInitRInit by auto +next + case (RInitRed e s b e'' s'' b'' C Cs e\<^sub>0) + then have IH: "\e' s'. P \ \e'',s''\ \ \e',s'\ \ P \ \e,s\ \ \e',s'\" by simp + show ?case using RInitRed rinit_ext[OF IH] by simp +next + case (RedRInit sh C sfs i sh' C' Cs v e h l b s' e') + then have init: "P \ \(INIT C' (Cs,True) \ e), (h, l, sh(C \ (sfs, Done)))\ \ \e',s'\" + using RedRInit by simp + then show ?case using RInit RedRInit.hyps(1) RedRInit.hyps(3) Val by fastforce +next + case BinOpThrow2 + thus ?case + by (fastforce elim: eval_cases intro: eval_evals.intros) +next + case FAssThrow2 + thus ?case + by (fastforce elim: eval_cases intro: eval_evals.intros) +next + case SFAssThrow + then show ?case + by (fastforce elim: eval_cases intro: eval_evals.intros) +next + case (CallThrowParams es vs e es' v M s b) + have val: "P \ \Val v,s\ \ \Val v,s\" by (rule eval_evals.intros) + have eval_e: "P \ \throw (e),s\ \ \e',s'\" using CallThrowParams by simp + then obtain xa where e': "e' = Throw xa" by (cases) (auto dest!: eval_final) + with list_eval_Throw [OF eval_e] + have vals: "P \ \es,s\ [\] \map Val vs @ Throw xa # es',s'\" + using CallThrowParams.hyps(1) eval_e list_eval_Throw by blast + then have "P \ \Val v\M(es),s\ \ \Throw xa,s'\" + using eval_evals.CallParamsThrow[OF val vals] by simp + thus ?case using e' by simp +next + case (SCallThrowParams es vs e es' C M s b) + have eval_e: "P \ \throw (e),s\ \ \e',s'\" using SCallThrowParams by simp + then obtain xa where e': "e' = Throw xa" by (cases) (auto dest!: eval_final) + then have "P \ \es,s\ [\] \map Val vs @ Throw xa # es',s'\" + using SCallThrowParams.hyps(1) eval_e list_eval_Throw by blast + then have "P \ \C\\<^sub>sM(es),s\ \ \Throw xa,s'\" + by (rule eval_evals.SCallParamsThrow) + thus ?case using e' by simp +next + case (BlockThrow V T a s b) + then have "P \ \Throw a, s\ \ \e',s'\" by simp + then obtain s': "s' = s" and e': "e' = Throw a" + by cases (auto elim!:eval_cases) + obtain h l sh where s: "s=(h,l,sh)" by (cases s) + have "P \ \Throw a, (h,l(V:=None),sh)\ \ \Throw a, (h,l(V:=None),sh)\" + by (simp add:eval_evals.intros eval_finalId) + hence "P\\{V:T;Throw a},(h,l,sh)\ \ \Throw a, (h,(l(V:=None))(V:=l V),sh)\" + by (rule eval_evals.Block) + then have "P \ \{V:T; Throw a},s\ \ \e',s'\" using s s' e' by simp + then show ?case by simp +next + case (InitBlockThrow V T v a s b) + then have "P \ \Throw a,s\ \ \e',s'\" by simp + then obtain s': "s' = s" and e': "e' = Throw a" + by cases (auto elim!:eval_cases) + obtain h l sh where s: "s = (h,l,sh)" by (cases s) + have "P \ \{V:T :=Val v; Throw a},(h,l,sh)\ \ \Throw a, (h, (l(V\v))(V:=l V),sh)\" + by(fastforce intro:eval_evals.intros) + then have "P \ \{V:T := Val v; Throw a},s\ \ \e',s'\" using s s' e' by simp + then show ?case by simp +next + case (RInitInitThrow sh C sfs i sh' a D Cs e h l b) + have IH: "\e' s'. P \ \RI (D,Throw a) ; Cs \ e,(h, l, sh(C \ (sfs, Error)))\ \ \e',s'\ \ + P \ \RI (C,Throw a) ; D # Cs \ e,(h, l, sh)\ \ \e',s'\" + using RInitInitFail[OF eval_finalId] RInitInitThrow by simp + then show ?case using RInitInitThrow.hyps(2) RInitInitThrow.prems(2) by auto +next + case (RInitThrow sh C sfs i sh' a e h l b) + then have e': "e' = Throw a" and s': "s' = (h,l,sh')" + using eval_final_same final_def by fastforce+ + show ?case using RInitFailFinal RInitThrow.hyps(1) RInitThrow.hyps(2) e' eval_finalId s' by auto +qed(auto elim: eval_cases simp: eval_evals.intros) +(*>*) + +(*<*) +(* ... und wieder anschalten: *) +declare split_paired_All [simp] split_paired_Ex [simp] +(*>*) + +text \ Its extension to @{text"\*"}: \ + +lemma extend_eval: +assumes wf: "wwf_J_prog P" +and reds: "P \ \e,s,b\ \* \e'',s'',b''\" and eval_rest: "P \ \e'',s''\ \ \e',s'\" +and iconf: "iconf (shp s) e" and bconf: "P,shp s \\<^sub>b (e::expr,b) \" +shows "P \ \e,s\ \ \e',s'\" +(*<*) +using reds eval_rest iconf bconf +proof (induct rule: converse_rtrancl_induct3) + case refl then show ?case by simp +next + case (step e1 s1 b1 e2 s2 b2) + then have ic: "iconf (shp s2) e2" using Red_preserves_iconf local.wf by blast + then have ec: "P,shp s2 \\<^sub>b (e2,b2) \" + using Red_preserves_bconf local.wf step.hyps(1) step.prems(2) step.prems(3) by blast + show ?case using step ic ec extend_1_eval[OF wf step.hyps(1)] by simp +qed +(*>*) + + +lemma extend_evals: +assumes wf: "wwf_J_prog P" +and reds: "P \ \es,s,b\ [\]* \es'',s'',b''\" and eval_rest: "P \ \es'',s''\ [\] \es',s'\" +and iconf: "iconfs (shp s) es" and bconf: "P,shp s \\<^sub>b (es::expr list,b) \" +shows "P \ \es,s\ [\] \es',s'\" +(*<*) +using reds eval_rest iconf bconf +proof (induct rule: converse_rtrancl_induct3) + case refl then show ?case by simp +next + case (step es1 s1 b1 es2 s2 b2) + then have ic: "iconfs (shp s2) es2" using Reds_preserves_iconf local.wf by blast + then have ec: "P,shp s2 \\<^sub>b (es2,b2) \" + using Reds_preserves_bconf local.wf step.hyps(1) step.prems(2) step.prems(3) by blast + show ?case using step ic ec extend_1_evals[OF wf step.hyps(1)] by simp +qed +(*>*) + +text \ Finally, small step semantics can be simulated by big step semantics: +\ + +theorem +assumes wf: "wwf_J_prog P" +shows small_by_big: + "\P \ \e,s,b\ \* \e',s',b'\; iconf (shp s) e; P,shp s \\<^sub>b (e,b) \; final e'\ + \ P \ \e,s\ \ \e',s'\" +and "\P \ \es,s,b\ [\]* \es',s',b'\; iconfs (shp s) es; P,shp s \\<^sub>b (es,b) \; finals es'\ + \ P \ \es,s\ [\] \es',s'\" +(*<*) +proof - + note wf + moreover assume "P \ \e,s,b\ \* \e',s',b'\" + moreover assume "final e'" + then have "P \ \e',s'\ \ \e',s'\" + by (simp add: eval_finalId) + moreover assume "iconf (shp s) e" + moreover assume "P,shp s \\<^sub>b (e,b) \" + ultimately show "P \ \e,s\ \ \e',s'\" + by (rule extend_eval) +next + assume fins: "finals es'" + note wf + moreover assume "P \ \es,s,b\ [\]* \es',s',b'\" + moreover have "P \ \es',s'\ [\] \es',s'\" using fins + by (rule eval_finalsId) + moreover assume "iconfs (shp s) es" + moreover assume "P,shp s \\<^sub>b (es,b) \" + ultimately show "P \ \es,s\ [\] \es',s'\" + by (rule extend_evals) +qed +(*>*) + +subsection "Equivalence" + +text\ And now, the crowning achievement: \ + +corollary big_iff_small: +"\ wwf_J_prog P; iconf (shp s) e; P,shp s \\<^sub>b (e::expr,b) \ \ + \ P \ \e,s\ \ \e',s'\ = (P \ \e,s,b\ \* \e',s',False\ \ final e')" +(*<*)by(blast dest: big_by_small eval_final small_by_big)(*>*) + +corollary big_iff_small_WT: + "wwf_J_prog P \ P,E \ e::T \ P,shp s \\<^sub>b (e,b) \ \ + P \ \e,s\ \ \e',s'\ = (P \ \e,s,b\ \* \e',s',False\ \ final e')" +(*<*)by(blast dest: big_iff_small WT_nsub_RI nsub_RI_iconf)(*>*) + + +subsection \ Lifting type safety to @{text"\"} \ + +text\ \dots and now to the big step semantics, just for fun. \ + +lemma eval_preserves_sconf: +fixes s::state and s'::state +assumes "wf_J_prog P" and "P \ \e,s\ \ \e',s'\" and "iconf (shp s) e" + and "P,E \ e::T" and "P,E \ s\" +shows "P,E \ s'\" +(*<*) +proof - + have "P,shp s \\<^sub>b (e,False) \" by(simp add: bconf_def) + with assms show ?thesis + by(blast intro:Red_preserves_sconf Red_preserves_iconf Red_preserves_bconf big_by_small + WT_implies_WTrt wf_prog_wwf_prog) +qed +(*>*) + + +lemma eval_preserves_type: +fixes s::state +assumes wf: "wf_J_prog P" + and "P \ \e,s\ \ \e',s'\" and "P,E \ s\" and "iconf (shp s) e" and "P,E \ e::T" +shows "\T'. P \ T' \ T \ P,E,hp s',shp s' \ e':T'" +(*<*) +proof - + have "P,shp s \\<^sub>b (e,False) \" by(simp add: bconf_def) + with assms show ?thesis by(blast dest:big_by_small[OF wf_prog_wwf_prog[OF wf]] + WT_implies_WTrt Red_preserves_type[OF wf]) +qed +(*>*) + + +end diff --git a/thys/JinjaDCI/J/Examples.thy b/thys/JinjaDCI/J/Examples.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/J/Examples.thy @@ -0,0 +1,123 @@ +(* Title: Jinja/J/Examples.thy + + Author: Christoph Petzinger + Copyright 2004 Technische Universitaet Muenchen +*) +(* + Expanded to include support for static fields and methods. + Susannah Mansky + 2017, UIUC +*) + +section \ Example Expressions \ + +theory Examples imports Expr begin + +(* HERE: none of the below currently have static methods or fields; these should be + tested at some point! *) + +definition classObject::"J_mb cdecl" +where + "classObject == (''Object'','''',[],[])" + + +definition classI :: "J_mb cdecl" +where + "classI == + (''I'', Object, + [], + [(''mult'',NonStatic,[Integer,Integer],Integer,[''i'',''j''], + if (Var ''i'' \Eq\ Val(Intg 0)) (Val(Intg 0)) + else Var ''j'' \Add\ + Var this \ ''mult''([Var ''i'' \Add\ Val(Intg (- 1)),Var ''j''])) + ])" + + +definition classL :: "J_mb cdecl" +where + "classL == + (''L'', Object, + [(''F'',NonStatic,Integer), (''N'',NonStatic,Class ''L'')], + [(''app'',NonStatic,[Class ''L''],Void,[''l''], + if (Var this \ ''N''{''L''} \Eq\ null) + (Var this \ ''N''{''L''} := Var ''l'') + else (Var this \ ''N''{''L''}) \ ''app''([Var ''l''])) + ])" + + +definition testExpr_BuildList :: "expr" +where + "testExpr_BuildList == + {''l1'':Class ''L'' := new ''L''; + Var ''l1''\''F''{''L''} := Val(Intg 1);; + {''l2'':Class ''L'' := new ''L''; + Var ''l2''\ ''F''{''L''} := Val(Intg 2);; + {''l3'':Class ''L'' := new ''L''; + Var ''l3''\ ''F''{''L''} := Val(Intg 3);; + {''l4'':Class ''L'' := new ''L''; + Var ''l4''\ ''F''{''L''} := Val(Intg 4);; + Var ''l1''\''app''([Var ''l2'']);; + Var ''l1''\''app''([Var ''l3'']);; + Var ''l1''\''app''([Var ''l4''])}}}}" + +definition testExpr1 ::"expr" +where + "testExpr1 == Val(Intg 5)" +definition testExpr2 ::"expr" +where + "testExpr2 == BinOp (Val(Intg 5)) Add (Val(Intg 6))" +definition testExpr3 ::"expr" +where + "testExpr3 == BinOp (Var ''V'') Add (Val(Intg 6))" +definition testExpr4 ::"expr" +where + "testExpr4 == ''V'' := Val(Intg 6)" +definition testExpr5 ::"expr" +where + "testExpr5 == new ''Object'';; {''V'':(Class ''C'') := new ''C''; Var ''V''\''F''{''C''} := Val(Intg 42)}" +definition testExpr6 ::"expr" +where + "testExpr6 == {''V'':(Class ''I'') := new ''I''; Var ''V''\''mult''([Val(Intg 40),Val(Intg 4)])}" + +definition mb_isNull:: "expr" +where + "mb_isNull == Var this \ ''test''{''A''} \Eq\ null " + +definition mb_add:: "expr" +where + "mb_add == (Var this \ ''int''{''A''} :=( Var this \ ''int''{''A''} \Add\ Var ''i''));; (Var this \ ''int''{''A''})" + +definition mb_mult_cond:: "expr" +where + "mb_mult_cond == (Var ''j'' \Eq\ Val (Intg 0)) \Eq\ Val (Bool False)" + +definition mb_mult_block:: "expr" +where + "mb_mult_block == ''temp'':=(Var ''temp'' \Add\ Var ''i'');;''j'':=(Var ''j'' \Add\ Val (Intg (- 1)))" + +definition mb_mult:: "expr" +where + "mb_mult == {''temp'':Integer:=Val (Intg 0); While (mb_mult_cond) mb_mult_block;; ( Var this \ ''int''{''A''} := Var ''temp'';; Var ''temp'' )}" + +definition classA:: "J_mb cdecl" +where + "classA == + (''A'', Object, + [(''int'',NonStatic,Integer), + (''test'',NonStatic,Class ''A'') ], + [(''isNull'',NonStatic,[],Boolean,[], mb_isNull), + (''add'',NonStatic,[Integer],Integer,[''i''], mb_add), + (''mult'',NonStatic,[Integer,Integer],Integer,[''i'',''j''], mb_mult) ])" + + +definition testExpr_ClassA:: "expr" +where + "testExpr_ClassA == + {''A1'':Class ''A'':= new ''A''; + {''A2'':Class ''A'':= new ''A''; + {''testint'':Integer:= Val (Intg 5); + (Var ''A2''\ ''int''{''A''} := (Var ''A1''\ ''add''([Var ''testint''])));; + (Var ''A2''\ ''int''{''A''} := (Var ''A1''\ ''add''([Var ''testint''])));; + Var ''A2''\ ''mult''([Var ''A2''\ ''int''{''A''}, Var ''testint'']) }}}" + +end diff --git a/thys/JinjaDCI/J/Expr.thy b/thys/JinjaDCI/J/Expr.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/J/Expr.thy @@ -0,0 +1,572 @@ +(* Title: JinjaDCI/J/Expr.thy + Author: Tobias Nipkow, Susannah Mansky + Copyright 2003 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory J/Expr.thy by Tobias Nipkow +*) + +section \ Expressions \ + +theory Expr +imports "../Common/Exceptions" +begin + +datatype bop = Eq | Add \ \names of binary operations\ + +datatype 'a exp + = new cname \ \class instance creation\ + | Cast cname "('a exp)" \ \type cast\ + | Val val \ \value\ + | BinOp "('a exp)" bop "('a exp)" ("_ \_\ _" [80,0,81] 80) \ \binary operation\ + | Var 'a \ \local variable (incl. parameter)\ + | LAss 'a "('a exp)" ("_:=_" [90,90]90) \ \local assignment\ + | FAcc "('a exp)" vname cname ("_\_{_}" [10,90,99]90) \ \field access\ + | SFAcc cname vname cname ("_\\<^sub>s_{_}" [10,90,99]90) \ \static field access\ + | FAss "('a exp)" vname cname "('a exp)" ("_\_{_} := _" [10,90,99,90]90) \ \field assignment\ + | SFAss cname vname cname "('a exp)" ("_\\<^sub>s_{_} := _" [10,90,99,90]90) \ \static field assignment\ + | Call "('a exp)" mname "('a exp list)" ("_\_'(_')" [90,99,0] 90) \ \method call\ + | SCall cname mname "('a exp list)" ("_\\<^sub>s_'(_')" [90,99,0] 90) \ \static method call\ + | Block 'a ty "('a exp)" ("'{_:_; _}") + | Seq "('a exp)" "('a exp)" ("_;;/ _" [61,60]60) + | Cond "('a exp)" "('a exp)" "('a exp)" ("if '(_') _/ else _" [80,79,79]70) + | While "('a exp)" "('a exp)" ("while '(_') _" [80,79]70) + | throw "('a exp)" + | TryCatch "('a exp)" cname 'a "('a exp)" ("try _/ catch'(_ _') _" [0,99,80,79] 70) + | INIT cname "cname list" bool "('a exp)" ("INIT _ '(_,_') \ _" [60,60,60,60] 60) \ \internal initialization command: class, list of superclasses to initialize, preparation flag; command on hold\ + | RI cname "('a exp)" "cname list" "('a exp)" ("RI '(_,_') ; _ \ _" [60,60,60,60] 60) \ \running of the initialization procedure for class with expression, classes still to initialize command on hold\ + +type_synonym + expr = "vname exp" \ \Jinja expression\ +type_synonym + J_mb = "vname list \ expr" \ \Jinja method body: parameter names and expression\ +type_synonym + J_prog = "J_mb prog" \ \Jinja program\ + +type_synonym + init_stack = "expr list \ bool" \ \Stack of expressions waiting on initialization in small step; indicator boolean True if current expression has been init checked\ + +text\The semantics of binary operators: \ + +fun binop :: "bop \ val \ val \ val option" where + "binop(Eq,v\<^sub>1,v\<^sub>2) = Some(Bool (v\<^sub>1 = v\<^sub>2))" +| "binop(Add,Intg i\<^sub>1,Intg i\<^sub>2) = Some(Intg(i\<^sub>1+i\<^sub>2))" +| "binop(bop,v\<^sub>1,v\<^sub>2) = None" + +lemma [simp]: + "(binop(Add,v\<^sub>1,v\<^sub>2) = Some v) = (\i\<^sub>1 i\<^sub>2. v\<^sub>1 = Intg i\<^sub>1 \ v\<^sub>2 = Intg i\<^sub>2 \ v = Intg(i\<^sub>1+i\<^sub>2))" +(*<*) +apply(cases v\<^sub>1) +apply auto +apply(cases v\<^sub>2) +apply auto +done +(*>*) + + +lemma map_Val_throw_eq: + "map Val vs @ throw ex # es = map Val vs' @ throw ex' # es' \ ex = ex'" +apply(induct vs arbitrary: vs') + apply(case_tac vs', auto)+ +done + +lemma map_Val_nthrow_neq: + "map Val vs = map Val vs' @ throw ex' # es' \ False" +apply(induct vs arbitrary: vs') + apply(case_tac vs', auto)+ +done + +lemma map_Val_eq: + "map Val vs = map Val vs' \ vs = vs'" +apply(induct vs arbitrary: vs') + apply(case_tac vs', auto)+ +done + + +lemma init_rhs_neq [simp]: "e \ INIT C (Cs,b) \ e" +proof - + have "size e \ size (INIT C (Cs,b) \ e)" by auto + then show ?thesis by fastforce +qed + +lemma init_rhs_neq' [simp]: "INIT C (Cs,b) \ e \ e" +proof - + have "size e \ size (INIT C (Cs,b) \ e)" by auto + then show ?thesis by fastforce +qed + +lemma ri_rhs_neq [simp]: "e \ RI(C,e');Cs \ e" +proof - + have "size e \ size (RI(C,e');Cs \ e)" by auto + then show ?thesis by fastforce +qed + +lemma ri_rhs_neq' [simp]: "RI(C,e');Cs \ e \ e" +proof - + have "size e \ size (RI(C,e');Cs \ e)" by auto + then show ?thesis by fastforce +qed + +subsection "Syntactic sugar" + +abbreviation (input) + InitBlock:: "'a \ ty \ 'a exp \ 'a exp \ 'a exp" ("(1'{_:_ := _;/ _})") where + "InitBlock V T e1 e2 == {V:T; V := e1;; e2}" + +abbreviation unit where "unit == Val Unit" +abbreviation null where "null == Val Null" +abbreviation "addr a == Val(Addr a)" +abbreviation "true == Val(Bool True)" +abbreviation "false == Val(Bool False)" + +abbreviation + Throw :: "addr \ 'a exp" where + "Throw a == throw(Val(Addr a))" + +abbreviation + THROW :: "cname \ 'a exp" where + "THROW xc == Throw(addr_of_sys_xcpt xc)" + + +subsection\Free Variables\ + +primrec fv :: "expr \ vname set" and fvs :: "expr list \ vname set" where + "fv(new C) = {}" +| "fv(Cast C e) = fv e" +| "fv(Val v) = {}" +| "fv(e\<^sub>1 \bop\ e\<^sub>2) = fv e\<^sub>1 \ fv e\<^sub>2" +| "fv(Var V) = {V}" +| "fv(LAss V e) = {V} \ fv e" +| "fv(e\F{D}) = fv e" +| "fv(C\\<^sub>sF{D}) = {}" +| "fv(e\<^sub>1\F{D}:=e\<^sub>2) = fv e\<^sub>1 \ fv e\<^sub>2" +| "fv(C\\<^sub>sF{D}:=e\<^sub>2) = fv e\<^sub>2" +| "fv(e\M(es)) = fv e \ fvs es" +| "fv(C\\<^sub>sM(es)) = fvs es" +| "fv({V:T; e}) = fv e - {V}" +| "fv(e\<^sub>1;;e\<^sub>2) = fv e\<^sub>1 \ fv e\<^sub>2" +| "fv(if (b) e\<^sub>1 else e\<^sub>2) = fv b \ fv e\<^sub>1 \ fv e\<^sub>2" +| "fv(while (b) e) = fv b \ fv e" +| "fv(throw e) = fv e" +| "fv(try e\<^sub>1 catch(C V) e\<^sub>2) = fv e\<^sub>1 \ (fv e\<^sub>2 - {V})" +| "fv(INIT C (Cs,b) \ e) = fv e" +| "fv(RI (C,e);Cs \ e') = fv e \ fv e'" +| "fvs([]) = {}" +| "fvs(e#es) = fv e \ fvs es" + +lemma [simp]: "fvs(es\<^sub>1 @ es\<^sub>2) = fvs es\<^sub>1 \ fvs es\<^sub>2" +(*<*)by (induct es\<^sub>1 type:list) auto(*>*) + +lemma [simp]: "fvs(map Val vs) = {}" +(*<*)by (induct vs) auto(*>*) + + +subsection\Accessing expression constructor arguments\ + +fun val_of :: "'a exp \ val option" where +"val_of (Val v) = Some v" | +"val_of _ = None" + +lemma val_of_spec: "val_of e = Some v \ e = Val v" +proof(cases e) qed(auto) + +fun lass_val_of :: "'a exp \ ('a \ val) option" where +"lass_val_of (V:=Val v) = Some (V, v)" | +"lass_val_of _ = None" + +lemma lass_val_of_spec: +assumes "lass_val_of e = \a\" +shows "e = (fst a:=Val (snd a))" +using assms proof(cases e) + case (LAss V e') then show ?thesis using assms proof(cases e')qed(auto) +qed(auto) + +fun map_vals_of :: "'a exp list \ val list option" where +"map_vals_of (e#es) = (case val_of e of Some v \ (case map_vals_of es of Some vs \ Some (v#vs) + | _ \ None) + | _ \ None)" | +"map_vals_of [] = Some []" + +lemma map_vals_of_spec: "map_vals_of es = Some vs \ es = map Val vs" +proof(induct es arbitrary: vs) qed(auto simp: val_of_spec) + +lemma map_vals_of_Vals[simp]: "map_vals_of (map Val vs) = \vs\" by(induct vs, auto) + +lemma map_vals_of_throw[simp]: + "map_vals_of (map Val vs @ throw e # es') = None" + by(induct vs, auto) + + +fun bool_of :: "'a exp \ bool option" where +"bool_of true = Some True" | +"bool_of false = Some False" | +"bool_of _ = None" + +lemma bool_of_specT: +assumes "bool_of e = Some True" shows "e = true" +proof - + have "bool_of e = Some True" by fact + then show ?thesis + proof(cases e) + case (Val x3) with assms show ?thesis + proof(cases x3) + case (Bool x) with assms Val show ?thesis + proof(cases x)qed(auto) + qed(simp_all) + qed(auto) +qed + +lemma bool_of_specF: +assumes "bool_of e = Some False" shows "e = false" +proof - + have "bool_of e = Some False" by fact + then show ?thesis + proof(cases e) + case (Val x3) with assms show ?thesis + proof(cases x3) + case (Bool x) with assms Val show ?thesis + proof(cases x)qed(auto) + qed(simp_all) + qed(auto) +qed + + +fun throw_of :: "'a exp \ 'a exp option" where +"throw_of (throw e') = Some e'" | +"throw_of _ = None" + +lemma throw_of_spec: "throw_of e = Some e' \ e = throw e'" +proof(cases e) qed(auto) + +fun init_exp_of :: "'a exp \ 'a exp option" where +"init_exp_of (INIT C (Cs,b) \ e) = Some e" | +"init_exp_of (RI(C,e');Cs \ e) = Some e" | +"init_exp_of _ = None" + +lemma init_exp_of_neq [simp]: "init_exp_of e = \e'\ \ e' \ e" by(cases e, auto) +lemma init_exp_of_neq'[simp]: "init_exp_of e = \e'\ \ e \ e'" by(cases e, auto) + + +subsection\Class initialization\ + +text \ This section defines a few functions that return information + about an expression's current initialization status. \ + + \ \ True if expression contains @{text INIT}, @{text RI}, or a call to a static method @{term clinit} \ +primrec sub_RI :: "'a exp \ bool" and sub_RIs :: "'a exp list \ bool" where + "sub_RI(new C) = False" +| "sub_RI(Cast C e) = sub_RI e" +| "sub_RI(Val v) = False" +| "sub_RI(e\<^sub>1 \bop\ e\<^sub>2) = (sub_RI e\<^sub>1 \ sub_RI e\<^sub>2)" +| "sub_RI(Var V) = False" +| "sub_RI(LAss V e) = sub_RI e" +| "sub_RI(e\F{D}) = sub_RI e" +| "sub_RI(C\\<^sub>sF{D}) = False" +| "sub_RI(e\<^sub>1\F{D}:=e\<^sub>2) = (sub_RI e\<^sub>1 \ sub_RI e\<^sub>2)" +| "sub_RI(C\\<^sub>sF{D}:=e\<^sub>2) = sub_RI e\<^sub>2" +| "sub_RI(e\M(es)) = (sub_RI e \ sub_RIs es)" +| "sub_RI(C\\<^sub>sM(es)) = (M = clinit \ sub_RIs es)" +| "sub_RI({V:T; e}) = sub_RI e" +| "sub_RI(e\<^sub>1;;e\<^sub>2) = (sub_RI e\<^sub>1 \ sub_RI e\<^sub>2)" +| "sub_RI(if (b) e\<^sub>1 else e\<^sub>2) = (sub_RI b \ sub_RI e\<^sub>1 \ sub_RI e\<^sub>2)" +| "sub_RI(while (b) e) = (sub_RI b \ sub_RI e)" +| "sub_RI(throw e) = sub_RI e" +| "sub_RI(try e\<^sub>1 catch(C V) e\<^sub>2) = (sub_RI e\<^sub>1 \ sub_RI e\<^sub>2)" +| "sub_RI(INIT C (Cs,b) \ e) = True" +| "sub_RI(RI (C,e);Cs \ e') = True" +| "sub_RIs([]) = False" +| "sub_RIs(e#es) = (sub_RI e \ sub_RIs es)" + + +lemmas sub_RI_sub_RIs_induct = sub_RI.induct sub_RIs.induct + +lemma nsub_RIs_def[simp]: + "\sub_RIs es \ \e \ set es. \sub_RI e" + by(induct es, auto) + +lemma sub_RI_base: + "e = INIT C (Cs, b) \ e' \ e = RI(C,e\<^sub>0);Cs \ e' \ sub_RI e" + by(cases e, auto) + +lemma nsub_RI_Vals[simp]: "\sub_RIs (map Val vs)" + by(induct vs, auto) + +lemma lass_val_of_nsub_RI: "lass_val_of e = \a\ \ \sub_RI e" + by(drule lass_val_of_spec, simp) + + + \ \ is not currently initializing class @{text C'} (point past checking flag) \ +primrec not_init :: "cname \ 'a exp \ bool" and not_inits :: "cname \ 'a exp list \ bool" where + "not_init C' (new C) = True" +| "not_init C' (Cast C e) = not_init C' e" +| "not_init C' (Val v) = True" +| "not_init C' (e\<^sub>1 \bop\ e\<^sub>2) = (not_init C' e\<^sub>1 \ not_init C' e\<^sub>2)" +| "not_init C' (Var V) = True" +| "not_init C' (LAss V e) = not_init C' e" +| "not_init C' (e\F{D}) = not_init C' e" +| "not_init C' (C\\<^sub>sF{D}) = True" +| "not_init C' (e\<^sub>1\F{D}:=e\<^sub>2) = (not_init C' e\<^sub>1 \ not_init C' e\<^sub>2)" +| "not_init C' (C\\<^sub>sF{D}:=e\<^sub>2) = not_init C' e\<^sub>2" +| "not_init C' (e\M(es)) = (not_init C' e \ not_inits C' es)" +| "not_init C' (C\\<^sub>sM(es)) = not_inits C' es" +| "not_init C' ({V:T; e}) = not_init C' e" +| "not_init C' (e\<^sub>1;;e\<^sub>2) = (not_init C' e\<^sub>1 \ not_init C' e\<^sub>2)" +| "not_init C' (if (b) e\<^sub>1 else e\<^sub>2) = (not_init C' b \ not_init C' e\<^sub>1 \ not_init C' e\<^sub>2)" +| "not_init C' (while (b) e) = (not_init C' b \ not_init C' e)" +| "not_init C' (throw e) = not_init C' e" +| "not_init C' (try e\<^sub>1 catch(C V) e\<^sub>2) = (not_init C' e\<^sub>1 \ not_init C' e\<^sub>2)" +| "not_init C' (INIT C (Cs,b) \ e) = ((b \ Cs = Nil \ C' \ hd Cs) \ C' \ set(tl Cs) \ not_init C' e)" +| "not_init C' (RI (C,e);Cs \ e') = (C' \ set (C#Cs) \ not_init C' e \ not_init C' e')" +| "not_inits C' ([]) = True" +| "not_inits C' (e#es) = (not_init C' e \ not_inits C' es)" + +lemma not_inits_def'[simp]: + "not_inits C es \ \e \ set es. not_init C e" + by(induct es, auto) + +lemma nsub_RIs_not_inits_aux: "\e \ set es. \sub_RI e \ not_init C e + \ \sub_RIs es \ not_inits C es" + by(induct es, auto) + +lemma nsub_RI_not_init: "\sub_RI e \ not_init C e" +proof(induct e) qed(auto intro: nsub_RIs_not_inits_aux) + +lemma nsub_RIs_not_inits: "\sub_RIs es \ not_inits C es" +apply(rule nsub_RIs_not_inits_aux) + apply(simp_all add: nsub_RI_not_init) +done + +subsection\Subexpressions\ + + \ \ all strictly smaller subexpressions; does not include self \ + primrec subexp :: "'a exp \ 'a exp set" and subexps :: "'a exp list \ 'a exp set" where + "subexp(new C) = {}" +| "subexp(Cast C e) = {e} \ subexp e" +| "subexp(Val v) = {}" +| "subexp(e\<^sub>1 \bop\ e\<^sub>2) = {e\<^sub>1, e\<^sub>2} \ subexp e\<^sub>1 \ subexp e\<^sub>2" +| "subexp(Var V) = {}" +| "subexp(LAss V e) = {e} \ subexp e" +| "subexp(e\F{D}) = {e} \ subexp e" +| "subexp(C\\<^sub>sF{D}) = {}" +| "subexp(e\<^sub>1\F{D}:=e\<^sub>2) = {e\<^sub>1, e\<^sub>2} \ subexp e\<^sub>1 \ subexp e\<^sub>2" +| "subexp(C\\<^sub>sF{D}:=e\<^sub>2) = {e\<^sub>2} \subexp e\<^sub>2" +| "subexp(e\M(es)) = {e} \ set es \ subexp e \ subexps es" +| "subexp(C\\<^sub>sM(es)) = set es \ subexps es" +| "subexp({V:T; e}) = {e} \ subexp e" +| "subexp(e\<^sub>1;;e\<^sub>2) = {e\<^sub>1, e\<^sub>2} \ subexp e\<^sub>1 \ subexp e\<^sub>2" +| "subexp(if (b) e\<^sub>1 else e\<^sub>2) = {b, e\<^sub>1, e\<^sub>2} \ subexp b \ subexp e\<^sub>1 \ subexp e\<^sub>2" +| "subexp(while (b) e) = {b, e} \ subexp b \ subexp e" +| "subexp(throw e) = {e} \ subexp e" +| "subexp(try e\<^sub>1 catch(C V) e\<^sub>2) = {e\<^sub>1, e\<^sub>2} \ subexp e\<^sub>1 \ subexp e\<^sub>2" +| "subexp(INIT C (Cs,b) \ e) = {e} \ subexp e" +| "subexp(RI (C,e);Cs \ e') = {e, e'} \ subexp e \ subexp e'" +| "subexps([]) = {}" +| "subexps(e#es) = {e} \ subexp e \ subexps es" + + +lemmas subexp_subexps_induct = subexp.induct subexps.induct + +abbreviation subexp_of :: "'a exp \ 'a exp \ bool" where + "subexp_of e e' \ e \ subexp e'" + +lemma subexp_size_le: + "(e' \ subexp e \ size e' < size e) \ (e' \ subexps es \ size e' < size_list size es)" +proof(induct rule: subexp_subexps.induct) + case Call:11 then show ?case using not_less_eq size_list_estimation by fastforce +next + case SCall:12 then show ?case using not_less_eq size_list_estimation by fastforce +qed(auto) + +lemma subexps_def2: "subexps es = set es \ (\e \ set es. subexp e)" by(induct es, auto) + + \ \ strong induction \ +lemma shows subexp_induct[consumes 1]: +"(\e. subexp e = {} \ R e) \ (\e. (\e'. e' \ subexp e \ R e') \ R e) + \ (\es. (\e'. e' \ subexps es \ R e') \ Rs es) \ (\e'. e' \ subexp e \ R e') \ R e" +and subexps_induct[consumes 1]: + "(\es. subexps es = {} \ Rs es) \ (\e. (\e'. e' \ subexp e \ R e') \ R e) + \ (\es. (\e'. e' \ subexps es \ R e') \ Rs es) \ (\e'. e' \ subexps es \ R e') \ Rs es" +proof(induct rule: subexp_subexps_induct) + case (Cast x1 x2) + then have "(\e'. subexp_of e' x2 \ R e') \ R x2" by fast + then have "(\e'. subexp_of e' (Cast x1 x2) \ R e')" by auto + then show ?case using Cast.prems(2) by fast +next + case (BinOp x1 x2 x3) + then have "(\e'. subexp_of e' x1 \ R e') \ R x1" and "(\e'. subexp_of e' x3 \ R e') \ R x3" + by fast+ + then have "(\e'. subexp_of e' (x1 \x2\ x3) \ R e')" by auto + then show ?case using BinOp.prems(2) by fast +next + case (LAss x1 x2) + then have "(\e'. subexp_of e' x2 \ R e') \ R x2" by fast + then have "(\e'. subexp_of e' (LAss x1 x2) \ R e')" by auto + then show ?case using LAss.prems(2) by fast +next + case (FAcc x1 x2 x3) + then have "(\e'. subexp_of e' x1 \ R e') \ R x1" by fast + then have "(\e'. subexp_of e' (x1\x2{x3}) \ R e')" by auto + then show ?case using FAcc.prems(2) by fast +next + case (FAss x1 x2 x3 x4) + then have "(\e'. subexp_of e' x1 \ R e') \ R x1" and "(\e'. subexp_of e' x4 \ R e') \ R x4" + by fast+ + then have "(\e'. subexp_of e' (x1\x2{x3} := x4) \ R e')" by auto + then show ?case using FAss.prems(2) by fast +next + case (SFAss x1 x2 x3 x4) + then have "(\e'. subexp_of e' x4 \ R e') \ R x4" by fast + then have "(\e'. subexp_of e' (x1\\<^sub>sx2{x3} := x4) \ R e')" by auto + then show ?case using SFAss.prems(2) by fast +next + case (Call x1 x2 x3) + then have "(\e'. subexp_of e' x1 \ R e') \ R x1" and "(\e'. e' \ subexps x3 \ R e') \ Rs x3" + by fast+ + then have "(\e'. subexp_of e' (x1\x2(x3)) \ R e')" using subexps_def2 by auto + then show ?case using Call.prems(2) by fast +next + case (SCall x1 x2 x3) + then have "(\e'. e' \ subexps x3 \ R e') \ Rs x3" by fast + then have "(\e'. subexp_of e' (x1\\<^sub>sx2(x3)) \ R e')" using subexps_def2 by auto + then show ?case using SCall.prems(2) by fast +next + case (Block x1 x2 x3) + then have "(\e'. subexp_of e' x3 \ R e') \ R x3" by fast + then have "(\e'. subexp_of e' {x1:x2; x3} \ R e')" by auto + then show ?case using Block.prems(2) by fast +next + case (Seq x1 x2) + then have "(\e'. subexp_of e' x1 \ R e') \ R x1" and "(\e'. subexp_of e' x2 \ R e') \ R x2" + by fast+ + then have "(\e'. subexp_of e' (x1;; x2) \ R e')" by auto + then show ?case using Seq.prems(2) by fast +next + case (Cond x1 x2 x3) + then have "(\e'. subexp_of e' x1 \ R e') \ R x1" and "(\e'. subexp_of e' x2 \ R e') \ R x2" + and "(\e'. subexp_of e' x3 \ R e') \ R x3" by fast+ + then have "(\e'. subexp_of e' (if (x1) x2 else x3) \ R e')" by auto + then show ?case using Cond.prems(2) by fast +next + case (While x1 x2) + then have "(\e'. subexp_of e' x1 \ R e') \ R x1" and "(\e'. subexp_of e' x2 \ R e') \ R x2" + by fast+ + then have "(\e'. subexp_of e' (while (x1) x2) \ R e')" by auto + then show ?case using While.prems(2) by fast +next + case (throw x) + then have "(\e'. subexp_of e' x \ R e') \ R x" by fast + then have "(\e'. subexp_of e' (throw x) \ R e')" by auto + then show ?case using throw.prems(2) by fast +next + case (TryCatch x1 x2 x3 x4) + then have "(\e'. subexp_of e' x1 \ R e') \ R x1" and "(\e'. subexp_of e' x4 \ R e') \ R x4" + by fast+ + then have "(\e'. subexp_of e' (try x1 catch(x2 x3) x4) \ R e')" by auto + then show ?case using TryCatch.prems(2) by fast +next + case (INIT x1 x2 x3 x4) + then have "(\e'. subexp_of e' x4 \ R e') \ R x4" by fast + then have "(\e'. subexp_of e' (INIT x1 (x2,x3) \ x4) \ R e')" by auto + then show ?case using INIT.prems(2) by fast +next + case (RI x1 x2 x3 x4) + then have "(\e'. subexp_of e' x2 \ R e') \ R x2" and "(\e'. subexp_of e' x4 \ R e') \ R x4" + by fast+ + then have "(\e'. subexp_of e' (RI (x1,x2) ; x3 \ x4) \ R e')" by auto + then show ?case using RI.prems(2) by fast +next + case (Cons_exp x1 x2) + then have "(\e'. subexp_of e' x1 \ R e') \ R x1" and "(\e'. e' \ subexps x2 \ R e') \ Rs x2" + by fast+ + then have "(\e'. e' \ subexps (x1 # x2) \ R e')" using subexps_def2 by auto + then show ?case using Cons_exp.prems(3) by fast +qed(auto) + + +subsection"Final expressions" +(* these definitions and most of the lemmas were in BigStep.thy in the original Jinja *) + +definition final :: "'a exp \ bool" +where + "final e \ (\v. e = Val v) \ (\a. e = Throw a)" + +definition finals:: "'a exp list \ bool" +where + "finals es \ (\vs. es = map Val vs) \ (\vs a es'. es = map Val vs @ Throw a # es')" + +lemma [simp]: "final(Val v)" +(*<*)by(simp add:final_def)(*>*) + +lemma [simp]: "final(throw e) = (\a. e = addr a)" +(*<*)by(simp add:final_def)(*>*) + +lemma finalE: "\ final e; \v. e = Val v \ R; \a. e = Throw a \ R \ \ R" +(*<*)by(auto simp:final_def)(*>*) + +lemma final_fv[iff]: "final e \ fv e = {}" + by (auto simp: final_def) + +lemma finalsE: + "\ finals es; \vs. es = map Val vs \ R; \vs a es'. es = map Val vs @ Throw a # es' \ R \ \ R" +(*<*)by(auto simp:finals_def)(*>*) + +lemma [iff]: "finals []" +(*<*)by(simp add:finals_def)(*>*) + +lemma [iff]: "finals (Val v # es) = finals es" +(*<*) +apply(clarsimp simp add: finals_def) +apply(rule iffI) + apply(erule disjE) + apply simp + apply(rule disjI2) + apply clarsimp + apply(case_tac vs) + apply simp + apply fastforce +apply(erule disjE) + apply clarsimp +apply(rule disjI2) +apply clarsimp +apply(rule_tac x = "v#vs" in exI) +apply simp +done +(*>*) + +lemma finals_app_map[iff]: "finals (map Val vs @ es) = finals es" +(*<*)by(induct_tac vs, auto)(*>*) + +lemma [iff]: "finals (map Val vs)" +(*<*)using finals_app_map[of vs "[]"]by(simp)(*>*) + +lemma [iff]: "finals (throw e # es) = (\a. e = addr a)" +(*<*) +apply(simp add:finals_def) +apply(rule iffI) + apply clarsimp + apply(case_tac vs) + apply simp + apply fastforce +apply clarsimp +apply(rule_tac x = "[]" in exI) +apply simp +done +(*>*) + +lemma not_finals_ConsI: "\ final e \ \ finals(e#es)" + (*<*) +apply(clarsimp simp add:finals_def final_def) +apply(case_tac vs) +apply auto +done +(*>*) + +lemma not_finals_ConsI2: "e = Val v \ \ finals es \ \ finals(e#es)" + (*<*) +apply(clarsimp simp add:finals_def final_def) +apply(case_tac vs) +apply auto +done +(*>*) + + +end diff --git a/thys/JinjaDCI/J/JWellForm.thy b/thys/JinjaDCI/J/JWellForm.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/J/JWellForm.thy @@ -0,0 +1,82 @@ +(* Title: JinjaDCI/J/JWellForm.thy + + Author: Tobias Nipkow, Susannah Mansky + Copyright 2003 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory J/JWellForm.thy by Tobias Nipkow +*) + +section \ Well-formedness Constraints \ + +theory JWellForm +imports "../Common/WellForm" WWellForm WellType DefAss +begin + +definition wf_J_mdecl :: "J_prog \ cname \ J_mb mdecl \ bool" +where + "wf_J_mdecl P C \ \(M,b,Ts,T,(pns,body)). + length Ts = length pns \ + distinct pns \ + \sub_RI body \ + (case b of + NonStatic \ this \ set pns \ + (\T'. P,[this\Class C,pns[\]Ts] \ body :: T' \ P \ T' \ T) \ + \ body \{this} \ set pns\ + | Static \ (\T'. P,[pns[\]Ts] \ body :: T' \ P \ T' \ T) \ + \ body \set pns\)" + +lemma wf_J_mdecl_NonStatic[simp]: + "wf_J_mdecl P C (M,NonStatic,Ts,T,pns,body) \ + (length Ts = length pns \ + distinct pns \ + \sub_RI body \ + this \ set pns \ + (\T'. P,[this\Class C,pns[\]Ts] \ body :: T' \ P \ T' \ T) \ + \ body \{this} \ set pns\)" +(*<*)by(simp add:wf_J_mdecl_def)(*>*) + +lemma wf_J_mdecl_Static[simp]: + "wf_J_mdecl P C (M,Static,Ts,T,pns,body) \ + (length Ts = length pns \ + distinct pns \ + \sub_RI body \ + (\T'. P,[pns[\]Ts] \ body :: T' \ P \ T' \ T) \ + \ body \set pns\)" +(*<*)by(simp add:wf_J_mdecl_def)(*>*) + + +abbreviation + wf_J_prog :: "J_prog \ bool" where + "wf_J_prog == wf_prog wf_J_mdecl" + +lemma wf_J_prog_wf_J_mdecl: + "\ wf_J_prog P; (C, D, fds, mths) \ set P; jmdcl \ set mths \ + \ wf_J_mdecl P C jmdcl" +(*<*) +apply (simp add: wf_prog_def) +apply (simp add: wf_cdecl_def) +apply (erule conjE)+ +apply (drule bspec, assumption) +apply simp +apply (erule conjE)+ +apply (drule bspec, assumption) +apply (simp add: wf_mdecl_def split_beta) +done +(*>*) + +lemma wf_mdecl_wwf_mdecl: "wf_J_mdecl P C Md \ wwf_J_mdecl P C Md" +(*<*) +apply(clarsimp simp:wwf_J_mdecl_def) apply(rename_tac M b Ts T pns body) +apply (case_tac b) + by (fastforce dest!:WT_fv)+ +(*>*) + +lemma wf_prog_wwf_prog: "wf_J_prog P \ wwf_J_prog P" +(*<*) +apply(simp add:wf_prog_def wf_cdecl_def wf_mdecl_def) +apply(fast intro:wf_mdecl_wwf_mdecl) +done +(*>*) + + +end diff --git a/thys/JinjaDCI/J/Progress.thy b/thys/JinjaDCI/J/Progress.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/J/Progress.thy @@ -0,0 +1,887 @@ +(* Title: JinjaDCI/J/Progress.thy + + Author: Tobias Nipkow, Susannah Mansky + Copyright 2003 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory J/Progress.thy by Tobias Nipkow +*) + +section \ Progress of Small Step Semantics \ + +theory Progress +imports WellTypeRT DefAss "../Common/Conform" EConform +begin + +lemma final_addrE: + "\ P,E,h,sh \ e : Class C; final e; + \a. e = addr a \ R; + \a. e = Throw a \ R \ \ R" +(*<*)by(auto simp:final_def)(*>*) + + +lemma finalRefE: + "\ P,E,h,sh \ e : T; is_refT T; final e; + e = null \ R; + \a C. \ e = addr a; T = Class C \ \ R; + \a. e = Throw a \ R \ \ R" +(*<*)by(auto simp:final_def is_refT_def)(*>*) + + +text\ Derivation of new induction scheme for well typing: \ + +inductive + WTrt' :: "[J_prog,heap,sheap,env,expr,ty] \ bool" + and WTrts' :: "[J_prog,heap,sheap,env,expr list, ty list] \ bool" + and WTrt2' :: "[J_prog,env,heap,sheap,expr,ty] \ bool" + ("_,_,_,_ \ _ :'' _" [51,51,51,51]50) + and WTrts2' :: "[J_prog,env,heap,sheap,expr list, ty list] \ bool" + ("_,_,_,_ \ _ [:''] _" [51,51,51,51]50) + for P :: J_prog and h :: heap and sh :: sheap +where + "P,E,h,sh \ e :' T \ WTrt' P h sh E e T" +| "P,E,h,sh \ es [:'] Ts \ WTrts' P h sh E es Ts" + +| "is_class P C \ P,E,h,sh \ new C :' Class C" +| "\ P,E,h,sh \ e :' T; is_refT T; is_class P C \ + \ P,E,h,sh \ Cast C e :' Class C" +| "typeof\<^bsub>h\<^esub> v = Some T \ P,E,h,sh \ Val v :' T" +| "E v = Some T \ P,E,h,sh \ Var v :' T" +| "\ P,E,h,sh \ e\<^sub>1 :' T\<^sub>1; P,E,h,sh \ e\<^sub>2 :' T\<^sub>2 \ + \ P,E,h,sh \ e\<^sub>1 \Eq\ e\<^sub>2 :' Boolean" +| "\ P,E,h,sh \ e\<^sub>1 :' Integer; P,E,h,sh \ e\<^sub>2 :' Integer \ + \ P,E,h,sh \ e\<^sub>1 \Add\ e\<^sub>2 :' Integer" +| "\ P,E,h,sh \ Var V :' T; P,E,h,sh \ e :' T'; P \ T' \ T \ + \ P,E,h,sh \ V:=e :' Void" +| "\ P,E,h,sh \ e :' Class C; P \ C has F,NonStatic:T in D \ \ P,E,h,sh \ e\F{D} :' T" +| "P,E,h,sh \ e :' NT \ P,E,h,sh \ e\F{D} :' T" +| "\ P \ C has F,Static:T in D \ \ P,E,h,sh \ C\\<^sub>sF{D} :' T" +| "\ P,E,h,sh \ e\<^sub>1 :' Class C; P \ C has F,NonStatic:T in D; + P,E,h,sh \ e\<^sub>2 :' T\<^sub>2; P \ T\<^sub>2 \ T \ + \ P,E,h,sh \ e\<^sub>1\F{D}:=e\<^sub>2 :' Void" +| "\ P,E,h,sh \ e\<^sub>1:'NT; P,E,h,sh \ e\<^sub>2 :' T\<^sub>2 \ \ P,E,h,sh \ e\<^sub>1\F{D}:=e\<^sub>2 :' Void" +| "\ P \ C has F,Static:T in D; + P,E,h,sh \ e\<^sub>2 :' T\<^sub>2; P \ T\<^sub>2 \ T \ + \ P,E,h,sh \ C\\<^sub>sF{D}:=e\<^sub>2 :' Void" +| "\ P,E,h,sh \ e :' Class C; P \ C sees M,NonStatic:Ts \ T = (pns,body) in D; + P,E,h,sh \ es [:'] Ts'; P \ Ts' [\] Ts \ + \ P,E,h,sh \ e\M(es) :' T" +| "\ P,E,h,sh \ e :' NT; P,E,h,sh \ es [:'] Ts \ \ P,E,h,sh \ e\M(es) :' T" +| "\ P \ C sees M,Static:Ts \ T = (pns,body) in D; + P,E,h,sh \ es [:'] Ts'; P \ Ts' [\] Ts; + M = clinit \ sh D = \(sfs,Processing)\ \ es = map Val vs \ + \ P,E,h,sh \ C\\<^sub>sM(es) :' T" +| "P,E,h,sh \ [] [:'] []" +| "\ P,E,h,sh \ e :' T; P,E,h,sh \ es [:'] Ts \ \ P,E,h,sh \ e#es [:'] T#Ts" +| "\ typeof\<^bsub>h\<^esub> v = Some T\<^sub>1; P \ T\<^sub>1 \ T; P,E(V\T),h,sh \ e\<^sub>2 :' T\<^sub>2 \ + \ P,E,h,sh \ {V:T := Val v; e\<^sub>2} :' T\<^sub>2" +| "\ P,E(V\T),h,sh \ e :' T'; \ assigned V e \ \ P,E,h,sh \ {V:T; e} :' T'" +| "\ P,E,h,sh \ e\<^sub>1:' T\<^sub>1; P,E,h,sh \ e\<^sub>2:'T\<^sub>2 \ \ P,E,h,sh \ e\<^sub>1;;e\<^sub>2 :' T\<^sub>2" +| "\ P,E,h,sh \ e :' Boolean; P,E,h,sh \ e\<^sub>1:' T\<^sub>1; P,E,h,sh \ e\<^sub>2:' T\<^sub>2; + P \ T\<^sub>1 \ T\<^sub>2 \ P \ T\<^sub>2 \ T\<^sub>1; + P \ T\<^sub>1 \ T\<^sub>2 \ T = T\<^sub>2; P \ T\<^sub>2 \ T\<^sub>1 \ T = T\<^sub>1 \ + \ P,E,h,sh \ if (e) e\<^sub>1 else e\<^sub>2 :' T" +| "\ P,E,h,sh \ e :' Boolean; P,E,h,sh \ c:' T \ + \ P,E,h,sh \ while(e) c :' Void" +| "\ P,E,h,sh \ e :' T\<^sub>r; is_refT T\<^sub>r \ \ P,E,h,sh \ throw e :' T" +| "\ P,E,h,sh \ e\<^sub>1 :' T\<^sub>1; P,E(V \ Class C),h,sh \ e\<^sub>2 :' T\<^sub>2; P \ T\<^sub>1 \ T\<^sub>2 \ + \ P,E,h,sh \ try e\<^sub>1 catch(C V) e\<^sub>2 :' T\<^sub>2" +| "\ P,E,h,sh \ e :' T; \C' \ set (C#Cs). is_class P C'; \sub_RI e; + \C' \ set (tl Cs). \sfs. sh C' = \(sfs,Processing)\; + b \ (\C' \ set Cs. \sfs. sh C' = \(sfs,Processing)\); + distinct Cs; supercls_lst P Cs \ \ P,E,h,sh \ INIT C (Cs, b) \ e :' T" +| "\ P,E,h,sh \ e :' T; P,E,h,sh \ e' :' T'; \C' \ set (C#Cs). is_class P C'; \sub_RI e'; + \C' \ set (C#Cs). not_init C' e; + \C' \ set Cs. \sfs. sh C' = \(sfs,Processing)\; + \sfs. sh C = \(sfs, Processing)\ \ (sh C = \(sfs, Error)\ \ e = THROW NoClassDefFoundError); + distinct (C#Cs); supercls_lst P (C#Cs) \ + \ P,E,h,sh \ RI(C, e);Cs \ e' :' T'" + +(*<*) +lemmas WTrt'_induct = WTrt'_WTrts'.induct [split_format (complete)] + and WTrt'_inducts = WTrt'_WTrts'.inducts [split_format (complete)] + +inductive_cases WTrt'_elim_cases[elim!]: + "P,E,h,sh \ V :=e :' T" +(*>*) + +lemma [iff]: "P,E,h,sh \ e\<^sub>1;;e\<^sub>2 :' T\<^sub>2 = (\T\<^sub>1. P,E,h,sh \ e\<^sub>1:' T\<^sub>1 \ P,E,h,sh \ e\<^sub>2:' T\<^sub>2)" +(*<*) +apply(rule iffI) +apply (auto elim: WTrt'.cases intro!:WTrt'_WTrts'.intros) +done +(*>*) + +lemma [iff]: "P,E,h,sh \ Val v :' T = (typeof\<^bsub>h\<^esub> v = Some T)" +(*<*) +apply(rule iffI) +apply (auto elim: WTrt'.cases intro!:WTrt'_WTrts'.intros) +done +(*>*) + +lemma [iff]: "P,E,h,sh \ Var v :' T = (E v = Some T)" +(*<*) +apply(rule iffI) +apply (auto elim: WTrt'.cases intro!:WTrt'_WTrts'.intros) +done +(*>*) + + +lemma wt_wt': "P,E,h,sh \ e : T \ P,E,h,sh \ e :' T" +and wts_wts': "P,E,h,sh \ es [:] Ts \ P,E,h,sh \ es [:'] Ts" +(*<*) +apply (induct rule:WTrt_inducts) +prefer 17 +apply(case_tac "assigned V e") +apply(clarsimp simp add:fun_upd_same assigned_def simp del:fun_upd_apply) +apply(erule (2) WTrt'_WTrts'.intros) +apply(erule (1) WTrt'_WTrts'.intros) +apply(blast intro:WTrt'_WTrts'.intros)+ +done +(*>*) + + +lemma wt'_wt: "P,E,h,sh \ e :' T \ P,E,h,sh \ e : T" +and wts'_wts: "P,E,h,sh \ es [:'] Ts \ P,E,h,sh \ es [:] Ts" +(*<*) +apply (induct rule:WTrt'_inducts) +prefer 19 +apply(rule WTrt_WTrts.intros) +apply(rule WTrt_WTrts.intros) +apply(rule WTrt_WTrts.intros) +apply simp +apply(erule (2) WTrt_WTrts.intros) +apply(blast intro:WTrt_WTrts.intros)+ +done +(*>*) + + +corollary wt'_iff_wt: "(P,E,h,sh \ e :' T) = (P,E,h,sh \ e : T)" +(*<*)by(blast intro:wt_wt' wt'_wt)(*>*) + + +corollary wts'_iff_wts: "(P,E,h,sh \ es [:'] Ts) = (P,E,h,sh \ es [:] Ts)" +(*<*)by(blast intro:wts_wts' wts'_wts)(*>*) + +(*<*) +lemmas WTrt_inducts2 = WTrt'_inducts [unfolded wt'_iff_wt wts'_iff_wts, + case_names WTrtNew WTrtCast WTrtVal WTrtVar WTrtBinOpEq WTrtBinOpAdd WTrtLAss + WTrtFAcc WTrtFAccNT WTrtSFAcc WTrtFAss WTrtFAssNT WTrtSFAss WTrtCall WTrtCallNT WTrtSCall + WTrtNil WTrtCons WTrtInitBlock WTrtBlock WTrtSeq WTrtCond WTrtWhile WTrtThrow WTrtTry + WTrtInit WTrtRI, consumes 1] +(*>*) + +theorem assumes wf: "wwf_J_prog P" and hconf: "P \ h \" and shconf: "P,h \\<^sub>s sh \" +shows progress: "P,E,h,sh \ e : T \ + (\l. \ \ e \dom l\; P,sh \\<^sub>b (e,b) \; \ final e \ \ \e' s' b'. P \ \e,(h,l,sh),b\ \ \e',s',b'\)" +and "P,E,h,sh \ es [:] Ts \ + (\l. \ \s es \dom l\; P,sh \\<^sub>b (es,b) \; \ finals es \ \ \es' s' b'. P \ \es,(h,l,sh),b\ [\] \es',s',b'\)" +(*<*) +proof (induct rule:WTrt_inducts2) + case (WTrtNew C) show ?case + proof (cases b) + case True then show ?thesis + proof cases + assume "\a. h a = None" + with assms WTrtNew True show ?thesis + by (fastforce del:exE intro!:RedNew simp add:new_Addr_def + elim!:wf_Fields_Ex[THEN exE]) + next + assume "\(\a. h a = None)" + with assms WTrtNew True show ?thesis + by(fastforce intro:RedNewFail simp:new_Addr_def) + qed + next + case False then show ?thesis + proof cases + assume "\sfs. sh C = Some (sfs, Done)" + with assms WTrtNew False show ?thesis + by(fastforce intro:NewInitDoneRed simp:new_Addr_def) + next + assume "\sfs. sh C = Some (sfs, Done)" + with assms WTrtNew False show ?thesis + by(fastforce intro:NewInitRed simp:new_Addr_def) + qed + qed +next + case (WTrtCast E e T C) + have wte: "P,E,h,sh \ e : T" and ref: "is_refT T" + and IH: "\l. \\ e \dom l\; P,sh \\<^sub>b (e,b) \; \ final e\ + \ \e' s' b'. P \ \e,(h,l,sh),b\ \ \e',s',b'\" + and D: "\ (Cast C e) \dom l\" + and castconf: "P,sh \\<^sub>b (Cast C e,b) \" by fact+ + from D have De: "\ e \dom l\" by auto + have bconf: "P,sh \\<^sub>b (e,b) \" using castconf bconf_Cast by fast + show ?case + proof cases + assume "final e" + with wte ref show ?thesis + proof (rule finalRefE) + assume "e = null" thus ?case by(fastforce intro:RedCastNull) + next + fix D a assume A: "T = Class D" "e = addr a" + show ?thesis + proof cases + assume "P \ D \\<^sup>* C" + thus ?thesis using A wte by(fastforce intro:RedCast) + next + assume "\ P \ D \\<^sup>* C" + thus ?thesis using A wte by(fastforce elim!:RedCastFail) + qed + next + fix a assume "e = Throw a" + thus ?thesis by(blast intro!:red_reds.CastThrow) + qed + next + assume nf: "\ final e" + from IH[OF De bconf nf] show ?thesis by (blast intro:CastRed) + qed +next + case WTrtVal thus ?case by(simp add:final_def) +next + case WTrtVar thus ?case by(fastforce intro:RedVar simp:hyper_isin_def) +next + case (WTrtBinOpEq E e1 T1 e2 T2) show ?case + proof cases + assume "final e1" + thus ?thesis + proof (rule finalE) + fix v1 assume eV[simp]: "e1 = Val v1" + show ?thesis + proof cases + assume "final e2" + thus ?thesis + proof (rule finalE) + fix v2 assume "e2 = Val v2" + thus ?thesis using WTrtBinOpEq by(fastforce intro:RedBinOp) + next + fix a assume "e2 = Throw a" + thus ?thesis using eV by(blast intro:red_reds.BinOpThrow2) + qed + next + assume nf: "\ final e2" + then have "P,sh \\<^sub>b (e2,b) \" using WTrtBinOpEq.prems(2) by(simp add:bconf_BinOp) + with WTrtBinOpEq nf show ?thesis + by simp (fast intro!:BinOpRed2) + qed + next + fix a assume "e1 = Throw a" + thus ?thesis by (fast intro:red_reds.BinOpThrow1) + qed + next + assume nf: "\ final e1" + then have e1: "val_of e1 = None" proof(cases e1)qed(auto) + then have "P,sh \\<^sub>b (e1,b) \" using WTrtBinOpEq.prems(2) by(simp add:bconf_BinOp) + with WTrtBinOpEq nf e1 show ?thesis + by simp (fast intro:BinOpRed1) + qed +next + case (WTrtBinOpAdd E e1 e2) show ?case + proof cases + assume "final e1" + thus ?thesis + proof (rule finalE) + fix v1 assume eV[simp]: "e1 = Val v1" + show ?thesis + proof cases + assume "final e2" + thus ?thesis + proof (rule finalE) + fix v2 assume eV2:"e2 = Val v2" + then obtain i1 i2 where "v1 = Intg i1 \ v2 = Intg i2" using WTrtBinOpAdd by clarsimp + thus ?thesis using WTrtBinOpAdd eV eV2 by(fastforce intro:RedBinOp) + next + fix a assume "e2 = Throw a" + thus ?thesis using eV by(blast intro:red_reds.BinOpThrow2) + qed + next + assume nf:"\ final e2" + then have "P,sh \\<^sub>b (e2,b) \" using WTrtBinOpAdd.prems(2) by(simp add:bconf_BinOp) + with WTrtBinOpAdd nf show ?thesis + by simp (fast intro!:BinOpRed2) + qed + next + fix a assume "e1 = Throw a" + thus ?thesis by(fast intro:red_reds.BinOpThrow1) + qed + next + assume nf: "\ final e1" + then have e1: "val_of e1 = None" proof(cases e1)qed(auto) + then have "P,sh \\<^sub>b (e1,b) \" using WTrtBinOpAdd.prems(2) by(simp add:bconf_BinOp) + with WTrtBinOpAdd nf e1 show ?thesis + by simp (fast intro:BinOpRed1) + qed +next + case (WTrtLAss E V T e T') + then have bconf: "P,sh \\<^sub>b (e,b) \" using bconf_LAss by fast + show ?case + proof cases + assume "final e" with WTrtLAss show ?thesis + by(fastforce simp:final_def intro: red_reds.RedLAss red_reds.LAssThrow) + next + assume "\ final e" with WTrtLAss bconf show ?thesis + by simp (fast intro:LAssRed) + qed +next + case (WTrtFAcc E e C F T D) + then have bconf: "P,sh \\<^sub>b (e,b) \" using bconf_FAcc by fast + have wte: "P,E,h,sh \ e : Class C" + and field: "P \ C has F,NonStatic:T in D" by fact+ + show ?case + proof cases + assume "final e" + with wte show ?thesis + proof (rule final_addrE) + fix a assume e: "e = addr a" + with wte obtain fs where hp: "h a = Some(C,fs)" by auto + with hconf have "P,h \ (C,fs) \" using hconf_def by fastforce + then obtain v where "fs(F,D) = Some v" using field + by(fastforce dest:has_fields_fun simp:oconf_def has_field_def) + with hp e show ?thesis by (meson field red_reds.RedFAcc) + next + fix a assume "e = Throw a" + thus ?thesis by(fastforce intro:red_reds.FAccThrow) + qed + next + assume "\ final e" with WTrtFAcc bconf show ?thesis + by(fastforce intro!:FAccRed) + qed +next + case (WTrtFAccNT E e F D T) + then have bconf: "P,sh \\<^sub>b (e,b) \" using bconf_FAcc by fast + show ?case + proof cases + assume "final e" \ \@{term e} is @{term null} or @{term throw}\ + with WTrtFAccNT show ?thesis + by(fastforce simp:final_def intro: red_reds.RedFAccNull red_reds.FAccThrow) + next + assume "\ final e" \ \@{term e} reduces by IH\ + with WTrtFAccNT bconf show ?thesis by simp (fast intro:FAccRed) + qed +next +case (WTrtSFAcc C F T D E) then show ?case + proof (cases b) + case True + then obtain sfs i where shD: "sh D = \(sfs,i)\" + using bconf_def[of P sh "C\\<^sub>sF{D}" b] WTrtSFAcc.prems(2) initPD_def by auto + with shconf have "P,h,D \\<^sub>s sfs \" using shconf_def[of P h sh] by auto + then obtain v where sfsF: "sfs F = Some v" using WTrtSFAcc.hyps + by(unfold soconf_def) (auto dest:has_field_idemp) + then show ?thesis using WTrtSFAcc.hyps shD sfsF True + by(fastforce elim:RedSFAcc) + next + case False + with assms WTrtSFAcc show ?thesis + by(metis (full_types) SFAccInitDoneRed SFAccInitRed) + qed +next + case (WTrtFAss E e1 C F T D e2 T2) + have wte1: "P,E,h,sh \ e1 : Class C" and field: "P \ C has F,NonStatic:T in D" by fact+ + show ?case + proof cases + assume "final e1" + with wte1 show ?thesis + proof (rule final_addrE) + fix a assume e1: "e1 = addr a" + show ?thesis + proof cases + assume "final e2" + thus ?thesis + proof (rule finalE) + fix v assume "e2 = Val v" + thus ?thesis using e1 wte1 by(fastforce intro: RedFAss[OF field]) + next + fix a assume "e2 = Throw a" + thus ?thesis using e1 by(fastforce intro:red_reds.FAssThrow2) + qed + next + assume nf: "\ final e2" + then have "P,sh \\<^sub>b (e2,b) \" using WTrtFAss.prems(2) e1 by(simp add:bconf_FAss) + with WTrtFAss e1 nf show ?thesis + by simp (fast intro!:FAssRed2) + qed + next + fix a assume "e1 = Throw a" + thus ?thesis by(fastforce intro:red_reds.FAssThrow1) + qed + next + assume nf: "\ final e1" + then have e1: "val_of e1 = None" proof(cases e1)qed(auto) + then have "P,sh \\<^sub>b (e1,b) \" using WTrtFAss.prems(2) by(simp add:bconf_FAss) + with WTrtFAss nf e1 show ?thesis + by simp (blast intro!:FAssRed1) + qed +next + case (WTrtFAssNT E e\<^sub>1 e\<^sub>2 T\<^sub>2 F D) + show ?case + proof cases + assume e1: "final e\<^sub>1" \ \@{term e\<^sub>1} is @{term null} or @{term throw}\ + show ?thesis + proof cases + assume "final e\<^sub>2" \ \@{term e\<^sub>2} is @{term Val} or @{term throw}\ + with WTrtFAssNT e1 show ?thesis + by(fastforce simp:final_def + intro: red_reds.RedFAssNull red_reds.FAssThrow1 red_reds.FAssThrow2) + next + assume nf: "\ final e\<^sub>2" \ \@{term e\<^sub>2} reduces by IH\ + show ?thesis + proof (rule finalE[OF e1]) + fix v assume ev: "e\<^sub>1 = Val v" + then have "P,sh \\<^sub>b (e\<^sub>2,b) \" using WTrtFAssNT.prems(2) nf by(simp add:bconf_FAss) + with WTrtFAssNT ev nf show ?thesis by auto (meson red_reds.FAssRed2) + next + fix a assume et: "e\<^sub>1 = Throw a" + then have "P,sh \\<^sub>b (e\<^sub>1,b) \" using WTrtFAssNT.prems(2) nf by(simp add:bconf_FAss) + with WTrtFAssNT et nf show ?thesis by(fastforce intro: red_reds.FAssThrow1) + qed + qed + next + assume nf: "\ final e\<^sub>1" \ \@{term e\<^sub>1} reduces by IH\ + then have e1: "val_of e\<^sub>1 = None" proof(cases e\<^sub>1)qed(auto) + then have "P,sh \\<^sub>b (e\<^sub>1,b) \" using WTrtFAssNT.prems(2) by(simp add:bconf_FAss) + with WTrtFAssNT nf e1 show ?thesis + by simp (blast intro!:FAssRed1) + qed +next + case (WTrtSFAss C F T D E e2 T\<^sub>2) + have field: "P \ C has F,Static:T in D" by fact+ + show ?case + proof cases + assume "final e2" + thus ?thesis + proof (rule finalE) + fix v assume ev: "e2 = Val v" + then show ?case + proof (cases b) + case True + then obtain sfs i where shD: "sh D = \(sfs,i)\" + using bconf_def[of P _ "C\\<^sub>sF{D} := e2"] WTrtSFAss.prems(2) initPD_def ev by auto + with shconf have "P,h,D \\<^sub>s sfs \" using shconf_def[of P] by auto + then obtain v where sfsF: "sfs F = Some v" using field + by(unfold soconf_def) (auto dest:has_field_idemp) + then show ?thesis using WTrtSFAss.hyps shD sfsF True ev + by(fastforce elim:RedSFAss) + next + case False + with assms WTrtSFAss ev show ?thesis + by(metis (full_types) SFAssInitDoneRed SFAssInitRed) + qed + next + fix a assume "e2 = Throw a" + thus ?thesis by(fastforce intro:red_reds.SFAssThrow) + qed + next + assume nf: "\ final e2" + then have "val_of e2 = None" using final_def val_of_spec by fastforce + then have "P,sh \\<^sub>b (e2,b) \" using WTrtSFAss.prems(2) by(simp add:bconf_SFAss) + with WTrtSFAss nf show ?thesis + by simp (fast intro!:SFAssRed) + qed +next + case (WTrtCall E e C M Ts T pns body D es Ts') + have wte: "P,E,h,sh \ e : Class C" + and "method": "P \ C sees M,NonStatic:Ts\T = (pns,body) in D" + and wtes: "P,E,h,sh \ es [:] Ts'"and sub: "P \ Ts' [\] Ts" + and IHes: "\l. + \\s es \dom l\; P,sh \\<^sub>b (es,b) \; \ finals es\ + \ \es' s' b'. P \ \es,(h,l,sh),b\ [\] \es',s',b'\" + and D: "\ (e\M(es)) \dom l\" by fact+ + show ?case + proof cases + assume "final e" + with wte show ?thesis + proof (rule final_addrE) + fix a assume e_addr: "e = addr a" + show ?thesis + proof cases + assume es: "\vs. es = map Val vs" + from wte e_addr obtain fs where ha: "h a = Some(C,fs)" by auto + show ?thesis + using e_addr ha "method" WTrts_same_length[OF wtes] sub es sees_wf_mdecl[OF wf "method"] + by(fastforce intro!: RedCall simp:list_all2_iff wf_mdecl_def) + next + assume "\(\vs. es = map Val vs)" + hence not_all_Val: "\(\e \ set es. \v. e = Val v)" + by(simp add:ex_map_conv) + let ?ves = "takeWhile (\e. \v. e = Val v) es" + let ?rest = "dropWhile (\e. \v. e = Val v) es" + let ?ex = "hd ?rest" let ?rst = "tl ?rest" + from not_all_Val have nonempty: "?rest \ []" by auto + hence es: "es = ?ves @ ?ex # ?rst" by simp + have "\e \ set ?ves. \v. e = Val v" by(fastforce dest:set_takeWhileD) + then obtain vs where ves: "?ves = map Val vs" + using ex_map_conv by blast + show ?thesis + proof cases + assume "final ?ex" + moreover from nonempty have "\(\v. ?ex = Val v)" + by(auto simp:neq_Nil_conv simp del:dropWhile_eq_Nil_conv) + (simp add:dropWhile_eq_Cons_conv) + ultimately obtain b where ex_Throw: "?ex = Throw b" + by(fast elim!:finalE) + show ?thesis using e_addr es ex_Throw ves + by(fastforce intro:CallThrowParams) + next + assume not_fin: "\ final ?ex" + have "finals es = finals(?ves @ ?ex # ?rst)" using es + by(rule arg_cong) + also have "\ = finals(?ex # ?rst)" using ves by simp + finally have "finals es = finals(?ex # ?rst)" . + hence fes: "\ finals es" using not_finals_ConsI[OF not_fin] by blast + have "P,sh \\<^sub>b (es,b) \" using bconf_Call WTrtCall.prems(2) + by (metis e_addr option.simps(5) val_of.simps(1)) + thus ?thesis using fes e_addr D IHes by(fastforce intro!:CallParams) + qed + qed + next + fix a assume "e = Throw a" + with WTrtCall.prems show ?thesis by(fast intro!:CallThrowObj) + qed + next + assume nf: "\ final e" + then have e1: "val_of e = None" proof(cases e)qed(auto) + then have "P,sh \\<^sub>b (e,b) \" using WTrtCall.prems(2) by(simp add:bconf_Call) + with WTrtCall nf e1 show ?thesis by simp (blast intro!:CallObj) + qed +next + case (WTrtCallNT E e es Ts M T) show ?case + proof cases + assume "final e" + moreover + { fix v assume e: "e = Val v" + hence "e = null" using WTrtCallNT by simp + have ?case + proof cases + assume "finals es" + moreover + { fix vs assume "es = map Val vs" + with WTrtCallNT e have ?thesis by(fastforce intro: RedCallNull) } + moreover + { fix vs a es' assume "es = map Val vs @ Throw a # es'" + with WTrtCallNT e have ?thesis by(fastforce intro: CallThrowParams) } + ultimately show ?thesis by(fastforce simp:finals_def) + next + assume nf: "\ finals es" \ \@{term es} reduces by IH\ + have "P,sh \\<^sub>b (es,b) \" using WTrtCallNT.prems(2) e by (simp add: bconf_Call) + with WTrtCallNT e nf show ?thesis by(fastforce intro: CallParams) + qed + } + moreover + { fix a assume "e = Throw a" + with WTrtCallNT have ?case by(fastforce intro: CallThrowObj) } + ultimately show ?thesis by(fastforce simp:final_def) + next + assume nf: "\ final e" \ \@{term e} reduces by IH\ + then have "val_of e = None" proof(cases e)qed(auto) + then have "P,sh \\<^sub>b (e,b) \" using WTrtCallNT.prems(2) by(simp add:bconf_Call) + with WTrtCallNT nf show ?thesis by (fastforce intro:CallObj) + qed +next + case (WTrtSCall C M Ts T pns body D E es Ts' sfs vs) + have "method": "P \ C sees M,Static:Ts\T = (pns,body) in D" + and wtes: "P,E,h,sh \ es [:] Ts'"and sub: "P \ Ts' [\] Ts" + and IHes: "\l. + \\s es \dom l\; P,sh \\<^sub>b (es,b) \; \ finals es\ + \ \es' s' b'. P \ \es,(h,l,sh),b\ [\] \es',s',b'\" + and clinit: "M = clinit \ sh D = \(sfs, Processing)\ \ es = map Val vs" + and D: "\ (C\\<^sub>sM(es)) \dom l\" by fact+ + show ?case + proof cases + assume es: "\vs. es = map Val vs" + show ?thesis + proof (cases b) + case True + then show ?thesis + using "method" WTrts_same_length[OF wtes] sub es sees_wf_mdecl[OF wf "method"] True + by(fastforce intro!: RedSCall simp:list_all2_iff wf_mdecl_def) + next + case False + show ?thesis + using "method" clinit WTrts_same_length[OF wtes] sub es False + by (metis (full_types) red_reds.SCallInitDoneRed red_reds.SCallInitRed) + qed + next + assume nmap: "\(\vs. es = map Val vs)" + hence not_all_Val: "\(\e \ set es. \v. e = Val v)" + by(simp add:ex_map_conv) + let ?ves = "takeWhile (\e. \v. e = Val v) es" + let ?rest = "dropWhile (\e. \v. e = Val v) es" + let ?ex = "hd ?rest" let ?rst = "tl ?rest" + from not_all_Val have nonempty: "?rest \ []" by auto + hence es: "es = ?ves @ ?ex # ?rst" by simp + have "\e \ set ?ves. \v. e = Val v" by(fastforce dest:set_takeWhileD) + then obtain vs where ves: "?ves = map Val vs" + using ex_map_conv by blast + show ?thesis + proof cases + assume "final ?ex" + moreover from nonempty have "\(\v. ?ex = Val v)" + by(auto simp:neq_Nil_conv simp del:dropWhile_eq_Nil_conv) + (simp add:dropWhile_eq_Cons_conv) + ultimately obtain b where ex_Throw: "?ex = Throw b" + by(fast elim!:finalE) + show ?thesis using es ex_Throw ves + by(fastforce intro:SCallThrowParams) + next + assume not_fin: "\ final ?ex" + have "finals es = finals(?ves @ ?ex # ?rst)" using es + by(rule arg_cong) + also have "\ = finals(?ex # ?rst)" using ves by simp + finally have "finals es = finals(?ex # ?rst)" . + hence fes: "\ finals es" using not_finals_ConsI[OF not_fin] by blast + have "P,sh \\<^sub>b (es,b) \" + by (meson WTrtSCall.prems(2) nmap bconf_SCall map_vals_of_spec not_None_eq) + thus ?thesis using fes D IHes by(fastforce intro!:SCallParams) + qed + qed +next + case WTrtNil thus ?case by simp +next + case (WTrtCons E e T es Ts) + have IHe: "\l. \\ e \dom l\; P,sh \\<^sub>b (e,b) \; \ final e\ + \ \e' s' b'. P \ \e,(h,l,sh),b\ \ \e',s',b'\" + and IHes: "\l. \\s es \dom l\; P,sh \\<^sub>b (es,b) \; \ finals es\ + \ \es' s' b'. P \ \es,(h,l,sh),b\ [\] \es',s',b'\" + and D: "\s (e#es) \dom l\" and not_fins: "\ finals(e # es)" by fact+ + have De: "\ e \dom l\" and Des: "\s es (\dom l\ \ \ e)" + using D by auto + show ?case + proof cases + assume "final e" + thus ?thesis + proof (rule finalE) + fix v assume e: "e = Val v" + hence Des': "\s es \dom l\" using De Des by auto + have bconfs: "P,sh \\<^sub>b (es,b) \" using WTrtCons.prems(2) e by(simp add: bconf_Cons) + have not_fins_tl: "\ finals es" using not_fins e by simp + show ?thesis using e IHes[OF Des' bconfs not_fins_tl] + by (blast intro!:ListRed2) + next + fix a assume "e = Throw a" + hence False using not_fins by simp + thus ?thesis .. + qed + next + assume nf:"\ final e" + then have "val_of e = None" proof(cases e)qed(auto) + then have bconf: "P,sh \\<^sub>b (e,b) \" using WTrtCons.prems(2) by(simp add: bconf_Cons) + with IHe[OF De bconf nf] show ?thesis by(fast intro!:ListRed1) + qed +next + case (WTrtInitBlock v T\<^sub>1 T E V e\<^sub>2 T\<^sub>2) + have IH2: "\l. \\ e\<^sub>2 \dom l\; P,sh \\<^sub>b (e\<^sub>2,b) \; \ final e\<^sub>2\ + \ \e' s' b'. P \ \e\<^sub>2,(h,l,sh),b\ \ \e',s',b'\" + and D: "\ {V:T := Val v; e\<^sub>2} \dom l\" by fact+ + show ?case + proof cases + assume "final e\<^sub>2" + then show ?thesis + proof (rule finalE) + fix v\<^sub>2 assume "e\<^sub>2 = Val v\<^sub>2" + thus ?thesis by(fast intro:RedInitBlock) + next + fix a assume "e\<^sub>2 = Throw a" + thus ?thesis by(fast intro:red_reds.InitBlockThrow) + qed + next + assume not_fin2: "\ final e\<^sub>2" + then have "val_of e\<^sub>2 = None" proof(cases e\<^sub>2)qed(auto) + from D have D2: "\ e\<^sub>2 \dom(l(V\v))\" by (auto simp:hyperset_defs) + have e2conf: "P,sh \\<^sub>b (e\<^sub>2,b) \" using WTrtInitBlock.prems(2) by(simp add: bconf_InitBlock) + from IH2[OF D2 e2conf not_fin2] + obtain h' l' sh' e' b' where red2: "P \ \e\<^sub>2,(h, l(V\v),sh),b\ \ \e',(h', l',sh'),b'\" + by auto + from red_lcl_incr[OF red2] have "V \ dom l'" by auto + with red2 show ?thesis by(fastforce intro:InitBlockRed) + qed +next + case (WTrtBlock E V T e T') + have IH: "\l. \\ e \dom l\; P,sh \\<^sub>b (e,b) \; \ final e\ + \ \e' s' b'. P \ \e,(h,l,sh),b\ \ \e',s',b'\" + and unass: "\ assigned V e" and D: "\ {V:T; e} \dom l\" by fact+ + show ?case + proof cases + assume "final e" + thus ?thesis + proof (rule finalE) + fix v assume "e = Val v" thus ?thesis by(fast intro:RedBlock) + next + fix a assume "e = Throw a" + thus ?thesis by(fast intro:red_reds.BlockThrow) + qed + next + assume not_fin: "\ final e" + then have "val_of e = None" proof(cases e)qed(auto) + from D have De: "\ e \dom(l(V:=None))\" by(simp add:hyperset_defs) + have bconf: "P,sh \\<^sub>b (e,b) \" using WTrtBlock by(simp add: bconf_Block) + from IH[OF De bconf not_fin] + obtain h' l' sh' e' b' where red: "P \ \e,(h,l(V:=None),sh),b\ \ \e',(h',l',sh'),b'\" + by auto + show ?thesis + proof (cases "l' V") + assume "l' V = None" + with red unass show ?thesis by(blast intro: BlockRedNone) + next + fix v assume "l' V = Some v" + with red unass show ?thesis by(blast intro: BlockRedSome) + qed + qed +next + case (WTrtSeq E e1 T1 e2 T2) show ?case + proof cases + assume "final e1" + thus ?thesis + by(fast elim:finalE intro:RedSeq red_reds.SeqThrow) + next + assume nf: "\ final e1" + then have e1: "val_of e1 = None" proof(cases e1)qed(auto) + then show ?thesis + proof(cases "lass_val_of e1") + case None + then have "P,sh \\<^sub>b (e1,b) \" using WTrtSeq.prems(2) e1 by(simp add: bconf_Seq) + with WTrtSeq nf e1 None show ?thesis by simp (blast intro:SeqRed) + next + case (Some p) + obtain V v where "e1 = V:=Val v" using lass_val_of_spec[OF Some] by simp + then show ?thesis using SeqRed[OF RedLAss] by blast + qed + qed +next + case (WTrtCond E e e\<^sub>1 T\<^sub>1 e\<^sub>2 T\<^sub>2 T) + have wt: "P,E,h,sh \ e : Boolean" by fact + show ?case + proof cases + assume "final e" + thus ?thesis + proof (rule finalE) + fix v assume val: "e = Val v" + then obtain b where v: "v = Bool b" using wt by auto + show ?thesis + proof (cases b) + case True with val v show ?thesis by(fastforce intro:RedCondT simp: prod_cases3) + next + case False with val v show ?thesis by(fastforce intro:RedCondF simp: prod_cases3) + qed + next + fix a assume "e = Throw a" + thus ?thesis by(fast intro:red_reds.CondThrow) + qed + next + assume nf: "\ final e" + then have "bool_of e = None" proof(cases e)qed(auto) + then have "P,sh \\<^sub>b (e,b) \" using WTrtCond.prems(2) by(simp add: bconf_Cond) + with WTrtCond nf show ?thesis by simp (blast intro:CondRed) + qed +next + case WTrtWhile show ?case by(fast intro:RedWhile) +next + case (WTrtThrow E e T\<^sub>r T) show ?case + proof cases + assume "final e" \ \Then @{term e} must be @{term throw} or @{term null}\ + with WTrtThrow show ?thesis + by(fastforce simp:final_def is_refT_def + intro:red_reds.ThrowThrow red_reds.RedThrowNull) + next + assume nf: "\ final e" \ \Then @{term e} must reduce\ + then have "val_of e = None" proof(cases e)qed(auto) + then have "P,sh \\<^sub>b (e,b) \" using WTrtThrow.prems(2) by(simp add: bconf_Throw) + with WTrtThrow nf show ?thesis by simp (blast intro:ThrowRed) + qed +next + case (WTrtTry E e1 T1 V C e2 T2) + have wt1: "P,E,h,sh \ e1 : T1" by fact + show ?case + proof cases + assume "final e1" + thus ?thesis + proof (rule finalE) + fix v assume "e1 = Val v" + thus ?thesis by(fast intro:RedTry) + next + fix a assume e1_Throw: "e1 = Throw a" + with wt1 obtain D fs where ha: "h a = Some(D,fs)" by fastforce + show ?thesis + proof cases + assume "P \ D \\<^sup>* C" + with e1_Throw ha show ?thesis by(fastforce intro!:RedTryCatch) + next + assume "\ P \ D \\<^sup>* C" + with e1_Throw ha show ?thesis by(fastforce intro!:RedTryFail) + qed + qed + next + assume nf: "\ final e1" + then have "val_of e1 = None" proof(cases e1)qed(auto) + then have "P,sh \\<^sub>b (e1,b) \" using WTrtTry.prems(2) by(simp add: bconf_Try) + with WTrtTry nf show ?thesis by simp (fast intro:TryRed) + qed +next + case (WTrtInit E e T\<^sub>r C Cs b) show ?case + proof(cases Cs) + case Nil then show ?thesis using WTrtInit by(fastforce intro!: RedInit) + next + case (Cons C' Cs') + show ?thesis + proof(cases b) + case True then show ?thesis using Cons by(fastforce intro!: RedInitRInit) + next + case False + show ?thesis + proof(cases "sh C'") + case None + then show ?thesis using False Cons by(fastforce intro!: InitNoneRed) + next + case (Some sfsi) + then obtain sfs i where sfsi:"sfsi = (sfs,i)" by(cases sfsi) + show ?thesis + proof(cases i) + case Done + then show ?thesis using False Some sfsi Cons by(fastforce intro!: RedInitDone) + next + case Processing + then show ?thesis using False Some sfsi Cons by(fastforce intro!: RedInitProcessing) + next + case Error + then show ?thesis using False Some sfsi Cons by(fastforce intro!: RedInitError) + next + case Prepared + show ?thesis + proof cases + assume "C' = Object" + then show ?thesis using False Some sfsi Prepared Cons by(fastforce intro: InitObjectRed) + next + assume "C' \ Object" + then show ?thesis using False Some sfsi Prepared WTrtInit.hyps(3) Cons + by(simp only: is_class_def)(fastforce intro!: InitNonObjectSuperRed) + qed + qed + qed + qed + qed +next + case (WTrtRI E e T\<^sub>r e' T\<^sub>r' C Cs) + obtain sfs i where shC: "sh C = \(sfs, i)\" using WTrtRI.hyps(9) by blast + show ?case + proof cases + assume fin: "final e" then show ?thesis + proof (rule finalE) + fix v assume e: "e = Val v" + then show ?thesis using shC e by(fast intro:RedRInit) + next + fix a assume eThrow: "e = Throw a" + show ?thesis + proof(cases Cs) + case Nil then show ?thesis using eThrow shC by(fastforce intro!: RInitThrow) + next + case Cons then show ?thesis using eThrow shC by(fastforce intro!: RInitInitThrow) + qed + qed + next + assume nf: "\ final e" + then have "val_of e = None" proof(cases e)qed(auto) + then have "P,sh \\<^sub>b (e,b) \" using WTrtRI.prems(2) by(simp add: bconf_RI) + with WTrtRI nf show ?thesis by simp (meson red_reds.RInitRed) + qed +qed +(*>*) + +end diff --git a/thys/JinjaDCI/J/SmallStep.thy b/thys/JinjaDCI/J/SmallStep.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/J/SmallStep.thy @@ -0,0 +1,634 @@ +(* Title: JinjaDCI/J/SmallStep.thy + Author: Tobias Nipkow, Susannah Mansky + Copyright 2003 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory J/SmallStep.thy by Tobias Nipkow +*) + +section \ Small Step Semantics \ + +theory SmallStep +imports Expr State WWellForm +begin + +fun blocks :: "vname list * ty list * val list * expr \ expr" +where + "blocks(V#Vs, T#Ts, v#vs, e) = {V:T := Val v; blocks(Vs,Ts,vs,e)}" +|"blocks([],[],[],e) = e" + +lemmas blocks_induct = blocks.induct[split_format (complete)] + +lemma [simp]: + "\ size vs = size Vs; size Ts = size Vs \ \ fv(blocks(Vs,Ts,vs,e)) = fv e - set Vs" +(*<*) +by (induct rule:blocks_induct) auto +(*>*) + + +lemma sub_RI_blocks_body[iff]: "length vs = length pns \ length Ts = length pns + \ sub_RI (blocks (pns, Ts, vs, body)) \ sub_RI body" +proof(induct pns arbitrary: Ts vs) + case Nil then show ?case by simp +next + case Cons then show ?case by(cases vs; cases Ts) auto +qed + + +definition assigned :: "'a \ 'a exp \ bool" +where + "assigned V e \ \v e'. e = (V := Val v;; e')" + +\ \ expression is okay to go the right side of @{text INIT} or @{text "RI \"} + or to have indicator Boolean be True (in latter case, given that class is + also verified initialized) \ +fun icheck :: "'m prog \ cname \ 'a exp \ bool" where +"icheck P C' (new C) = (C' = C)" | +"icheck P D' (C\\<^sub>sF{D}) = ((D' = D) \ (\T. P \ C has F,Static:T in D))" | +"icheck P D' (C\\<^sub>sF{D}:=(Val v)) = ((D' = D) \ (\T. P \ C has F,Static:T in D))" | +"icheck P D (C\\<^sub>sM(es)) = ((\vs. es = map Val vs) \ (\Ts T m. P \ C sees M,Static:Ts\T = m in D))" | +"icheck P _ _ = False" + +lemma nicheck_SFAss_nonVal: "val_of e\<^sub>2 = None \ \icheck P C' (C\\<^sub>sF{D} := (e\<^sub>2::'a exp))" + by(rule notI, cases e\<^sub>2, auto) + +inductive_set + red :: "J_prog \ ((expr \ state \ bool) \ (expr \ state \ bool)) set" + and reds :: "J_prog \ ((expr list \ state \ bool) \ (expr list \ state \ bool)) set" + and red' :: "J_prog \ expr \ state \ bool \ expr \ state \ bool \ bool" + ("_ \ ((1\_,/_,/_\) \/ (1\_,/_,/_\))" [51,0,0,0,0,0,0] 81) + and reds' :: "J_prog \ expr list \ state \ bool \ expr list \ state \ bool \ bool" + ("_ \ ((1\_,/_,/_\) [\]/ (1\_,/_,/_\))" [51,0,0,0,0,0,0] 81) + for P :: J_prog +where + + "P \ \e,s,b\ \ \e',s',b'\ \ ((e,s,b), e',s',b') \ red P" +| "P \ \es,s,b\ [\] \es',s',b'\ \ ((es,s,b), es',s',b') \ reds P" + +| RedNew: + "\ new_Addr h = Some a; P \ C has_fields FDTs; h' = h(a\blank P C) \ + \ P \ \new C, (h,l,sh), True\ \ \addr a, (h',l,sh), False\" + +| RedNewFail: + "\ new_Addr h = None; is_class P C \ \ + P \ \new C, (h,l,sh), True\ \ \THROW OutOfMemory, (h,l,sh), False\" + +| NewInitDoneRed: + "sh C = Some (sfs, Done) \ + P \ \new C, (h,l,sh), False\ \ \new C, (h,l,sh), True\" + +| NewInitRed: + "\ \sfs. sh C = Some (sfs, Done); is_class P C \ + \ P \ \new C,(h,l,sh),False\ \ \INIT C ([C],False) \ new C,(h,l,sh),False\" + +| CastRed: + "P \ \e,s,b\ \ \e',s',b'\ \ + P \ \Cast C e, s, b\ \ \Cast C e', s', b'\" + +| RedCastNull: + "P \ \Cast C null, s, b\ \ \null,s,b\" + +| RedCast: + "\ h a = Some(D,fs); P \ D \\<^sup>* C \ + \ P \ \Cast C (addr a), (h,l,sh), b\ \ \addr a, (h,l,sh), b\" + +| RedCastFail: + "\ h a = Some(D,fs); \ P \ D \\<^sup>* C \ + \ P \ \Cast C (addr a), (h,l,sh), b\ \ \THROW ClassCast, (h,l,sh), b\" + +| BinOpRed1: + "P \ \e,s,b\ \ \e',s',b'\ \ + P \ \e \bop\ e\<^sub>2, s, b\ \ \e' \bop\ e\<^sub>2, s', b'\" + +| BinOpRed2: + "P \ \e,s,b\ \ \e',s',b'\ \ + P \ \(Val v\<^sub>1) \bop\ e, s, b\ \ \(Val v\<^sub>1) \bop\ e', s', b'\" + +| RedBinOp: + "binop(bop,v\<^sub>1,v\<^sub>2) = Some v \ + P \ \(Val v\<^sub>1) \bop\ (Val v\<^sub>2), s, b\ \ \Val v,s,b\" + +| RedVar: + "l V = Some v \ + P \ \Var V,(h,l,sh),b\ \ \Val v,(h,l,sh),b\" + +| LAssRed: + "P \ \e,s,b\ \ \e',s',b'\ \ + P \ \V:=e,s,b\ \ \V:=e',s',b'\" + +| RedLAss: + "P \ \V:=(Val v), (h,l,sh), b\ \ \unit, (h,l(V\v),sh), b\" + +| FAccRed: + "P \ \e,s,b\ \ \e',s',b'\ \ + P \ \e\F{D}, s, b\ \ \e'\F{D}, s', b'\" + +| RedFAcc: + "\ h a = Some(C,fs); fs(F,D) = Some v; + P \ C has F,NonStatic:t in D \ + \ P \ \(addr a)\F{D}, (h,l,sh), b\ \ \Val v,(h,l,sh),b\" + +| RedFAccNull: + "P \ \null\F{D}, s, b\ \ \THROW NullPointer, s, b\" + +| RedFAccNone: + "\ h a = Some(C,fs); \(\b t. P \ C has F,b:t in D) \ + \ P \ \(addr a)\F{D},(h,l,sh),b\ \ \THROW NoSuchFieldError,(h,l,sh),b\" + +| RedFAccStatic: + "\ h a = Some(C,fs); P \ C has F,Static:t in D \ + \ P \ \(addr a)\F{D},(h,l,sh),b\ \ \THROW IncompatibleClassChangeError,(h,l,sh),b\" + +| RedSFAcc: + "\ P \ C has F,Static:t in D; + sh D = Some (sfs,i); + sfs F = Some v \ + \ P \ \C\\<^sub>sF{D},(h,l,sh),True\ \ \Val v,(h,l,sh),False\" + +| SFAccInitDoneRed: + "\ P \ C has F,Static:t in D; + sh D = Some (sfs,Done) \ + \ P \ \C\\<^sub>sF{D},(h,l,sh),False\ \ \C\\<^sub>sF{D},(h,l,sh),True\" + +| SFAccInitRed: + "\ P \ C has F,Static:t in D; + \sfs. sh D = Some (sfs,Done) \ + \ P \ \C\\<^sub>sF{D},(h,l,sh),False\ \ \INIT D ([D],False) \ C\\<^sub>sF{D},(h,l,sh),False\" + +| RedSFAccNone: + "\(\b t. P \ C has F,b:t in D) + \ P \ \C\\<^sub>sF{D},(h,l,sh),b\ \ \THROW NoSuchFieldError,(h,l,sh),False\" + +| RedSFAccNonStatic: + "P \ C has F,NonStatic:t in D + \ P \ \C\\<^sub>sF{D},(h,l,sh),b\ \ \THROW IncompatibleClassChangeError,(h,l,sh),False\" + +| FAssRed1: + "P \ \e,s,b\ \ \e',s',b'\ \ + P \ \e\F{D}:=e\<^sub>2, s, b\ \ \e'\F{D}:=e\<^sub>2, s', b'\" + +| FAssRed2: + "P \ \e,s,b\ \ \e',s',b'\ \ + P \ \Val v\F{D}:=e, s, b\ \ \Val v\F{D}:=e', s', b'\" + +| RedFAss: + "\ P \ C has F,NonStatic:t in D; h a = Some(C,fs) \ \ + P \ \(addr a)\F{D}:=(Val v), (h,l,sh), b\ \ \unit, (h(a \ (C,fs((F,D) \ v))),l,sh), b\" + +| RedFAssNull: + "P \ \null\F{D}:=Val v, s, b\ \ \THROW NullPointer, s, b\" + +| RedFAssNone: + "\ h a = Some(C,fs); \(\b t. P \ C has F,b:t in D) \ + \ P \ \(addr a)\F{D}:=(Val v),(h,l,sh),b\ \ \THROW NoSuchFieldError,(h,l,sh),b\" + +| RedFAssStatic: + "\ h a = Some(C,fs); P \ C has F,Static:t in D \ + \ P \ \(addr a)\F{D}:=(Val v),(h,l,sh),b\ \ \THROW IncompatibleClassChangeError,(h,l,sh),b\" + +| SFAssRed: + "P \ \e,s,b\ \ \e',s',b'\ \ + P \ \C\\<^sub>sF{D}:=e, s, b\ \ \C\\<^sub>sF{D}:=e', s', b'\" + +| RedSFAss: + "\ P \ C has F,Static:t in D; + sh D = Some(sfs,i); + sfs' = sfs(F\v); sh' = sh(D\(sfs',i)) \ + \ P \ \C\\<^sub>sF{D}:=(Val v),(h,l,sh),True\ \ \unit,(h,l,sh'),False\" + +| SFAssInitDoneRed: + "\ P \ C has F,Static:t in D; + sh D = Some(sfs,Done) \ + \ P \ \C\\<^sub>sF{D}:=(Val v),(h,l,sh),False\ \ \C\\<^sub>sF{D}:=(Val v),(h,l,sh),True\" + +| SFAssInitRed: + "\ P \ C has F,Static:t in D; + \sfs. sh D = Some(sfs,Done) \ + \ P \ \C\\<^sub>sF{D}:=(Val v),(h,l,sh),False\ \ \INIT D ([D],False)\ C\\<^sub>sF{D}:=(Val v),(h,l,sh),False\" + +| RedSFAssNone: + "\(\b t. P \ C has F,b:t in D) + \ P \ \C\\<^sub>sF{D}:=(Val v),s,b\ \ \THROW NoSuchFieldError,s,False\" + +| RedSFAssNonStatic: + "P \ C has F,NonStatic:t in D + \ P \ \C\\<^sub>sF{D}:=(Val v),s,b\ \ \THROW IncompatibleClassChangeError,s,False\" + +| CallObj: + "P \ \e,s,b\ \ \e',s',b'\ \ + P \ \e\M(es),s,b\ \ \e'\M(es),s',b'\" + +| CallParams: + "P \ \es,s,b\ [\] \es',s',b'\ \ + P \ \(Val v)\M(es),s,b\ \ \(Val v)\M(es'),s',b'\" + +| RedCall: + "\ h a = Some(C,fs); P \ C sees M,NonStatic:Ts\T = (pns,body) in D; size vs = size pns; size Ts = size pns \ + \ P \ \(addr a)\M(map Val vs), (h,l,sh), b\ \ \blocks(this#pns, Class D#Ts, Addr a#vs, body), (h,l,sh), b\" + +| RedCallNull: + "P \ \null\M(map Val vs),s,b\ \ \THROW NullPointer,s,b\" + +| RedCallNone: + "\ h a = Some(C,fs); \(\b Ts T m D. P \ C sees M,b:Ts\T = m in D) \ + \ P \ \(addr a)\M(map Val vs),(h,l,sh),b\ \ \THROW NoSuchMethodError,(h,l,sh),b\" + +| RedCallStatic: + "\ h a = Some(C,fs); P \ C sees M,Static:Ts\T = m in D \ + \ P \ \(addr a)\M(map Val vs),(h,l,sh),b\ \ \THROW IncompatibleClassChangeError,(h,l,sh),b\" + +| SCallParams: + "P \ \es,s,b\ [\] \es',s',b'\ \ + P \ \C\\<^sub>sM(es),s,b\ \ \C\\<^sub>sM(es'),s',b'\" + +| RedSCall: + "\ P \ C sees M,Static:Ts\T = (pns,body) in D; + length vs = length pns; size Ts = size pns \ + \ P \ \C\\<^sub>sM(map Val vs),s,True\ \ \blocks(pns, Ts, vs, body), s, False\" + +| SCallInitDoneRed: + "\ P \ C sees M,Static:Ts\T = (pns,body) in D; + sh D = Some(sfs,Done) \ (M = clinit \ sh D = Some(sfs,Processing)) \ + \ P \ \C\\<^sub>sM(map Val vs),(h,l,sh), False\ \ \C\\<^sub>sM(map Val vs),(h,l,sh), True\" + +| SCallInitRed: + "\ P \ C sees M,Static:Ts\T = (pns,body) in D; + \sfs. sh D = Some(sfs,Done); M \ clinit \ + \ P \ \C\\<^sub>sM(map Val vs),(h,l,sh), False\ \ \INIT D ([D],False) \ C\\<^sub>sM(map Val vs),(h,l,sh),False\" + +| RedSCallNone: + "\ \(\b Ts T m D. P \ C sees M,b:Ts\T = m in D) \ + \ P \ \C\\<^sub>sM(map Val vs),s,b\ \ \THROW NoSuchMethodError,s,False\" + +| RedSCallNonStatic: + "\ P \ C sees M,NonStatic:Ts\T = m in D \ + \ P \ \C\\<^sub>sM(map Val vs),s,b\ \ \THROW IncompatibleClassChangeError,s,False\" + +| BlockRedNone: + "\ P \ \e, (h,l(V:=None),sh), b\ \ \e', (h',l',sh'), b'\; l' V = None; \ assigned V e \ + \ P \ \{V:T; e}, (h,l,sh), b\ \ \{V:T; e'}, (h',l'(V := l V),sh'), b'\" + +| BlockRedSome: + "\ P \ \e, (h,l(V:=None),sh), b\ \ \e', (h',l',sh'), b'\; l' V = Some v;\ assigned V e \ + \ P \ \{V:T; e}, (h,l,sh), b\ \ \{V:T := Val v; e'}, (h',l'(V := l V),sh'), b'\" + +| InitBlockRed: + "\ P \ \e, (h,l(V\v),sh), b\ \ \e', (h',l',sh'), b'\; l' V = Some v' \ + \ P \ \{V:T := Val v; e}, (h,l,sh), b\ \ \{V:T := Val v'; e'}, (h',l'(V := l V),sh'), b'\" + +| RedBlock: + "P \ \{V:T; Val u}, s, b\ \ \Val u, s, b\" + +| RedInitBlock: + "P \ \{V:T := Val v; Val u}, s, b\ \ \Val u, s, b\" + +| SeqRed: + "P \ \e,s,b\ \ \e',s',b'\ \ + P \ \e;;e\<^sub>2, s, b\ \ \e';;e\<^sub>2, s', b'\" + +| RedSeq: + "P \ \(Val v);;e\<^sub>2, s, b\ \ \e\<^sub>2, s, b\" + +| CondRed: + "P \ \e,s,b\ \ \e',s',b'\ \ + P \ \if (e) e\<^sub>1 else e\<^sub>2, s, b\ \ \if (e') e\<^sub>1 else e\<^sub>2, s', b'\" + +| RedCondT: + "P \ \if (true) e\<^sub>1 else e\<^sub>2, s, b\ \ \e\<^sub>1, s, b\" + +| RedCondF: + "P \ \if (false) e\<^sub>1 else e\<^sub>2, s, b\ \ \e\<^sub>2, s, b\" + +| RedWhile: + "P \ \while(b) c, s, b'\ \ \if(b) (c;;while(b) c) else unit, s, b'\" + +| ThrowRed: + "P \ \e,s,b\ \ \e',s',b'\ \ + P \ \throw e, s, b\ \ \throw e', s', b'\" + +| RedThrowNull: + "P \ \throw null, s, b\ \ \THROW NullPointer, s, b\" + +| TryRed: + "P \ \e,s,b\ \ \e',s',b'\ \ + P \ \try e catch(C V) e\<^sub>2, s, b\ \ \try e' catch(C V) e\<^sub>2, s', b'\" + +| RedTry: + "P \ \try (Val v) catch(C V) e\<^sub>2, s, b\ \ \Val v, s, b\" + +| RedTryCatch: + "\ hp s a = Some(D,fs); P \ D \\<^sup>* C \ + \ P \ \try (Throw a) catch(C V) e\<^sub>2, s, b\ \ \{V:Class C := addr a; e\<^sub>2}, s, b\" + +| RedTryFail: + "\ hp s a = Some(D,fs); \ P \ D \\<^sup>* C \ + \ P \ \try (Throw a) catch(C V) e\<^sub>2, s, b\ \ \Throw a, s, b\" + +| ListRed1: + "P \ \e,s,b\ \ \e',s',b'\ \ + P \ \e#es,s,b\ [\] \e'#es,s',b'\" + +| ListRed2: + "P \ \es,s,b\ [\] \es',s',b'\ \ + P \ \Val v # es,s,b\ [\] \Val v # es',s',b'\" + +\ \Initialization procedure\ + +| RedInit: + "\sub_RI e \ P \ \INIT C (Nil,b) \ e,s,b'\ \ \e,s,icheck P C e\" + +| InitNoneRed: + "sh C = None + \ P \ \INIT C' (C#Cs,False) \ e,(h,l,sh),b\ \ \INIT C' (C#Cs,False) \ e,(h,l,sh(C \ (sblank P C, Prepared))),b\" + +| RedInitDone: + "sh C = Some(sfs,Done) + \ P \ \INIT C' (C#Cs,False) \ e,(h,l,sh),b\ \ \INIT C' (Cs,True) \ e,(h,l,sh),b\" + +| RedInitProcessing: + "sh C = Some(sfs,Processing) + \ P \ \INIT C' (C#Cs,False) \ e,(h,l,sh),b\ \ \INIT C' (Cs,True) \ e,(h,l,sh),b\" + +| RedInitError: + "sh C = Some(sfs,Error) + \ P \ \INIT C' (C#Cs,False) \ e,(h,l,sh),b\ \ \RI (C,THROW NoClassDefFoundError);Cs \ e,(h,l,sh),b\" + +| InitObjectRed: + "\ sh C = Some(sfs,Prepared); + C = Object; + sh' = sh(C \ (sfs,Processing)) \ + \ P \ \INIT C' (C#Cs,False) \ e,(h,l,sh),b\ \ \INIT C' (C#Cs,True) \ e,(h,l,sh'),b\" + +| InitNonObjectSuperRed: + "\ sh C = Some(sfs,Prepared); + C \ Object; + class P C = Some (D,r); + sh' = sh(C \ (sfs,Processing)) \ + \ P \ \INIT C' (C#Cs,False) \ e,(h,l,sh),b\ \ \INIT C' (D#C#Cs,False) \ e,(h,l,sh'),b\" + +| RedInitRInit: + "P \ \INIT C' (C#Cs,True) \ e,(h,l,sh),b\ \ \RI (C,C\\<^sub>sclinit([]));Cs \ e,(h,l,sh),b\" + +| RInitRed: + "P \ \e,s,b\ \ \e',s',b'\ \ + P \ \RI (C,e);Cs \ e\<^sub>0, s, b\ \ \RI (C,e');Cs \ e\<^sub>0, s', b'\" + +| RedRInit: + "\ sh C = Some (sfs, i); + sh' = sh(C \ (sfs,Done)); + C' = last(C#Cs) \ \ + P \ \RI (C, Val v);Cs \ e, (h,l,sh), b\ \ \INIT C' (Cs,True) \ e, (h,l,sh'), b\" + +\ \Exception propagation\ + +| CastThrow: "P \ \Cast C (throw e), s, b\ \ \throw e, s, b\" +| BinOpThrow1: "P \ \(throw e) \bop\ e\<^sub>2, s, b\ \ \throw e, s, b\" +| BinOpThrow2: "P \ \(Val v\<^sub>1) \bop\ (throw e), s, b\ \ \throw e, s, b\" +| LAssThrow: "P \ \V:=(throw e), s, b\ \ \throw e, s, b\" +| FAccThrow: "P \ \(throw e)\F{D}, s, b\ \ \throw e, s, b\" +| FAssThrow1: "P \ \(throw e)\F{D}:=e\<^sub>2, s, b\ \ \throw e, s, b\" +| FAssThrow2: "P \ \Val v\F{D}:=(throw e), s, b\ \ \throw e, s, b\" +| SFAssThrow: "P \ \C\\<^sub>sF{D}:=(throw e), s, b\ \ \throw e, s, b\" +| CallThrowObj: "P \ \(throw e)\M(es), s, b\ \ \throw e, s, b\" +| CallThrowParams: "\ es = map Val vs @ throw e # es' \ \ P \ \(Val v)\M(es), s, b\ \ \throw e, s, b\" +| SCallThrowParams: "\ es = map Val vs @ throw e # es' \ \ P \ \C\\<^sub>sM(es), s, b\ \ \throw e, s, b\" +| BlockThrow: "P \ \{V:T; Throw a}, s, b\ \ \Throw a, s, b\" +| InitBlockThrow: "P \ \{V:T := Val v; Throw a}, s, b\ \ \Throw a, s, b\" +| SeqThrow: "P \ \(throw e);;e\<^sub>2, s, b\ \ \throw e, s, b\" +| CondThrow: "P \ \if (throw e) e\<^sub>1 else e\<^sub>2, s, b\ \ \throw e, s, b\" +| ThrowThrow: "P \ \throw(throw e), s, b\ \ \throw e, s, b\" +| RInitInitThrow: "\ sh C = Some(sfs,i); sh' = sh(C \ (sfs,Error)) \ \ + P \ \RI (C,Throw a);D#Cs \ e,(h,l,sh),b\ \ \RI (D,Throw a);Cs \ e,(h,l,sh'),b\" +| RInitThrow: "\ sh C = Some(sfs, i); sh' = sh(C \ (sfs,Error)) \ \ + P \ \RI (C,Throw a);Nil \ e,(h,l,sh),b\ \ \Throw a,(h,l,sh'),b\" +(*<*) +lemmas red_reds_induct = red_reds.induct [split_format (complete)] + and red_reds_inducts = red_reds.inducts [split_format (complete)] + +inductive_cases [elim!]: + "P \ \V:=e,s,b\ \ \e',s',b'\" + "P \ \e1;;e2,s,b\ \ \e',s',b'\" +(*>*) + +subsection\ The reflexive transitive closure \ + +abbreviation + Step :: "J_prog \ expr \ state \ bool \ expr \ state \ bool \ bool" + ("_ \ ((1\_,/_,/_\) \*/ (1\_,/_,/_\))" [51,0,0,0,0,0,0] 81) + where "P \ \e,s,b\ \* \e',s',b'\ \ ((e,s,b), e',s',b') \ (red P)\<^sup>*" + +abbreviation + Steps :: "J_prog \ expr list \ state \ bool \ expr list \ state \ bool \ bool" + ("_ \ ((1\_,/_,/_\) [\]*/ (1\_,/_,/_\))" [51,0,0,0,0,0,0] 81) + where "P \ \es,s,b\ [\]* \es',s',b'\ \ ((es,s,b), es',s',b') \ (reds P)\<^sup>*" + + +lemmas converse_rtrancl_induct3 = + converse_rtrancl_induct [of "(ax, ay, az)" "(bx, by, bz)", split_format (complete), + consumes 1, case_names refl step] + +lemma converse_rtrancl_induct_red[consumes 1]: +assumes "P \ \e,(h,l,sh),b\ \* \e',(h',l',sh'),b'\" +and "\e h l sh b. R e h l sh b e h l sh b" +and "\e\<^sub>0 h\<^sub>0 l\<^sub>0 sh\<^sub>0 b\<^sub>0 e\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1 b\<^sub>1 e' h' l' sh' b'. + \ P \ \e\<^sub>0,(h\<^sub>0,l\<^sub>0,sh\<^sub>0),b\<^sub>0\ \ \e\<^sub>1,(h\<^sub>1,l\<^sub>1,sh\<^sub>1),b\<^sub>1\; R e\<^sub>1 h\<^sub>1 l\<^sub>1 sh\<^sub>1 b\<^sub>1 e' h' l' sh' b' \ + \ R e\<^sub>0 h\<^sub>0 l\<^sub>0 sh\<^sub>0 b\<^sub>0 e' h' l' sh' b'" +shows "R e h l sh b e' h' l' sh' b'" +(*<*) +proof - + { fix s s' + assume reds: "P \ \e,s,b\ \* \e',s',b'\" + and base: "\e s b. R e (hp s) (lcl s) (shp s) b e (hp s) (lcl s) (shp s) b" + and red\<^sub>1: "\e\<^sub>0 s\<^sub>0 b\<^sub>0 e\<^sub>1 s\<^sub>1 b\<^sub>1 e' s' b'. + \ P \ \e\<^sub>0,s\<^sub>0,b\<^sub>0\ \ \e\<^sub>1,s\<^sub>1,b\<^sub>1\; R e\<^sub>1 (hp s\<^sub>1) (lcl s\<^sub>1) (shp s\<^sub>1) b\<^sub>1 e' (hp s') (lcl s') (shp s') b' \ + \ R e\<^sub>0 (hp s\<^sub>0) (lcl s\<^sub>0) (shp s\<^sub>0) b\<^sub>0 e' (hp s') (lcl s') (shp s') b'" + from reds have "R e (hp s) (lcl s) (shp s) b e' (hp s') (lcl s') (shp s') b'" + proof (induct rule:converse_rtrancl_induct3) + case refl show ?case by(rule base) + next + case step + thus ?case by(blast intro:red\<^sub>1) + qed + } + with assms show ?thesis by fastforce +qed +(*>*) + + +subsection\Some easy lemmas\ + +lemma [iff]: "\ P \ \[],s,b\ [\] \es',s',b'\" +(*<*)by(blast elim: reds.cases)(*>*) + +lemma [iff]: "\ P \ \Val v,s,b\ \ \e',s',b'\" +(*<*)by(fastforce elim: red.cases)(*>*) + +lemma val_no_step: "val_of e = \v\ \ \ P \ \e,s,b\ \ \e',s',b'\" +(*<*)by(drule val_of_spec, simp)(*>*) + +lemma [iff]: "\ P \ \Throw a,s,b\ \ \e',s',b'\" +(*<*)by(fastforce elim: red.cases)(*>*) + + +lemma map_Vals_no_step [iff]: "\ P \ \map Val vs,s,b\ [\] \es',s',b'\" +(*<*) +apply(induct vs arbitrary: es', simp) +apply(rule notI) +apply(erule reds.cases, auto) +done +(*>*) + +lemma vals_no_step: "map_vals_of es = \vs\ \ \ P \ \es,s,b\ [\] \es',s',b'\" +(*<*)by(drule map_vals_of_spec, simp)(*>*) + +lemma vals_throw_no_step [iff]: "\ P \ \map Val vs @ Throw a # es,s,b\ [\] \es',s',b'\" +(*<*) +apply(induct vs arbitrary: es', auto) +apply(erule reds.cases, auto) +apply(erule reds.cases, auto) +done +(*>*) + +lemma lass_val_of_red: + "\ lass_val_of e = \a\; P \ \e,(h, l, sh),b\ \ \e',(h', l', sh'),b'\ \ + \ e' = unit \ h' = h \ l' = l(fst a\snd a) \ sh' = sh \ b = b'" +(*<*)by(drule lass_val_of_spec, auto)(*>*) + + +lemma final_no_step [iff]: "final e \ \ P \ \e,s,b\ \ \e',s',b'\" +(*<*)by(erule finalE, simp+)(*>*) + +lemma finals_no_step [iff]: "finals es \ \ P \ \es,s,b\ [\] \es',s',b'\" +(*<*)by(erule finalsE, simp+)(*>*) + +lemma reds_final_same: +"P \ \e,s,b\ \* \e',s',b'\ \ final e \ e = e' \ s = s' \ b = b'" +proof(induct rule:converse_rtrancl_induct3) + case refl show ?case by simp +next + case (step e0 s0 b0 e1 s1 b1) show ?case + proof(rule finalE[OF step.prems(1)]) + fix v assume "e0 = Val v" then show ?thesis using step by simp + next + fix a assume "e0 = Throw a" then show ?thesis using step by simp + qed +qed + +lemma reds_throw: +"P \ \e,s,b\ \* \e',s',b'\ \ (\e\<^sub>t. throw_of e = \e\<^sub>t\ \ \e\<^sub>t'. throw_of e' = \e\<^sub>t'\)" +proof(induct rule:converse_rtrancl_induct3) + case refl then show ?case by simp +next + case (step e0 s0 b0 e1 s1 b1) + then show ?case by(auto elim: red.cases) +qed + +lemma red_hext_incr: "P \ \e,(h,l,sh),b\ \ \e',(h',l',sh'),b'\ \ h \ h'" + and reds_hext_incr: "P \ \es,(h,l,sh),b\ [\] \es',(h',l',sh'),b'\ \ h \ h'" +(*<*) +proof(induct rule:red_reds_inducts) + case RedNew thus ?case + by(fastforce dest:new_Addr_SomeD simp:hext_def split:if_splits) +next + case RedFAss thus ?case by(simp add:hext_def split:if_splits) +qed simp_all +(*>*) + + +lemma red_lcl_incr: "P \ \e,(h\<^sub>0,l\<^sub>0,sh\<^sub>0),b\ \ \e',(h\<^sub>1,l\<^sub>1,sh\<^sub>1),b'\ \ dom l\<^sub>0 \ dom l\<^sub>1" +and reds_lcl_incr: "P \ \es,(h\<^sub>0,l\<^sub>0,sh\<^sub>0),b\ [\] \es',(h\<^sub>1,l\<^sub>1,sh\<^sub>1),b'\ \ dom l\<^sub>0 \ dom l\<^sub>1" +(*<*)by(induct rule: red_reds_inducts)(auto simp del:fun_upd_apply)(*>*) + +lemma red_lcl_add: "P \ \e,(h,l,sh),b\ \ \e',(h',l',sh'),b'\ \ (\l\<^sub>0. P \ \e,(h,l\<^sub>0++l,sh),b\ \ \e',(h',l\<^sub>0++l',sh'),b'\)" +and reds_lcl_add: "P \ \es,(h,l,sh),b\ [\] \es',(h',l',sh'),b'\ \ (\l\<^sub>0. P \ \es,(h,l\<^sub>0++l,sh),b\ [\] \es',(h',l\<^sub>0++l',sh'),b'\)" +(*<*) +proof (induct rule:red_reds_inducts) + case RedCast thus ?case by(fastforce intro:red_reds.intros) +next + case RedCastFail thus ?case by(force intro:red_reds.intros) +next + case RedFAcc thus ?case by(fastforce intro:red_reds.intros) +next + case RedCall thus ?case by(fastforce intro:red_reds.intros) +next + case (InitBlockRed e h l V v sh b e' h' l' sh' b' v' T l\<^sub>0) + have IH: "\l\<^sub>0. P \ \e,(h, l\<^sub>0 ++ l(V \ v), sh),b\ \ \e',(h', l\<^sub>0 ++ l', sh'),b'\" + and l'V: "l' V = Some v'" by fact+ + from IH have IH': "P \ \e,(h, (l\<^sub>0 ++ l)(V \ v), sh),b\ \ \e',(h', l\<^sub>0 ++ l', sh'),b'\" + by simp + have "(l\<^sub>0 ++ l')(V := (l\<^sub>0 ++ l) V) = l\<^sub>0 ++ l'(V := l V)" + by(rule ext)(simp add:map_add_def) + with red_reds.InitBlockRed[OF IH'] l'V show ?case by(simp del:fun_upd_apply) +next + case (BlockRedNone e h l V sh b e' h' l' sh' b' T l\<^sub>0) + have IH: "\l\<^sub>0. P \ \e,(h, l\<^sub>0 ++ l(V := None), sh),b\ \ \e',(h', l\<^sub>0 ++ l', sh'),b'\" + and l'V: "l' V = None" and unass: "\ assigned V e" by fact+ + have "l\<^sub>0(V := None) ++ l(V := None) = (l\<^sub>0 ++ l)(V := None)" + by(simp add:fun_eq_iff map_add_def) + hence IH': "P \ \e,(h, (l\<^sub>0++l)(V := None), sh),b\ \ \e',(h', l\<^sub>0(V := None) ++ l', sh'),b'\" + using IH[of "l\<^sub>0(V := None)"] by simp + have "(l\<^sub>0(V := None) ++ l')(V := (l\<^sub>0 ++ l) V) = l\<^sub>0 ++ l'(V := l V)" + by(simp add:fun_eq_iff map_add_def) + with red_reds.BlockRedNone[OF IH' _ unass] l'V show ?case + by(simp add: map_add_def) +next + case (BlockRedSome e h l V sh b e' h' l' sh' b' v T l\<^sub>0) + have IH: "\l\<^sub>0. P \ \e,(h, l\<^sub>0 ++ l(V := None), sh),b\ \ \e',(h', l\<^sub>0 ++ l', sh'),b'\" + and l'V: "l' V = Some v" and unass: "\ assigned V e" by fact+ + have "l\<^sub>0(V := None) ++ l(V := None) = (l\<^sub>0 ++ l)(V := None)" + by(simp add:fun_eq_iff map_add_def) + hence IH': "P \ \e,(h, (l\<^sub>0++l)(V := None), sh),b\ \ \e',(h', l\<^sub>0(V := None) ++ l', sh'),b'\" + using IH[of "l\<^sub>0(V := None)"] by simp + have "(l\<^sub>0(V := None) ++ l')(V := (l\<^sub>0 ++ l) V) = l\<^sub>0 ++ l'(V := l V)" + by(simp add:fun_eq_iff map_add_def) + with red_reds.BlockRedSome[OF IH' _ unass] l'V show ?case + by(simp add:map_add_def) +next + case RedTryCatch thus ?case by(fastforce intro:red_reds.intros) +next + case RedTryFail thus ?case by(force intro!:red_reds.intros) +qed (simp_all add:red_reds.intros) +(*>*) + + +lemma Red_lcl_add: +assumes "P \ \e,(h,l,sh), b\ \* \e',(h',l',sh'), b'\" shows "P \ \e,(h,l\<^sub>0++l,sh),b\ \* \e',(h',l\<^sub>0++l',sh'),b'\" +(*<*) +using assms +proof(induct rule:converse_rtrancl_induct_red) + case 1 thus ?case by simp +next + case 2 thus ?case + by (blast dest: red_lcl_add intro: converse_rtrancl_into_rtrancl) +qed +(*>*) + +lemma assumes wf: "wwf_J_prog P" +shows red_proc_pres: "P \ \e,(h,l,sh),b\ \ \e',(h',l',sh'),b'\ + \ not_init C e \ sh C = \(sfs, Processing)\ \ not_init C e' \ (\sfs'. sh' C = \(sfs', Processing)\)" + and reds_proc_pres: "P \ \es,(h,l,sh),b\ [\] \es',(h',l',sh'),b'\ + \ not_inits C es \ sh C = \(sfs, Processing)\ \ not_inits C es' \ (\sfs'. sh' C = \(sfs', Processing)\)" +(*<*) +proof(induct rule:red_reds_inducts) + case RedCall then show ?case + using sees_wwf_nsub_RI[OF wf RedCall.hyps(2)] sub_RI_blocks_body nsub_RI_not_init by auto +next + case RedSCall then show ?case + using sees_wwf_nsub_RI[OF wf RedSCall.hyps(1)] sub_RI_blocks_body nsub_RI_not_init by auto +next + case (RedInitDone sh C sfs C' Cs e h l b) + then show ?case by(cases Cs, auto) +next + case (RedInitProcessing sh C sfs C' Cs e h l b) + then show ?case by(cases Cs, auto) +next + case (RedRInit sh C sfs i sh' C' Cs v e h l b) + then show ?case by(cases Cs, auto) +next + case (CallThrowParams es vs e es' v M h l sh b) + then show ?case by(auto dest: not_inits_def') +next + case (SCallThrowParams es vs e es' C M h l sh b) + then show ?case by(auto dest: not_inits_def') +qed(auto) + +end diff --git a/thys/JinjaDCI/J/State.thy b/thys/JinjaDCI/J/State.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/J/State.thy @@ -0,0 +1,32 @@ +(* Title: JinjaDCI/J/State.thy + + Author: Tobias Nipkow, Susannah Mansky + Copyright 2003 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory J/State.thy by Tobias Nipkow +*) + +section \ Program State \ + +theory State imports "../Common/Exceptions" begin + +type_synonym + locals = "vname \ val" \ \local vars, incl. params and ``this''\ +type_synonym + state = "heap \ locals \ sheap" + +definition hp :: "state \ heap" +where + "hp \ fst" +definition lcl :: "state \ locals" +where + "lcl \ fst \ snd" +definition shp :: "state \ sheap" +where + "shp \ snd \ snd" + +(*<*) +declare hp_def[simp] lcl_def[simp] shp_def[simp] +(*>*) + +end diff --git a/thys/JinjaDCI/J/TypeSafe.thy b/thys/JinjaDCI/J/TypeSafe.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/J/TypeSafe.thy @@ -0,0 +1,1332 @@ +(* Title: JinjaDCI/J/TypeSafe.thy + + Author: Tobias Nipkow, Susannah Mansky + Copyright 2003 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory J/TypeSafe.thy by Tobias Nipkow +*) + +section \ Type Safety Proof \ + +theory TypeSafe +imports Progress BigStep SmallStep JWellForm +begin + +(* here because it requires well-typing def *) +lemma red_shext_incr: "P \ \e,(h,l,sh),b\ \ \e',(h',l',sh'),b'\ + \ (\E T. P,E,h,sh \ e : T \ sh \\<^sub>s sh')" + and reds_shext_incr: "P \ \es,(h,l,sh),b\ [\] \es',(h',l',sh'),b'\ + \ (\E Ts. P,E,h,sh \ es [:] Ts \ sh \\<^sub>s sh')" +(*<*) +proof(induct rule:red_reds_inducts) qed(auto simp: shext_def) +(*>*) + +lemma wf_types_clinit: +assumes wf:"wf_prog wf_md P" and ex: "class P C = Some a" and proc: "sh C = \(sfs, Processing)\" +shows "P,E,h,sh \ C\\<^sub>sclinit([]) : Void" +proof - + from ex obtain D fs ms where "a = (D,fs,ms)" by(cases a) + then have sP: "(C, D, fs, ms) \ set P" using ex map_of_SomeD[of P C a] by(simp add: class_def) + then have "wf_clinit ms" using assms by(unfold wf_prog_def wf_cdecl_def, auto) + then obtain pns body where sm: "(clinit, Static, [], Void, pns, body) \ set ms" + by(unfold wf_clinit_def) auto + then have "P \ C sees clinit,Static:[] \ Void = (pns,body) in C" + using mdecl_visible[OF wf sP sm] by simp + then show ?thesis using WTrtSCall proc by simp +qed + +subsection\Basic preservation lemmas\ + +text\ First some easy preservation lemmas. \ + +theorem red_preserves_hconf: + "P \ \e,(h,l,sh),b\ \ \e',(h',l',sh'),b'\ \ (\T E. \ P,E,h,sh \ e : T; P \ h \ \ \ P \ h' \)" +and reds_preserves_hconf: + "P \ \es,(h,l,sh),b\ [\] \es',(h',l',sh'),b'\ \ (\Ts E. \ P,E,h,sh \ es [:] Ts; P \ h \ \ \ P \ h' \)" +(*<*) +proof (induct rule:red_reds_inducts) + case (RedNew h a C FDTs h' l sh es) + have new: "new_Addr h = Some a" and fields: "P \ C has_fields FDTs" + and h': "h' = h(a\blank P C)" + and hconf: "P \ h \" by fact+ + from new have None: "h a = None" by(rule new_Addr_SomeD) + moreover have "P,h \ blank P C \" + using fields by(rule oconf_blank) + ultimately show "P \ h' \" using h' by(fast intro: hconf_new[OF hconf]) +next + case (RedFAss C F t D h a fs v l sh b') + let ?fs' = "fs((F,D)\v)" + have hconf: "P \ h \" and ha: "h a = Some(C,fs)" + and wt: "P,E,h,sh \ addr a\F{D}:=Val v : T" by fact+ + from wt ha obtain TF Tv where typeofv: "typeof\<^bsub>h\<^esub> v = Some Tv" + and has: "P \ C has F,NonStatic:TF in D" + and sub: "P \ Tv \ TF" by auto + have "P,h \ (C, ?fs') \" + proof (rule oconf_fupd[OF has]) + show "P,h \ (C, fs) \" using hconf ha by(simp add:hconf_def) + show "P,h \ v :\ TF" using sub typeofv by(simp add:conf_def) + qed + with hconf ha show "P \ h(a\(C, ?fs')) \" by (rule hconf_upd_obj) +qed(auto elim: WTrt.cases) +(*>*) + + +theorem red_preserves_lconf: + "P \ \e,(h,l,sh),b\ \ \e',(h',l',sh'),b'\ \ + (\T E. \ P,E,h,sh \ e:T; P,h \ l (:\) E \ \ P,h' \ l' (:\) E)" +and reds_preserves_lconf: + "P \ \es,(h,l,sh),b\ [\] \es',(h',l',sh'),b'\ \ + (\Ts E. \ P,E,h,sh \ es[:]Ts; P,h \ l (:\) E \ \ P,h' \ l' (:\) E)" +(*<*) +proof(induct rule:red_reds_inducts) + case RedNew thus ?case + by(fast intro:lconf_hext red_hext_incr[OF red_reds.RedNew]) +next + case RedLAss thus ?case by(fastforce elim: lconf_upd simp:conf_def) +next + case RedFAss thus ?case + by(fast intro:lconf_hext red_hext_incr[OF red_reds.RedFAss]) +next + case (InitBlockRed e h l V v sh b e' h' l' sh' b' v' T T') + have red: "P \ \e, (h, l(V\v),sh),b\ \ \e',(h', l',sh'),b'\" + and IH: "\T E . \ P,E,h,sh \ e:T; P,h \ l(V\v) (:\) E \ + \ P,h' \ l' (:\) E" + and l'V: "l' V = Some v'" and lconf: "P,h \ l (:\) E" + and wt: "P,E,h,sh \ {V:T := Val v; e} : T'" by fact+ + from lconf_hext[OF lconf red_hext_incr[OF red]] + have "P,h' \ l (:\) E" . + moreover from IH lconf wt have "P,h' \ l' (:\) E(V\T)" + by(auto simp del: fun_upd_apply simp: fun_upd_same lconf_upd2 conf_def) + ultimately show "P,h' \ l'(V := l V) (:\) E" + by (fastforce simp:lconf_def split:if_split_asm) +next + case (BlockRedNone e h l V sh b e' h' l' sh' b' T T') + have red: "P \ \e,(h, l(V := None),sh),b\ \ \e',(h', l',sh'),b'\" + and IH: "\E T. \ P,E,h,sh \ e : T; P,h \ l(V:=None) (:\) E \ + \ P,h' \ l' (:\) E" + and lconf: "P,h \ l (:\) E" and wt: "P,E,h,sh \ {V:T; e} : T'" by fact+ + from lconf_hext[OF lconf red_hext_incr[OF red]] + have "P,h' \ l (:\) E" . + moreover have "P,h' \ l' (:\) E(V\T)" + by(rule IH, insert lconf wt, auto simp:lconf_def) + ultimately show "P,h' \ l'(V := l V) (:\) E" + by (fastforce simp:lconf_def split:if_split_asm) +next + case (BlockRedSome e h l V sh b e' h' l' sh' b' v T T') + have red: "P \ \e,(h, l(V := None),sh),b\ \ \e',(h', l',sh'),b'\" + and IH: "\E T. \P,E,h,sh \ e : T; P,h \ l(V:=None) (:\) E\ + \ P,h' \ l' (:\) E" + and lconf: "P,h \ l (:\) E" and wt: "P,E,h,sh \ {V:T; e} : T'" by fact+ + from lconf_hext[OF lconf red_hext_incr[OF red]] + have "P,h' \ l (:\) E" . + moreover have "P,h' \ l' (:\) E(V\T)" + by(rule IH, insert lconf wt, auto simp:lconf_def) + ultimately show "P,h' \ l'(V := l V) (:\) E" + by (fastforce simp:lconf_def split:if_split_asm) +qed(auto elim: WTrt.cases) +(*>*) + + +theorem red_preserves_shconf: + "P \ \e,(h,l,sh),b\ \ \e',(h',l',sh'),b'\ \ (\T E. \ P,E,h,sh \ e : T; P,h \\<^sub>s sh \ \ \ P,h' \\<^sub>s sh' \)" +and reds_preserves_shconf: + "P \ \es,(h,l,sh),b\ [\] \es',(h',l',sh'),b'\ \ (\Ts E. \ P,E,h,sh \ es [:] Ts; P,h \\<^sub>s sh \ \ \ P,h' \\<^sub>s sh' \)" +(*<*) +proof (induct rule:red_reds_inducts) + case (RedNew h a C FDTs h' l sh es) + have new: "new_Addr h = Some a" + and h': "h' = h(a\blank P C)" + and shconf: "P,h \\<^sub>s sh \" by fact+ + from new have None: "h a = None" by(rule new_Addr_SomeD) + then show "P,h' \\<^sub>s sh \" using h' by(fast intro: shconf_hnew[OF shconf]) +next + case (RedFAss C F t D h a fs v l sh b) + let ?fs' = "fs((F,D)\v)" + have shconf: "P,h \\<^sub>s sh \" and ha: "h a = Some(C,fs)" by fact+ + then show "P,h(a\(C, ?fs')) \\<^sub>s sh \" by (rule shconf_hupd_obj) +next + case (RedSFAss C F t D sh sfs i sfs' v sh' h l) + let ?sfs' = "sfs(F\v)" + have shconf: "P,h \\<^sub>s sh \" and shD: "sh D = \(sfs, i)\" + and wt: "P,E,h,sh \ C\\<^sub>sF{D} := Val v : T" by fact+ + from wt obtain TF Tv where typeofv: "typeof\<^bsub>h\<^esub> v = Some Tv" + and has: "P \ C has F,Static:TF in D" + and sub: "P \ Tv \ TF" by (auto elim: WTrt.cases) + have has': "P \ D has F,Static:TF in D" using has by(rule has_field_idemp) + have "P,h,D \\<^sub>s ?sfs' \" + proof (rule soconf_fupd[OF has']) + show "P,h,D \\<^sub>s sfs \" using shconf shD by(simp add:shconf_def) + show "P,h \ v :\ TF" using sub typeofv by(simp add:conf_def) + qed + with shconf have "P,h \\<^sub>s sh(D\(?sfs',i)) \" by (rule shconf_upd_obj) + then show ?case using RedSFAss.hyps(3) RedSFAss.hyps(4) by blast +next + case (InitNoneRed sh C C' Cs e h l) + let ?sfs' = "sblank P C" + have "P,h \\<^sub>s sh(C \ (?sfs', Prepared)) \" + proof(rule shconf_upd_obj) + show "P,h \\<^sub>s sh \" using InitNoneRed by simp + show "P,h,C \\<^sub>s sblank P C \" by (metis has_field_def soconf_def soconf_sblank) + qed + then show ?case by blast +next + case (InitObjectRed sh C sfs sh' C' Cs e h l) + have sh': "sh' = sh(C \ (sfs, Processing))" by fact + have "P,h \\<^sub>s sh(C \ (sfs, Processing)) \" + proof(rule shconf_upd_obj) + show "P,h \\<^sub>s sh \" using InitObjectRed by simp + moreover have "sh C = \(sfs, Prepared)\" using InitObjectRed by simp + ultimately show "P,h,C \\<^sub>s sfs \" using shconfD by blast + qed + then show ?case using sh' by blast +next + case (InitNonObjectSuperRed sh C sfs D a b sh' C' Cs e h l) + have sh': "sh' = sh(C \ (sfs, Processing))" by fact + have "P,h \\<^sub>s sh(C \ (sfs, Processing)) \" + proof(rule shconf_upd_obj) + show "P,h \\<^sub>s sh \" using InitNonObjectSuperRed by simp + moreover have "sh C = \(sfs, Prepared)\" using InitNonObjectSuperRed by simp + ultimately show "P,h,C \\<^sub>s sfs \" using shconfD by blast + qed + then show ?case using sh' by blast +next + case (RedRInit sh C sfs i sh' C' Cs e v h l) + have sh': "sh' = sh(C \ (sfs, Done))" by fact + have "P,h \\<^sub>s sh(C \ (sfs, Done)) \" + proof(rule shconf_upd_obj) + show "P,h \\<^sub>s sh \" using RedRInit by simp + moreover have "sh C = \(sfs, i)\" using RedRInit by simp + ultimately show "P,h,C \\<^sub>s sfs \" using shconfD by blast + qed + then show ?case using sh' by blast +next + case (RInitInitThrow sh C sfs i sh' a D Cs e h l) + have sh': "sh' = sh(C \ (sfs, Error))" by fact + have "P,h \\<^sub>s sh(C \ (sfs, Error)) \" + proof(rule shconf_upd_obj) + show "P,h \\<^sub>s sh \" using RInitInitThrow by simp + moreover have "sh C = \(sfs, i)\" using RInitInitThrow by simp + ultimately show "P,h,C \\<^sub>s sfs \" using shconfD by blast + qed + then show ?case using sh' by blast +next + case (RInitThrow sh C sfs i sh' a e' h l) + have sh': "sh' = sh(C \ (sfs, Error))" by fact + have "P,h \\<^sub>s sh(C \ (sfs, Error)) \" + proof(rule shconf_upd_obj) + show "P,h \\<^sub>s sh \" using RInitThrow by simp + moreover have "sh C = \(sfs, i)\" using RInitThrow by simp + ultimately show "P,h,C \\<^sub>s sfs \" using shconfD by blast + qed + then show ?case using sh' by blast +qed(auto elim: WTrt.cases) +(*>*) + +theorem assumes wf: "wwf_J_prog P" +shows red_preserves_iconf: + "P \ \e,(h,l,sh),b\ \ \e',(h',l',sh'),b'\ \ iconf sh e \ iconf sh' e'" +and reds_preserves_iconf: + "P \ \es,(h,l,sh),b\ [\] \es',(h',l',sh'),b'\ \ iconfs sh es \ iconfs sh' es'" +(*<*) +proof (induct rule:red_reds_inducts) + case (BinOpRed1 e h l sh b e' h' l' sh' b' bop e\<^sub>2) + then show ?case using BinOpRed1 nsub_RI_iconf[of e\<^sub>2 sh'] val_of_spec + proof(cases "val_of e") qed(simp,fast) +next + case (FAssRed1 e h l sh b e' h' l' sh' b' F D e\<^sub>2) + then show ?case using FAssRed1 nsub_RI_iconf[of e\<^sub>2 sh'] val_of_spec + proof(cases "val_of e") qed(simp,fast) +next + case (CallObj e h l sh b e' h' l' sh' b' M es) + then show ?case using CallObj nsub_RIs_iconfs[of es sh'] val_of_spec + proof(cases "val_of e") qed(simp,fast) +next + case RedCall then show ?case using sees_wwf_nsub_RI[OF wf RedCall.hyps(2)] + by (clarsimp simp: assigned_def nsub_RI_iconf) +next + case (RedSCall C M Ts T pns body D vs a a b) + then have "\sub_RI (blocks (pns, Ts, vs, body))" + using sees_wwf_nsub_RI[OF wf RedSCall.hyps(1)] by simp + then show ?case by(rule nsub_RI_iconf) +next + case SCallInitRed then show ?case by fastforce +next + case (BlockRedNone e h l V sh b e' h' l' sh' b' T) + then show ?case by auto +next + case (SeqRed e h l sh b e' h' l' sh' b' e\<^sub>2) + then show ?case + proof(cases "lass_val_of e") + case None then show ?thesis using SeqRed nsub_RI_iconf by(auto dest: val_of_spec) + next + case (Some a) + have "e' = unit \ sh' = sh" by(simp add: lass_val_of_red[OF Some SeqRed(1)]) + then show ?thesis using SeqRed Some by(auto dest: val_of_spec) + qed +next + case (ListRed1 e h l sh b e' h' l' sh' b' es) + then show ?case using ListRed1 nsub_RIs_iconfs[of es sh'] val_of_spec + proof(cases "val_of e") qed(simp,fast) +next + case RedInit then show ?case by(auto simp: nsub_RI_iconf) +next + case (RedInitDone sh C sfs C' Cs e h l b) + then show ?case proof(cases Cs) qed(auto simp: initPD_def) +next + case (RedInitProcessing sh C sfs C' Cs e h l b) + then show ?case proof(cases Cs) qed(auto simp: initPD_def) +next + case (RedRInit sh C sfs i sh' C' Cs v e h l b) + then show ?case proof(cases Cs) qed(auto simp: initPD_def) +next + case CallThrowParams then show ?case by(auto simp: iconfs_map_throw) +next + case SCallThrowParams then show ?case by(auto simp: iconfs_map_throw) +qed(auto simp: nsub_RI_iconf lass_val_of_iconf) +(*>*) + + +lemma Seq_bconf_preserve_aux: +assumes "P \ \e,(h, l, sh),b\ \ \e',(h', l', sh'),b'\" and "P,sh \\<^sub>b (e;; e\<^sub>2,b) \" + and "P,sh \\<^sub>b (e::expr,b) \ \ P,sh' \\<^sub>b (e'::expr,b') \" +shows "P,sh' \\<^sub>b (e';;e\<^sub>2,b') \" +proof(cases "val_of e") + case None show ?thesis + proof(cases "lass_val_of e") + case lNone: None show ?thesis + proof(cases "lass_val_of e'") + case lNone': None + then show ?thesis using None assms lNone + by(auto dest: val_of_spec simp: bconf_def option.distinct(1)) + next + case (Some a) + then show ?thesis using None assms lNone by(auto dest: lass_val_of_spec simp: bconf_def) + qed + next + case (Some a) + then show ?thesis using None assms by(auto dest: lass_val_of_spec) + qed +next + case (Some a) + then show ?thesis using assms by(auto dest: val_of_spec) +qed + +theorem red_preserves_bconf: + "P \ \e,(h,l,sh),b\ \ \e',(h',l',sh'),b'\ \ iconf sh e \ P,sh \\<^sub>b (e,b) \ \ P,sh' \\<^sub>b (e',b') \" +and reds_preserves_bconf: + "P \ \es,(h,l,sh),b\ [\] \es',(h',l',sh'),b'\ \ iconfs sh es \ P,sh \\<^sub>b (es,b) \ \ P,sh' \\<^sub>b (es',b') \" +(*<*) +proof (induct rule:red_reds_inducts) + case (CastRed e a a b b e' a a b b' C) then show ?case + proof(cases b') qed(simp, simp add: bconf_def) +next + case (BinOpRed1 e h l sh b e' h' l' sh' b' bop e\<^sub>2) show ?case + proof(cases b') + case True with BinOpRed1 val_of_spec show ?thesis + proof(cases "val_of e") qed(simp,fast) + next + case False then show ?thesis by (simp add: bconf_def) + qed +next +case (BinOpRed2 e a a b b e' a a b b' v\<^sub>1 bop) then show ?case + proof(cases b') qed(simp, simp add: bconf_def) +next + case (LAssRed e a a b b e' a a b b' V) then show ?case + proof(cases b') qed(simp, simp add: bconf_def) +next + case (FAccRed e a a b b e' a a b b' F D) then show ?case + proof(cases b') qed(simp, simp add: bconf_def) +next + case (RedSFAccNonStatic C F t D h l sh b) then show ?case + using has_field_fun[of P C F NonStatic] by (auto simp: bconf_def) +next + case (FAssRed1 e h l sh b e' h' l' sh' b' F D e\<^sub>2) show ?case + proof(cases b') + case True with FAssRed1 val_of_spec show ?thesis + proof(cases "val_of e'")qed((simp,fast)+) + next + case False then show ?thesis by(simp add: bconf_def) + qed +next + case (FAssRed2 e a a b b e' a a b b' v F D) then show ?case + proof(cases b') qed(simp, simp add: bconf_def) +next + case (SFAssRed e h l sh b e' h' l' sh' b' C F D) then show ?case + proof(cases b') qed(fastforce simp: bconf_def val_no_step)+ +next + case (RedSFAssNonStatic C F t D v a a b b) then show ?case + using has_field_fun[of P C F NonStatic] by (auto simp: bconf_def) +next + case (CallObj e h l sh b e' h' l' sh' b' M es) show ?case + proof(cases b') + case True with CallObj val_of_spec show ?thesis + proof(cases "val_of e'")qed((simp,fast)+) + next + case False then show ?thesis by(simp add: bconf_def) + qed +next + case (CallParams es a a b b es' a a b b' v M) then show ?case + proof(cases b') qed(simp, simp add: bconf_def) +next + case (SCallParams es h l sh b es' h' l' sh' b' C M) show ?case + proof(cases b') + case b': True show ?thesis + proof(cases "map_vals_of es'") + case None + then show ?thesis using SCallParams b' vals_no_step + proof(cases "map_vals_of es")qed(clarsimp,fast) + next + case f: Some + then show ?thesis using SCallParams b' vals_no_step + proof(cases "map_vals_of es")qed(clarsimp,fast) + qed + next + case False then show ?thesis by(simp add: bconf_def) + qed +next + case (SCallInitDoneRed C M Ts T pns body D sh sfs vs h l) + then show ?case by(auto simp: bconf_def initPD_def) (rule_tac x=D in exI, auto)+ +next + case (RedSCallNonStatic C M Ts T a b D vs h l sh b) then show ?case + using sees_method_fun[of P C M NonStatic] by (auto simp: bconf_def) +next + case (BlockRedNone e h l V sh b e' h' l' sh' b' T) show ?case + proof(cases "assigned V e'") + case True + then obtain v e2 where "e' = V := Val v;;e2" by(clarsimp simp: assigned_def) + then show ?thesis using BlockRedNone by(clarsimp simp: bconf_def) + next + case False then show ?thesis using BlockRedNone by simp + qed +next + case (BlockRedSome e h l V sh b e' h' l' sh' b' v T) then show ?case + proof(cases b') qed(simp, simp add: bconf_def) +next + case (InitBlockRed e h l V v sh b e' h' l' sh' b' v' T) show ?case + proof(cases b') + case True + then show ?thesis using InitBlockRed by (simp add: assigned_def) + next + case False then show ?thesis by(simp add: bconf_def) + qed +next + case (RedBlock V T u) + then have "\assigned V (Val u)" by(clarsimp simp: assigned_def) + then show ?case using RedBlock by(simp add: bconf_def) +next + case (SeqRed e h l sh b e' h' l' sh' b' e\<^sub>2) + have "iconf sh e" + proof(cases "lass_val_of e") + case (Some a) show ?thesis by(rule lass_val_of_iconf[OF Some]) + next + case None then show ?thesis using SeqRed by(auto dest: val_of_spec) + qed + then show ?case using SeqRed Seq_bconf_preserve_aux by simp +next + case (CondRed e a a b b e' a a b b' e\<^sub>1 e\<^sub>2) then show ?case + proof(cases b') qed(simp, simp add: bconf_def) +next + case (ThrowRed e a a b b e' a a b b') then show ?case + proof(cases b') qed(simp, simp add: bconf_def) +next + case (TryRed e a a b b e' a a b b' C V e\<^sub>2) then show ?case + proof(cases b') qed(simp, simp add: bconf_def) +next + case (ListRed1 e h l sh b e' h' l' sh' b' es) + with val_of_spec show ?case + proof(cases b') qed((clarsimp,fast),simp add: bconfs_def) +next + case (RedInit C b' e X Y b b'') + then show ?case + by(auto simp: bconf_def icheck_ss_exp icheck_init_class icheck_curr_init) +next + case (RInitRed e a a b b e' a a b b' C Cs e\<^sub>0) then show ?case + proof(cases b') qed(simp, simp add: bconf_def) +next + case (BlockThrow V T a) + then have "\assigned V (Throw a)" by(simp add: assigned_def) + then show ?case using BlockThrow by simp +qed(simp_all, auto simp: bconf_def initPD_def) +(*>*) + +text\ Preservation of definite assignment more complex and requires a +few lemmas first. \ + +lemma [iff]: "\A. \ length Vs = length Ts; length vs = length Ts\ \ + \ (blocks (Vs,Ts,vs,e)) A = \ e (A \ \set Vs\)" +(*<*) +apply(induct Vs Ts vs e rule:blocks_induct) +apply(simp_all add:hyperset_defs) +done +(*>*) + + +lemma red_lA_incr: "P \ \e,(h,l,sh),b\ \ \e',(h',l',sh'),b'\ + \ \dom l\ \ \ e \ \dom l'\ \ \ e'" +and reds_lA_incr: "P \ \es,(h,l,sh),b\ [\] \es',(h',l',sh'),b'\ + \ \dom l\ \ \s es \ \dom l'\ \ \s es'" +(*<*) +apply(induct rule:red_reds_inducts) +apply(simp_all del:fun_upd_apply add:hyperset_defs) +apply auto +apply(blast dest:red_lcl_incr)+ +done +(*>*) + +text\ Now preservation of definite assignment. \ + +lemma assumes wf: "wf_J_prog P" +shows red_preserves_defass: + "P \ \e,(h,l,sh),b\ \ \e',(h',l',sh'),b'\ \ \ e \dom l\ \ \ e' \dom l'\" +and "P \ \es,(h,l,sh),b\ [\] \es',(h',l',sh'),b'\ \ \s es \dom l\ \ \s es' \dom l'\" +(*<*) +proof (induct rule:red_reds_inducts) + case BinOpRed1 thus ?case by (auto elim!: D_mono[OF red_lA_incr]) +next + case FAssRed1 thus ?case by (auto elim!: D_mono[OF red_lA_incr]) +next + case CallObj thus ?case by (auto elim!: Ds_mono[OF red_lA_incr]) +next + case RedCall thus ?case + by (auto dest!:sees_wf_mdecl[OF wf] simp:wf_mdecl_def hyperset_defs elim!:D_mono') +next + case RedSCall thus ?case + by (auto dest!:sees_wf_mdecl[OF wf] simp:wf_mdecl_def hyperset_defs elim!:D_mono') +next + case SCallInitRed + then show ?case by(auto simp:hyperset_defs Ds_Vals) +next + case InitBlockRed thus ?case + by(auto simp:hyperset_defs elim!:D_mono' simp del:fun_upd_apply) +next + case BlockRedNone thus ?case + by(auto simp:hyperset_defs elim!:D_mono' simp del:fun_upd_apply) +next + case BlockRedSome thus ?case + by(auto simp:hyperset_defs elim!:D_mono' simp del:fun_upd_apply) +next + case SeqRed thus ?case by (auto elim!: D_mono[OF red_lA_incr]) +next + case CondRed thus ?case by (auto elim!: D_mono[OF red_lA_incr]) +next + case TryRed thus ?case + by (fastforce dest:red_lcl_incr intro:D_mono' simp:hyperset_defs) +next + case ListRed1 thus ?case by (auto elim!: Ds_mono[OF red_lA_incr]) +next + case RedWhile thus ?case by(auto simp:hyperset_defs elim!:D_mono') +next + case RedInit then show ?case by (auto intro: D_mono' simp: hyperset_defs) +next + case (RInitRed e h l sh b e' h' l' sh' b' C Cs e\<^sub>0) + then show ?case by(auto simp:hyperset_defs dest:red_lcl_incr elim!:D_mono') +qed(auto simp:hyperset_defs) +(*>*) + + +text\ Combining conformance of heap, static heap, and local variables: \ + +definition sconf :: "J_prog \ env \ state \ bool" ("_,_ \ _ \" [51,51,51]50) +where + "P,E \ s \ \ let (h,l,sh) = s in P \ h \ \ P,h \ l (:\) E \ P,h \\<^sub>s sh \" + +lemma red_preserves_sconf: + "\ P \ \e,s,b\ \ \e',s',b'\; P,E,hp s,shp s \ e : T; P,E \ s \ \ \ P,E \ s' \" +(*<*) +by(fastforce intro:red_preserves_hconf red_preserves_lconf red_preserves_shconf + simp add:sconf_def) +(*>*) + +lemma reds_preserves_sconf: + "\ P \ \es,s,b\ [\] \es',s',b'\; P,E,hp s,shp s \ es [:] Ts; P,E \ s \ \ \ P,E \ s' \" +(*<*) +by(fastforce intro:reds_preserves_hconf reds_preserves_lconf reds_preserves_shconf + simp add:sconf_def) +(*>*) + + +subsection "Subject reduction" + +lemma wt_blocks: + "\E. \ length Vs = length Ts; length vs = length Ts \ \ + (P,E,h,sh \ blocks(Vs,Ts,vs,e) : T) = + (P,E(Vs[\]Ts),h,sh \ e:T \ (\Ts'. map (typeof\<^bsub>h\<^esub>) vs = map Some Ts' \ P \ Ts' [\] Ts))" +(*<*) +apply(induct Vs Ts vs e rule:blocks_induct) +apply (force simp add:rel_list_all2_Cons2) +apply simp_all +done +(*>*) + +theorem assumes wf: "wf_J_prog P" +shows subject_reduction2: "P \ \e,(h,l,sh),b\ \ \e',(h',l',sh'),b'\ \ + (\E T. \ P,E \ (h,l,sh) \; iconf sh e; P,E,h,sh \ e:T \ + \ \T'. P,E,h',sh' \ e':T' \ P \ T' \ T)" +and subjects_reduction2: "P \ \es,(h,l,sh),b\ [\] \es',(h',l',sh'),b'\ \ + (\E Ts. \ P,E \ (h,l,sh) \; iconfs sh es; P,E,h,sh \ es [:] Ts \ + \ \Ts'. P,E,h',sh' \ es' [:] Ts' \ P \ Ts' [\] Ts)" +(*<*) +proof (induct rule:red_reds_inducts) + case RedNew then show ?case by (auto simp: blank_def) +next + case RedNewFail thus ?case + by (unfold sconf_def hconf_def) (fastforce elim!:typeof_OutOfMemory) +next + case CastRed thus ?case + by(clarsimp simp:is_refT_def) + (blast intro: widens_trans dest!:widen_Class[THEN iffD1]) +next + case RedCastFail thus ?case + by (unfold sconf_def hconf_def) (fastforce elim!:typeof_ClassCast) +next + case (BinOpRed1 e\<^sub>1 h l sh b e\<^sub>1' h' l' sh' b' bop e\<^sub>2) + have red: "P \ \e\<^sub>1,(h,l,sh),b\ \ \e\<^sub>1',(h',l',sh'),b'\" + and IH: "\E T. \P,E \ (h,l,sh) \; iconf sh e\<^sub>1; P,E,h,sh \ e\<^sub>1:T\ + \ \U. P,E,h',sh' \ e\<^sub>1' : U \ P \ U \ T" + and conf: "P,E \ (h,l,sh) \" and iconf: "iconf sh (e\<^sub>1 \bop\ e\<^sub>2)" + and wt: "P,E,h,sh \ e\<^sub>1 \bop\ e\<^sub>2 : T" by fact+ + have val: "val_of e\<^sub>1 = None" using red iconf val_no_step by auto + then have iconf1: "iconf sh e\<^sub>1" and nsub_RI2: "\sub_RI e\<^sub>2" using iconf by simp+ + have "P,E,h',sh' \ e\<^sub>1' \bop\ e\<^sub>2 : T" + proof (cases bop) + assume [simp]: "bop = Eq" + from wt obtain T\<^sub>1 T\<^sub>2 where [simp]: "T = Boolean" + and wt\<^sub>1: "P,E,h,sh \ e\<^sub>1 : T\<^sub>1" and wt\<^sub>2: "P,E,h,sh \ e\<^sub>2 : T\<^sub>2" by auto + show ?thesis + using WTrt_hext_shext_mono[OF wt\<^sub>2 red_hext_incr[OF red] red_shext_incr[OF red wt\<^sub>1] nsub_RI2] + IH[OF conf iconf1 wt\<^sub>1] by auto + next + assume [simp]: "bop = Add" + from wt have [simp]: "T = Integer" + and wt\<^sub>1: "P,E,h,sh \ e\<^sub>1 : Integer" and wt\<^sub>2: "P,E,h,sh \ e\<^sub>2 : Integer" + by auto + show ?thesis + using WTrt_hext_shext_mono[OF wt\<^sub>2 red_hext_incr[OF red] red_shext_incr[OF red wt\<^sub>1] nsub_RI2] + IH[OF conf iconf1 wt\<^sub>1] by auto + qed + thus ?case by auto +next + case (BinOpRed2 e\<^sub>2 h l sh b e\<^sub>2' h' l' sh' b' v\<^sub>1 bop) + have red: "P \ \e\<^sub>2,(h,l,sh),b\ \ \e\<^sub>2',(h',l',sh'),b'\" + and IH: "\E T. \P,E \ (h,l,sh) \; iconf sh e\<^sub>2; P,E,h,sh \ e\<^sub>2:T\ + \ \U. P,E,h',sh' \ e\<^sub>2' : U \ P \ U \ T" + and conf: "P,E \ (h,l,sh) \" and iconf: "iconf sh (Val v\<^sub>1 \bop\ e\<^sub>2)" + and wt: "P,E,h,sh \ (Val v\<^sub>1) \bop\ e\<^sub>2 : T" by fact+ + have iconf2: "iconf sh e\<^sub>2" using iconf by simp + have "P,E,h',sh' \ (Val v\<^sub>1) \bop\ e\<^sub>2' : T" + proof (cases bop) + assume [simp]: "bop = Eq" + from wt obtain T\<^sub>1 T\<^sub>2 where [simp]: "T = Boolean" + and wt\<^sub>1: "P,E,h,sh \ Val v\<^sub>1 : T\<^sub>1" and wt\<^sub>2: "P,E,h,sh \ e\<^sub>2:T\<^sub>2" by auto + show ?thesis + using IH[OF conf iconf2 wt\<^sub>2] WTrt_hext_mono[OF wt\<^sub>1 red_hext_incr[OF red]] + by auto + next + assume [simp]: "bop = Add" + from wt have [simp]: "T = Integer" + and wt\<^sub>1: "P,E,h,sh \ Val v\<^sub>1 : Integer" and wt\<^sub>2: "P,E,h,sh \ e\<^sub>2 : Integer" + by auto + show ?thesis + using IH[OF conf iconf2 wt\<^sub>2] WTrt_hext_mono[OF wt\<^sub>1 red_hext_incr[OF red]] + by auto + qed + thus ?case by auto +next + case (RedBinOp bop) thus ?case + proof (cases bop) + case Eq thus ?thesis using RedBinOp by auto + next + case Add thus ?thesis using RedBinOp by auto + qed +next + case RedVar thus ?case by (fastforce simp:sconf_def lconf_def conf_def) +next + case (LAssRed e h l sh b e' h' l' sh' b' V) + obtain Te where Te: "P,E,h,sh \ e : Te \ P \ Te \ the(E V)" using LAssRed.prems(3) by auto + then have wide: "P \ Te \ the(E V)" using LAssRed by simp + then have "\T'. P,E,h',sh' \ e' : T' \ P \ T' \ Te" + using LAssRed.hyps(2) LAssRed.prems(1,2) Te widen_trans[OF _ wide] by auto + then obtain T' where wt: "P,E,h',sh' \ e' : T' \ P \ T' \ Te" by clarsimp + have "P,E,h',sh' \ V:=e' : Void" using LAssRed wt widen_trans[OF _ wide] by auto + then show ?case using LAssRed by(rule_tac x = Void in exI) auto +next + case (FAccRed e h l sh b e' h' l' sh' b' F D) + have IH: "\E T. \P,E \ (h,l,sh) \; iconf sh e; P,E,h,sh \ e : T\ + \ \U. P,E,h',sh' \ e' : U \ P \ U \ T" + and conf: "P,E \ (h,l,sh) \" and iconf: "iconf sh (e\F{D})" + and wt: "P,E,h,sh \ e\F{D} : T" by fact+ + have iconf': "iconf sh e" using iconf by simp+ + \ \The goal: ?case = @{prop ?case}\ + \ \Now distinguish the two cases how wt can have arisen.\ + { fix C assume wte: "P,E,h,sh \ e : Class C" + and has: "P \ C has F,NonStatic:T in D" + from IH[OF conf iconf' wte] + obtain U where wte': "P,E,h',sh' \ e' : U" and UsubC: "P \ U \ Class C" + by auto + \ \Now distinguish what @{term U} can be.\ + { assume "U = NT" hence ?case using wte' + by(blast intro:WTrtFAccNT widen_refl) } + moreover + { fix C' assume U: "U = Class C'" and C'subC: "P \ C' \\<^sup>* C" + from has_field_mono[OF has C'subC] wte' U + have ?case by(blast intro:WTrtFAcc) } + ultimately have ?case using UsubC by(simp add: widen_Class) blast } + moreover + { assume "P,E,h,sh \ e : NT" + hence "P,E,h',sh' \ e' : NT" using IH[OF conf iconf'] by fastforce + hence ?case by(fastforce intro:WTrtFAccNT widen_refl) } + ultimately show ?case using wt by blast +next + case RedFAcc thus ?case + by(fastforce simp:sconf_def hconf_def oconf_def conf_def has_field_def + dest:has_fields_fun) +next + case RedFAccNull thus ?case + by(fastforce intro: widen_refl WTThrow[OF WTVal] elim!: typeof_NullPointer + simp: sconf_def hconf_def) +next + case RedSFAccNone then show ?case + by(fastforce intro: WTrtThrow[OF WTrtVal] elim!: typeof_NoSuchFieldError + simp: sconf_def hconf_def) +next + case RedFAccStatic then show ?case + by(fastforce intro: WTrtThrow[OF WTrtVal] elim!: typeof_IncompatibleClassChangeError + simp: sconf_def hconf_def) +next + case (RedSFAcc C F t D sh sfs i v h l es) + then have "P \ C has F,Static:T in D" by fast + then have dM: "P \ D has F,Static:T in D" by(rule has_field_idemp) + then show ?case using RedSFAcc by(fastforce simp:sconf_def shconf_def soconf_def conf_def) +next + case SFAccInitDoneRed then show ?case by (meson widen_refl) +next + case (SFAccInitRed C F t D sh h l E T) + have "is_class P D" using SFAccInitRed.hyps(1) by(rule has_field_is_class') + then have "P,E,h,sh \ INIT D ([D],False) \ C\\<^sub>sF{D} : T \ P \ T \ T" + using SFAccInitRed WTrtInit[OF SFAccInitRed.prems(3)] by clarsimp + then show ?case by(rule exI) +next + case RedSFAccNonStatic then show ?case + by(fastforce intro: WTrtThrow[OF WTrtVal] elim!: typeof_IncompatibleClassChangeError + simp: sconf_def hconf_def) +next + case (FAssRed1 e h l sh b e' h' l' sh' b' F D e\<^sub>2) + have red: "P \ \e,(h,l,sh),b\ \ \e',(h',l',sh'),b'\" + and IH: "\E T. \P,E \ (h,l,sh) \; iconf sh e; P,E,h,sh \ e : T\ + \ \U. P,E,h',sh' \ e' : U \ P \ U \ T" + and conf: "P,E \ (h,l,sh) \" and iconf: "iconf sh (e\F{D} := e\<^sub>2)" + and wt: "P,E,h,sh \ e\F{D}:=e\<^sub>2 : T" by fact+ + have val: "val_of e = None" using red iconf val_no_step by auto + then have iconf': "iconf sh e" and nsub_RI2: "\sub_RI e\<^sub>2" using iconf by simp+ + from wt have void: "T = Void" by blast + \ \We distinguish if @{term e} has type @{term NT} or a Class type\ + \ \Remember ?case = @{term ?case}\ + { assume wt':"P,E,h,sh \ e : NT" + hence "P,E,h',sh' \ e' : NT" using IH[OF conf iconf'] by fastforce + moreover obtain T\<^sub>2 where "P,E,h,sh \ e\<^sub>2 : T\<^sub>2" using wt by auto + from this red_hext_incr[OF red] red_shext_incr[OF red wt'] nsub_RI2 have "P,E,h',sh' \ e\<^sub>2 : T\<^sub>2" + by(rule WTrt_hext_shext_mono) + ultimately have ?case using void by(blast intro!:WTrtFAssNT) + } + moreover + { fix C TF T\<^sub>2 assume wt\<^sub>1: "P,E,h,sh \ e : Class C" and wt\<^sub>2: "P,E,h,sh \ e\<^sub>2 : T\<^sub>2" + and has: "P \ C has F,NonStatic:TF in D" and sub: "P \ T\<^sub>2 \ TF" + obtain U where wt\<^sub>1': "P,E,h',sh' \ e' : U" and UsubC: "P \ U \ Class C" + using IH[OF conf iconf' wt\<^sub>1] by blast + have wt\<^sub>2': "P,E,h',sh' \ e\<^sub>2 : T\<^sub>2" + by(rule WTrt_hext_shext_mono[OF wt\<^sub>2 red_hext_incr[OF red] red_shext_incr[OF red wt\<^sub>1] nsub_RI2]) + \ \Is @{term U} the null type or a class type?\ + { assume "U = NT" with wt\<^sub>1' wt\<^sub>2' void have ?case + by(blast intro!:WTrtFAssNT) } + moreover + { fix C' assume UClass: "U = Class C'" and "subclass": "P \ C' \\<^sup>* C" + have "P,E,h',sh' \ e' : Class C'" using wt\<^sub>1' UClass by auto + moreover have "P \ C' has F,NonStatic:TF in D" + by(rule has_field_mono[OF has "subclass"]) + ultimately have ?case using wt\<^sub>2' sub void by(blast intro:WTrtFAss) } + ultimately have ?case using UsubC by(auto simp add:widen_Class) } + ultimately show ?case using wt by blast +next + case (FAssRed2 e\<^sub>2 h l sh b e\<^sub>2' h' l' sh' b' v F D) + have red: "P \ \e\<^sub>2,(h,l,sh),b\ \ \e\<^sub>2',(h',l',sh'),b'\" + and IH: "\E T. \P,E \ (h,l,sh) \; iconf sh e\<^sub>2; P,E,h,sh \ e\<^sub>2 : T\ + \ \U. P,E,h',sh' \ e\<^sub>2' : U \ P \ U \ T" + and conf: "P,E \ (h,l,sh) \" and iconf: "iconf sh (Val v\F{D} := e\<^sub>2)" + and wt: "P,E,h,sh \ Val v\F{D}:=e\<^sub>2 : T" by fact+ + have iconf2: "iconf sh e\<^sub>2" using iconf by simp + from wt have [simp]: "T = Void" by auto + from wt show ?case + proof (rule WTrt_elim_cases) + fix C TF T\<^sub>2 + assume wt\<^sub>1: "P,E,h,sh \ Val v : Class C" + and has: "P \ C has F,NonStatic:TF in D" + and wt\<^sub>2: "P,E,h,sh \ e\<^sub>2 : T\<^sub>2" and TsubTF: "P \ T\<^sub>2 \ TF" + have wt\<^sub>1': "P,E,h',sh' \ Val v : Class C" + using WTrt_hext_mono[OF wt\<^sub>1 red_hext_incr[OF red]] by auto + obtain T\<^sub>2' where wt\<^sub>2': "P,E,h',sh' \ e\<^sub>2' : T\<^sub>2'" and T'subT: "P \ T\<^sub>2' \ T\<^sub>2" + using IH[OF conf iconf2 wt\<^sub>2] by blast + have "P,E,h',sh' \ Val v\F{D}:=e\<^sub>2' : Void" + by(rule WTrtFAss[OF wt\<^sub>1' has wt\<^sub>2' widen_trans[OF T'subT TsubTF]]) + thus ?case by auto + next + fix T\<^sub>2 assume null: "P,E,h,sh \ Val v : NT" and wt\<^sub>2: "P,E,h,sh \ e\<^sub>2 : T\<^sub>2" + from null have "v = Null" by simp + moreover + obtain T\<^sub>2' where "P,E,h',sh' \ e\<^sub>2' : T\<^sub>2' \ P \ T\<^sub>2' \ T\<^sub>2" + using IH[OF conf iconf2 wt\<^sub>2] by blast + ultimately show ?thesis by(fastforce intro:WTrtFAssNT) + qed +next + case RedFAss thus ?case by(auto simp del:fun_upd_apply) +next + case RedFAssNull thus ?case + by(fastforce intro: WTThrow[OF WTVal] elim!:typeof_NullPointer simp:sconf_def hconf_def) +next + case RedFAssStatic then show ?case + by(fastforce intro: WTrtThrow[OF WTrtVal] elim!: typeof_IncompatibleClassChangeError + simp: sconf_def hconf_def) +next + case (SFAssRed e h l sh b e' h' l' sh' b' C F D E T) + have IH: "\E T. \P,E \ (h,l,sh) \; iconf sh e; P,E,h,sh \ e : T\ + \ \U. P,E,h',sh' \ e' : U \ P \ U \ T" + and conf: "P,E \ (h,l,sh) \" and iconf: "iconf sh (C\\<^sub>sF{D} := e)" + and wt: "P,E,h,sh \ C\\<^sub>sF{D}:=e : T" by fact+ + have iconf': "iconf sh e" using iconf by simp + from wt have [simp]: "T = Void" by auto + from wt show ?case + proof (rule WTrt_elim_cases) + fix TF T1 + assume has: "P \ C has F,Static:TF in D" + and wt1: "P,E,h,sh \ e : T1" and TsubTF: "P \ T1 \ TF" + obtain T' where wt1': "P,E,h',sh' \ e' : T'" and T'subT: "P \ T' \ T1" + using IH[OF conf iconf' wt1] by blast + have "P,E,h',sh' \ C\\<^sub>sF{D}:=e' : Void" + by(rule WTrtSFAss[OF wt1' has widen_trans[OF T'subT TsubTF]]) + thus ?case by auto + qed +next + case SFAssInitDoneRed then show ?case by (meson widen_refl) +next + case (SFAssInitRed C F t D sh v h l E T) + have "is_class P D" using SFAssInitRed.hyps(1) by(rule has_field_is_class') + then have "P,E,h,sh \ INIT D ([D],False) \ C\\<^sub>sF{D} := Val v : T \ P \ T \ T" + using SFAssInitRed WTrtInit[OF SFAssInitRed.prems(3)] by clarsimp + then show ?case by(rule exI) +next + case RedSFAssNone then show ?case + by(fastforce intro: WTrtThrow[OF WTrtVal] elim!: typeof_NoSuchFieldError + simp: sconf_def hconf_def) +next + case RedSFAssNonStatic then show ?case + by(fastforce intro: WTrtThrow[OF WTrtVal] elim!: typeof_IncompatibleClassChangeError + simp: sconf_def hconf_def) +next + case (CallObj e h l sh b e' h' l' sh' b' M es) + have red: "P \ \e,(h,l,sh),b\ \ \e',(h',l',sh'),b'\" + and IH: "\E T. \P,E \ (h,l,sh) \; iconf sh e; P,E,h,sh \ e : T\ + \ \U. P,E,h',sh' \ e' : U \ P \ U \ T" + and conf: "P,E \ (h,l,sh) \" and iconf: "iconf sh (e\M(es))" + and wt: "P,E,h,sh \ e\M(es) : T" by fact+ + have val: "val_of e = None" using red iconf val_no_step by auto + then have iconf': "iconf sh e" and nsub_RIs: "\sub_RIs es" using iconf by simp+ + \ \We distinguish if @{term e} has type @{term NT} or a Class type\ + \ \Remember ?case = @{term ?case}\ + { assume wt':"P,E,h,sh \ e:NT" + hence "P,E,h',sh' \ e' : NT" using IH[OF conf iconf'] by fastforce + moreover + fix Ts assume wtes: "P,E,h,sh \ es [:] Ts" + have "P,E,h',sh' \ es [:] Ts" + by(rule WTrts_hext_shext_mono[OF wtes red_hext_incr[OF red] red_shext_incr[OF red wt'] nsub_RIs]) + ultimately have ?case by(blast intro!:WTrtCallNT) } + moreover + { fix C D Ts Us pns body + assume wte: "P,E,h,sh \ e : Class C" + and "method": "P \ C sees M,NonStatic:Ts\T = (pns,body) in D" + and wtes: "P,E,h,sh \ es [:] Us" and subs: "P \ Us [\] Ts" + obtain U where wte': "P,E,h',sh' \ e' : U" and UsubC: "P \ U \ Class C" + using IH[OF conf iconf' wte] by blast + \ \Is @{term U} the null type or a class type?\ + { assume "U = NT" + moreover have "P,E,h',sh' \ es [:] Us" + by(rule WTrts_hext_shext_mono[OF wtes red_hext_incr[OF red] red_shext_incr[OF red wte] nsub_RIs]) + ultimately have ?case using wte' by(blast intro!:WTrtCallNT) } + moreover + { fix C' assume UClass: "U = Class C'" and "subclass": "P \ C' \\<^sup>* C" + have "P,E,h',sh' \ e' : Class C'" using wte' UClass by auto + moreover obtain Ts' T' pns' body' D' + where method': "P \ C' sees M,NonStatic:Ts'\T' = (pns',body') in D'" + and subs': "P \ Ts [\] Ts'" and sub': "P \ T' \ T" + using Call_lemma[OF "method" "subclass" wf] by fast + moreover have "P,E,h',sh' \ es [:] Us" + by(rule WTrts_hext_shext_mono[OF wtes red_hext_incr[OF red] red_shext_incr[OF red wte] nsub_RIs]) + ultimately have ?case + using subs by(blast intro:WTrtCall rtrancl_trans widens_trans) } + ultimately have ?case using UsubC by(auto simp add:widen_Class) } + ultimately show ?case using wt by auto +next + case (CallParams es h l sh b es' h' l' sh' b' v M) + have reds: "P \ \es,(h,l,sh),b\ [\] \es',(h',l',sh'),b'\" + and IH: "\E Ts. \P,E \ (h,l,sh) \; iconfs sh es; P,E,h,sh \ es [:] Ts\ + \ \Us. P,E,h',sh' \ es' [:] Us \ P \ Us [\] Ts" + and conf: "P,E \ (h,l,sh) \" and iconf: "iconf sh (Val v\M(es))" + and wt: "P,E,h,sh \ Val v\M(es) : T" by fact+ + have iconfs: "iconfs sh es" using iconf by simp + from wt show ?case + proof (rule WTrt_elim_cases) + fix C D Ts Us pns body + assume wte: "P,E,h,sh \ Val v : Class C" + and "P \ C sees M,NonStatic:Ts\T = (pns,body) in D" + and wtes: "P,E,h,sh \ es [:] Us" and "P \ Us [\] Ts" + moreover have "P,E,h',sh' \ Val v : Class C" + using WTrt_hext_mono[OF wte reds_hext_incr[OF reds]] by auto + moreover + obtain Us' where "P,E,h',sh' \ es' [:] Us' \ P \ Us' [\] Us" + using IH[OF conf iconfs wtes] by blast + ultimately show ?thesis by(blast intro:WTrtCall widens_trans) + next + fix Us + assume null: "P,E,h,sh \ Val v : NT" and wtes: "P,E,h,sh \ es [:] Us" + from null have "v = Null" by simp + moreover + obtain Us' where "P,E,h',sh' \ es' [:] Us' \ P \ Us' [\] Us" + using IH[OF conf iconfs wtes] by blast + ultimately show ?thesis by(fastforce intro:WTrtCallNT) + qed +next + case (RedCall h a C fs M Ts T pns body D vs l sh b E T') + have hp: "h a = Some(C,fs)" + and "method": "P \ C sees M,NonStatic: Ts\T = (pns,body) in D" + and wt: "P,E,h,sh \ addr a\M(map Val vs) : T'" by fact+ + obtain Ts' where wtes: "P,E,h,sh \ map Val vs [:] Ts'" + and subs: "P \ Ts' [\] Ts" and T'isT: "T' = T" + using wt "method" hp by (auto dest:sees_method_fun) + from wtes subs have length_vs: "length vs = length Ts" + by(fastforce simp:list_all2_iff dest!:WTrts_same_length) + from sees_wf_mdecl[OF wf "method"] obtain T'' + where wtabody: "P,[this#pns [\] Class D#Ts] \ body :: T''" + and T''subT: "P \ T'' \ T" and length_pns: "length pns = length Ts" + by(fastforce simp:wf_mdecl_def simp del:map_upds_twist) + from wtabody have "P,Map.empty(this#pns [\] Class D#Ts),h,sh \ body : T''" + by(rule WT_implies_WTrt) + hence "P,E(this#pns [\] Class D#Ts),h,sh \ body : T''" + by(rule WTrt_env_mono) simp + hence "P,E,h,sh \ blocks(this#pns, Class D#Ts, Addr a#vs, body) : T''" + using wtes subs hp sees_method_decl_above[OF "method"] length_vs length_pns + by(fastforce simp add:wt_blocks rel_list_all2_Cons2) + with T''subT T'isT show ?case by blast +next + case RedCallNull thus ?case + by(fastforce intro: WTThrow[OF WTVal] elim!:typeof_NullPointer simp: sconf_def hconf_def) +next + case RedCallStatic then show ?case + by(fastforce intro: WTrtThrow[OF WTrtVal] elim!: typeof_IncompatibleClassChangeError + simp: sconf_def hconf_def) +next + case (SCallParams es h l sh b es' h' l' sh' b' C M) + have IH: "\E Ts. \P,E \ (h,l,sh) \; iconfs sh es; P,E,h,sh \ es [:] Ts\ + \ \Us. P,E,h',sh' \ es' [:] Us \ P \ Us [\] Ts" + and conf: "P,E \ (h,l,sh) \" and iconf: "iconf sh (C\\<^sub>sM(es))" + and wt: "P,E,h,sh \ C\\<^sub>sM(es) : T" by fact+ + have iconfs: "iconfs sh es" using iconf by simp + from wt show ?case + proof (rule WTrt_elim_cases) + fix D Ts Us pns body sfs vs + assume method: "P \ C sees M,Static:Ts\T = (pns,body) in D" + and wtes: "P,E,h,sh \ es [:] Us" and us: "P \ Us [\] Ts" + and clinit: "M = clinit \ sh D = \(sfs,Processing)\ \ es = map Val vs" + obtain Us' where es': "P,E,h',sh' \ es' [:] Us'" and us': "P \ Us' [\] Us" + using IH[OF conf iconfs wtes] by blast + show ?thesis + proof(cases "M = clinit") + case True then show ?thesis using clinit SCallParams.hyps(1) by blast + next + case False + then show ?thesis using es' method us us' by(blast intro:WTrtSCall widens_trans) + qed + qed +next + case (RedSCall C M Ts T pns body D vs h l sh E T') + have "method": "P \ C sees M,Static: Ts\T = (pns,body) in D" + and wt: "P,E,h,sh \ C\\<^sub>sM(map Val vs) : T'" by fact+ + obtain Ts' where wtes: "P,E,h,sh \ map Val vs [:] Ts'" + and subs: "P \ Ts' [\] Ts" and T'isT: "T' = T" + using wt "method" map_Val_eq by(auto dest:sees_method_fun)+ + from wtes subs have length_vs: "length vs = length Ts" + by(fastforce simp:list_all2_iff dest!:WTrts_same_length) + from sees_wf_mdecl[OF wf "method"] obtain T'' + where wtabody: "P,[pns [\] Ts] \ body :: T''" + and T''subT: "P \ T'' \ T" and length_pns: "length pns = length Ts" + by(fastforce simp:wf_mdecl_def simp del:map_upds_twist) + from wtabody have "P,Map.empty(pns [\] Ts),h,sh \ body : T''" + by(rule WT_implies_WTrt) + hence "P,E(pns [\] Ts),h,sh \ body : T''" + by(rule WTrt_env_mono) simp + hence "P,E,h,sh \ blocks(pns, Ts, vs, body) : T''" + using wtes subs sees_method_decl_above[OF "method"] length_vs length_pns + by(fastforce simp add:wt_blocks rel_list_all2_Cons2) + with T''subT T'isT show ?case by blast +next + case SCallInitDoneRed then show ?case by (meson widen_refl) +next + case (SCallInitRed C F Ts t pns body D sh v h l E T) + have "is_class P D" using SCallInitRed.hyps(1) by(rule sees_method_is_class') + then have "P,E,h,sh \ INIT D ([D],False) \ C\\<^sub>sF(map Val v) : T \ P \ T \ T" + using SCallInitRed WTrtInit[OF SCallInitRed.prems(3)] by clarsimp + then show ?case by(rule exI) +next + case RedSCallNone then show ?case + by(fastforce intro: WTrtThrow[OF WTrtVal] elim!: typeof_NoSuchMethodError + simp: sconf_def hconf_def) +next + case RedSCallNonStatic then show ?case + by(fastforce intro: WTrtThrow[OF WTrtVal] elim!: typeof_IncompatibleClassChangeError + simp: sconf_def hconf_def) +next + case BlockRedNone thus ?case + by(auto simp del:fun_upd_apply)(fastforce simp:sconf_def lconf_def) +next + case (BlockRedSome e h l V sh b e' h' l' sh' b' v T E Te) + have red: "P \ \e,(h,l(V:=None),sh),b\ \ \e',(h',l',sh'),b'\" + and IH: "\E T. \P,E \ (h,l(V:=None),sh) \; iconf sh e; P,E,h,sh \ e : T\ + \ \T'. P,E,h',sh' \ e' : T' \ P \ T' \ T" + and Some: "l' V = Some v" and conf: "P,E \ (h,l,sh) \" + and iconf: "iconf sh {V:T; e}" + and wt: "P,E,h,sh \ {V:T; e} : Te" by fact+ + obtain Te' where IH': "P,E(V\T),h',sh' \ e' : Te' \ P \ Te' \ Te" + using IH conf iconf wt by(fastforce simp:sconf_def lconf_def) + have "P,h' \ l' (:\) E(V\T)" using conf wt + by(fastforce intro:red_preserves_lconf[OF red] simp:sconf_def lconf_def) + hence "P,h' \ v :\ T" using Some by(fastforce simp:lconf_def) + with IH' show ?case + by(fastforce simp:sconf_def conf_def fun_upd_same simp del:fun_upd_apply) +next + case (InitBlockRed e h l V v sh b e' h' l' sh' b' v' T E T') + have red: "P \ \e, (h,l(V\v),sh),b\ \ \e',(h',l',sh'),b'\" + and IH: "\E T. \P,E \ (h,l(V\v),sh) \; iconf sh e; P,E,h,sh \ e : T\ + \ \U. P,E,h',sh' \ e' : U \ P \ U \ T" + and v': "l' V = Some v'" and conf: "P,E \ (h,l,sh) \" + and iconf: "iconf sh {V:T; V:=Val v;; e}" + and wt: "P,E,h,sh \ {V:T := Val v; e} : T'" by fact+ + from wt obtain T\<^sub>1 where wt\<^sub>1: "typeof\<^bsub>h\<^esub> v = Some T\<^sub>1" + and T1subT: "P \ T\<^sub>1 \ T" and wt\<^sub>2: "P,E(V\T),h,sh \ e : T'" by auto + have lconf\<^sub>2: "P,h \ l(V\v) (:\) E(V\T)" using conf wt\<^sub>1 T1subT + by(simp add:sconf_def lconf_upd2 conf_def) + have "\T\<^sub>1'. typeof\<^bsub>h'\<^esub> v' = Some T\<^sub>1' \ P \ T\<^sub>1' \ T" + using v' red_preserves_lconf[OF red wt\<^sub>2 lconf\<^sub>2] + by(fastforce simp:lconf_def conf_def) + with IH conf iconf lconf\<^sub>2 wt\<^sub>2 show ?case by (fastforce simp add:sconf_def) +next + case (SeqRed e h l sh b e' h' l' sh' b' e\<^sub>2) + then have val: "val_of e = None" by (simp add: val_no_step) + show ?case + proof(cases "lass_val_of e") + case None + then show ?thesis + using SeqRed val by(auto elim: WTrt_hext_shext_mono[OF _ red_hext_incr red_shext_incr]) + next + case (Some a) + have "sh = sh'" using SeqRed lass_val_of_spec[OF Some] by auto + then show ?thesis using SeqRed val Some + by(auto intro: lass_val_of_iconf[OF Some] elim: WTrt_hext_mono[OF _ red_hext_incr]) + qed +next + case CondRed thus ?case + by auto (blast intro:WTrt_hext_shext_mono[OF _ red_hext_incr red_shext_incr])+ +next + case ThrowRed thus ?case + by(auto simp:is_refT_def)(blast dest:widen_Class[THEN iffD1])+ +next + case RedThrowNull thus ?case + by(fastforce intro: WTThrow[OF WTVal] elim!:typeof_NullPointer simp:sconf_def hconf_def) +next + case TryRed thus ?case + by auto (blast intro:widen_trans WTrt_hext_shext_mono[OF _ red_hext_incr red_shext_incr]) +next + case RedTryFail thus ?case + by(fastforce intro: WTrtThrow[OF WTrtVal] simp:sconf_def hconf_def) +next + case (ListRed1 e h l sh b e' h' l' sh' b' es) + then have val: "val_of e = None" by(simp add: val_no_step) + obtain U Us where Ts: "Ts = U # Us" using ListRed1 by auto + then have nsub_RI: "\ sub_RIs es" and wts: "P,E,h,sh \ es [:] Us" and wt: "P,E,h,sh \ e : U" + and IH: "\E T. \P,E \ (h, l, sh) \; P,E,h,sh \ e : T\ \ \T'. P,E,h',sh' \ e' : T' \ P \ T' \ T" + using ListRed1 val by auto + obtain T' where + "\E0 E1. (\T2. P,E1,h',sh' \ e' : T2 \ P \ T2 \ E0) = (P,E1,h',sh' \ e' : T' E0 E1 \ P \ T' E0 E1 \ E0)" + by moura + then have disj: "\E t. \ P,E \ (h, l, sh) \ \ \ P,E,h,sh \ e : t \ P,E,h',sh' \ e' : T' t E \ P \ T' t E \ t" + using IH by presburger + have "P,E,h',sh' \ es [:] Us" + using nsub_RI wts wt by (metis (no_types) ListRed1.hyps(1) WTrts_hext_shext_mono red_hext_incr red_shext_incr) + then have "\ts. (\t tsa. ts = t # tsa \ P,E,h',sh' \ e' : t \ P,E,h',sh' \ es [:] tsa) \ P \ ts [\] (U # Us)" + using disj wt ListRed1.prems(1) by blast + then show ?case using Ts by auto +next + case ListRed2 thus ?case + by(fastforce dest: hext_typeof_mono[OF reds_hext_incr]) +next + case (InitNoneRed sh C C' Cs e h l b) + then have sh: "sh \\<^sub>s sh(C \ (sblank P C, Prepared))" by(simp add: shext_def) + have wt: "P,E,h,sh(C \ (sblank P C, Prepared)) \ INIT C' (C # Cs,False) \ e : T" + using InitNoneRed WTrt_shext_mono[OF _ sh] by fastforce + then show ?case by(rule_tac x = T in exI) (simp add: fun_upd_def) +next + case (RedInitDone sh C sfs C' Cs e h l b) + then have "P,E,h,sh \ INIT C' (Cs,True) \ e : T" by auto (metis Nil_tl list.set_sel(2)) + then show ?case by(rule_tac x = T in exI) simp +next + case (RedInitProcessing sh C sfs C' Cs e h l b) + then have "P,E,h,sh \ INIT C' (Cs,True) \ e : T" by auto (metis Nil_tl list.set_sel(2))+ + then show ?case by(rule_tac x = T in exI) simp +next + case RedInitError then show ?case + by(fastforce intro: WTrtThrow[OF WTrtVal] elim!: typeof_NoClassDefFoundError + simp: sconf_def hconf_def) +next + case (InitObjectRed sh C sfs sh' C' Cs e h l b) + then have sh: "sh \\<^sub>s sh(Object \ (sfs, Processing))" by(simp add: shext_def) + have "P,E,h,sh' \ INIT C' (C # Cs,True) \ e : T" + using InitObjectRed WTrt_shext_mono[OF _ sh] by auto + then show ?case by(rule_tac x = T in exI) (simp add: fun_upd_def) +next + case (InitNonObjectSuperRed sh C sfs D fs ms sh' C' Cs e h l b) + then have sh: "sh \\<^sub>s sh(C \ (sfs, Processing))" by(simp add: shext_def) + then have cd: "is_class P D" using InitNonObjectSuperRed class_wf wf wf_cdecl_supD by blast + have sup': "supercls_lst P (C # Cs)" using InitNonObjectSuperRed.prems(3) by auto + then have sup: "supercls_lst P (D # C # Cs)" + using supercls_lst_app[of P C Cs D] subcls1I[OF InitNonObjectSuperRed.hyps(3,2)] by auto + have "distinct (C # Cs)" using InitNonObjectSuperRed.prems(3) by auto + then have dist: "distinct (D # C # Cs)" + using wf_supercls_distinct_app[OF wf InitNonObjectSuperRed.hyps(2-3) sup'] by simp + have "P,E,h,sh' \ INIT C' (D # C # Cs,False) \ e : T" + using InitNonObjectSuperRed WTrt_shext_mono[OF _ sh] cd sup dist by auto + then show ?case by(rule_tac x = T in exI) simp +next + case (RedInitRInit C' C Cs e' h l sh b E T) + then obtain a sfs where C: "class P C = \a\" and proc: "sh C = \(sfs, Processing)\" + using WTrtInit by(auto simp: is_class_def) + then have T': "P,E,h,sh \ C\\<^sub>sclinit([]) : Void" using wf_types_clinit[OF wf C] by simp + have "P,E,h,sh \ RI (C,C\\<^sub>sclinit([])) ; Cs \ e' : T" + using RedInitRInit by(auto intro: T') + then show ?case by(rule_tac x = T in exI) simp +next + case (RInitRed e h l sh b e' h' l' sh' b' C Cs e\<^sub>0 E T) + then have "(\E T. P,E \ (h, l, sh) \ \ P,E,h,sh \ e : T \ \T'. P,E,h',sh' \ e' : T' \ P \ T' \ T)" + by auto + then have "\T'. P,E,h',sh' \ e' : T'" using RInitRed by blast + then obtain T' where e': "P,E,h',sh' \ e' : T'" by auto + have wt\<^sub>0: "P,E,h',sh' \ e\<^sub>0 : T" + using RInitRed by simp (auto intro: WTrt_hext_shext_mono[OF _ red_hext_incr red_shext_incr]) + have nip: "\C' \ set (C#Cs). not_init C' e' \ (\sfs. sh' C' = \(sfs, Processing)\)" + using RInitRed red_proc_pres[OF wf_prog_wwf_prog[OF wf]] by auto + have shC: "\sfs. sh' C = \(sfs, Processing)\ \ sh' C = \(sfs, Error)\ \ e' = THROW NoClassDefFoundError" + using RInitRed red_proc_pres[OF wf_prog_wwf_prog[OF wf] RInitRed.hyps(1)] by blast + have "P,E,h',sh' \ RI (C,e') ; Cs \ e\<^sub>0 : T" using RInitRed e' wt\<^sub>0 nip shC by auto + then show ?case by(rule_tac x = T in exI) simp +next + case (RedRInit sh C sfs i sh' C' Cs v e h l b) + then have sh: "sh \\<^sub>s sh(C \ (sfs, Done))" by(auto simp: shext_def) + have wt: "P,E,h,sh(C \ (sfs, Done)) \ e : T" + using RedRInit WTrt_shext_mono[OF _ sh] by auto + have shC: "\C' \ set(tl Cs). \sfs. sh C' = \(sfs, Processing)\" using RedRInit by(cases Cs, auto) + have "P,E,h,sh' \ INIT C' (Cs,True) \ e : T" using RedRInit wt shC by(cases Cs, auto) + then show ?case by(rule_tac x = T in exI) simp +next + case (SCallThrowParams es vs e es' C M h l sh b) + then show ?case using map_Val_nthrow_neq[of _ vs e es'] by fastforce +next + case (RInitInitThrow sh C sfs i sh' a D Cs e h l b) + then have sh: "sh \\<^sub>s sh(C \ (sfs, Error))" by(auto simp: shext_def) + have wt: "P,E,h,sh(C \ (sfs, Error)) \ e : T" + using RInitInitThrow WTrt_shext_mono[OF _ sh] by clarsimp + then have "P,E,h,sh' \ RI (D,Throw a) ; Cs \ e : T" using RInitInitThrow by auto + then show ?case by(rule_tac x = T in exI) simp +qed fastforce+ (* esp all Throw propagation rules except RInitInit are dealt with here *) +(*>*) + + +corollary subject_reduction: + "\ wf_J_prog P; P \ \e,s,b\ \ \e',s',b'\; P,E \ s \; iconf (shp s) e; P,E,hp s,shp s \ e:T \ + \ \T'. P,E,hp s',shp s' \ e':T' \ P \ T' \ T" +(*<*)by(cases s, cases s', fastforce dest:subject_reduction2)(*>*) + +corollary subjects_reduction: + "\ wf_J_prog P; P \ \es,s,b\ [\] \es',s',b'\; P,E \ s \; iconfs (shp s) es; P,E,hp s,shp s \ es[:]Ts \ + \ \Ts'. P,E,hp s',shp s' \ es'[:]Ts' \ P \ Ts' [\] Ts" +(*<*)by(cases s, cases s', fastforce dest:subjects_reduction2)(*>*) + + +subsection \ Lifting to @{text"\*"} \ + +text\ Now all these preservation lemmas are first lifted to the transitive +closure \dots \ + +lemma Red_preserves_sconf: +assumes wf: "wf_J_prog P" and Red: "P \ \e,s,b\ \* \e',s',b'\" +shows "\T. \ P,E,hp s,shp s \ e : T; iconf (shp s) e; P,E \ s \ \ \ P,E \ s' \" +(*<*) +using Red +proof (induct rule:converse_rtrancl_induct3) + case refl show ?case by fact +next + case (step e s b e' s' b') + obtain h l sh h' l' sh' where s:"s = (h,l,sh)" and s':"s' = (h',l',sh')" + by(cases s, cases s') + then have "P \ \e,(h,l,sh),b\ \ \e',(h',l',sh'),b'\" using step.hyps(1) by simp + then have iconf': "iconf (shp s') e'" using red_preserves_iconf[OF wf_prog_wwf_prog[OF wf]] + step.prems(2) s s' by simp + thus ?case using step + by(blast intro:red_preserves_sconf dest: subject_reduction[OF wf]) +qed +(*>*) + +lemma Red_preserves_iconf: +assumes wf: "wwf_J_prog P" and Red: "P \ \e,s,b\ \* \e',s',b'\" +shows "iconf (shp s) e \ iconf (shp s') e'" +(*<*) +using Red +proof (induct rule:converse_rtrancl_induct3) + case refl show ?case by fact +next + case (step e s b e' s' b') + thus ?case using wf step by(cases s, cases s', simp) (blast intro:red_preserves_iconf) +qed +(*>*) + +lemma Reds_preserves_iconf: +assumes wf: "wwf_J_prog P" and Red: "P \ \es,s,b\ [\]* \es',s',b'\" +shows "iconfs (shp s) es \ iconfs (shp s') es'" +(*<*) +using Red +proof (induct rule:converse_rtrancl_induct3) + case refl show ?case by fact +next + case (step e s b e' s' b') + thus ?case using wf step by(cases s, cases s', simp) (blast intro:reds_preserves_iconf) +qed +(*>*) + +lemma Red_preserves_bconf: +assumes wf: "wwf_J_prog P" and Red: "P \ \e,s,b\ \* \e',s',b'\" +shows "iconf (shp s) e \ P,(shp s) \\<^sub>b (e,b) \ \ P,(shp s') \\<^sub>b (e'::expr,b') \" +(*<*) +using Red +proof (induct rule:converse_rtrancl_induct3) + case refl show ?case by fact +next + case (step e s1 b e' s2 b') + then have "iconf (shp s2) e'" using step red_preserves_iconf[OF wf] + by(cases s1, cases s2) auto + thus ?case using step by(cases s1, cases s2, simp) (blast intro:red_preserves_bconf) +qed +(*>*) + +lemma Reds_preserves_bconf: +assumes wf: "wwf_J_prog P" and Red: "P \ \es,s,b\ [\]* \es',s',b'\" +shows "iconfs (shp s) es \ P,(shp s) \\<^sub>b (es,b) \ \ P,(shp s') \\<^sub>b (es'::expr list,b') \" +(*<*) +using Red +proof (induct rule:converse_rtrancl_induct3) + case refl show ?case by fact +next + case (step es s1 b es' s2 b') + then have "iconfs (shp s2) es'" using step reds_preserves_iconf[OF wf] + by(cases s1, cases s2) auto + thus ?case using step by(cases s1, cases s2, simp) (blast intro:reds_preserves_bconf) +qed +(*>*) + +lemma Red_preserves_defass: +assumes wf: "wf_J_prog P" and reds: "P \ \e,s,b\ \* \e',s',b'\" +shows "\ e \dom(lcl s)\ \ \ e' \dom(lcl s')\" +using reds +proof (induct rule:converse_rtrancl_induct3) + case refl thus ?case . +next + case (step e s b e' s' b') thus ?case + by(cases s,cases s')(auto dest:red_preserves_defass[OF wf]) +qed + + +lemma Red_preserves_type: +assumes wf: "wf_J_prog P" and Red: "P \ \e,s,b\ \* \e',s',b'\" +shows "!!T. \ P,E \ s\; iconf (shp s) e; P,E,hp s,shp s \ e:T \ + \ \T'. P \ T' \ T \ P,E,hp s',shp s' \ e':T'" +(*<*) +using Red +proof (induct rule:converse_rtrancl_induct3) + case refl thus ?case by blast +next + case step thus ?case + by(blast intro:widen_trans red_preserves_sconf Red_preserves_iconf[OF wf_prog_wwf_prog[OF wf]] + dest:subject_reduction[OF wf]) +qed +(*>*) + + +subsection "The final polish" + +text\ The above preservation lemmas are now combined and packed nicely. \ + +definition wf_config :: "J_prog \ env \ state \ expr \ ty \ bool" ("_,_,_ \ _ : _ \" [51,0,0,0,0]50) +where + "P,E,s \ e:T \ \ P,E \ s \ \ iconf (shp s) e \ P,E,hp s,shp s \ e:T" + +theorem Subject_reduction: assumes wf: "wf_J_prog P" +shows "P \ \e,s,b\ \ \e',s',b'\ \ P,E,s \ e : T \ + \ \T'. P,E,s' \ e' : T' \ \ P \ T' \ T" +(*<*) +by(cases s, cases s') + (force simp: wf_config_def + elim:red_preserves_sconf red_preserves_iconf[OF wf_prog_wwf_prog[OF wf]] + dest:subject_reduction[OF wf]) +(*>*) + + +theorem Subject_reductions: +assumes wf: "wf_J_prog P" and reds: "P \ \e,s,b\ \* \e',s',b'\" +shows "\T. P,E,s \ e:T \ \ \T'. P,E,s' \ e':T' \ \ P \ T' \ T" +(*<*) +using reds +proof (induct rule:converse_rtrancl_induct3) + case refl thus ?case by blast +next + case step thus ?case + by(blast dest:Subject_reduction[OF wf] intro:widen_trans) +qed +(*>*) + + +corollary Progress: assumes wf: "wf_J_prog P" +shows "\ P,E,s \ e : T \; \ e \dom(lcl s)\; P,shp s \\<^sub>b (e,b) \; \ final e \ + \ \e' s' b'. P \ \e,s,b\ \ \e',s',b'\" +(*<*) +using progress[OF wf_prog_wwf_prog[OF wf]] +by(cases b) (auto simp:wf_config_def sconf_def) +(*>*) + +corollary TypeSafety: + "\ wf_J_prog P; P,E \ s \; P,E \ e::T; \ e \dom(lcl s)\; + iconf (shp s) e; P,(shp s) \\<^sub>b (e,b) \; + P \ \e,s,b\ \* \e',s',b'\; \(\e'' s'' b''. P \ \e',s',b'\ \ \e'',s'',b''\) \ + \ (\v. e' = Val v \ P,hp s' \ v :\ T) \ + (\a. e' = Throw a \ a \ dom(hp s'))" +(*<*) +apply(subgoal_tac "wwf_J_prog P") + prefer 2 apply(rule wf_prog_wwf_prog, simp) +apply(subgoal_tac " P,E,s \ e:T \") + prefer 2 + apply(fastforce simp:wf_config_def dest:WT_implies_WTrt) +apply(frule (2) Subject_reductions) +apply(erule exE conjE)+ +apply(frule (2) Red_preserves_defass) +apply(frule (3) Red_preserves_bconf) +apply(subgoal_tac "final e'") + prefer 2 + apply(blast dest: Progress) +apply (fastforce simp:wf_config_def final_def conf_def dest: Progress) +done +(*>*) + + +end diff --git a/thys/JinjaDCI/J/WWellForm.thy b/thys/JinjaDCI/J/WWellForm.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/J/WWellForm.thy @@ -0,0 +1,42 @@ +(* Title: JinjaDCI/J/WWellForm.thy + + Author: Tobias Nipkow, Susannah Mansky + Copyright 2003 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory J/WWellForm.thy by Tobias Nipkow +*) + +section \ Weak well-formedness of Jinja programs \ + +theory WWellForm imports "../Common/WellForm" Expr begin + +definition wwf_J_mdecl :: "J_prog \ cname \ J_mb mdecl \ bool" +where + "wwf_J_mdecl P C \ \(M,b,Ts,T,(pns,body)). + length Ts = length pns \ distinct pns \ \sub_RI body \ + (case b of + NonStatic \ this \ set pns \ fv body \ {this} \ set pns + | Static \ fv body \ set pns)" + +lemma wwf_J_mdecl_NonStatic[simp]: + "wwf_J_mdecl P C (M,NonStatic,Ts,T,pns,body) = + (length Ts = length pns \ distinct pns \ \sub_RI body \ this \ set pns \ fv body \ {this} \ set pns)" +(*<*)by(simp add:wwf_J_mdecl_def)(*>*) + +lemma wwf_J_mdecl_Static[simp]: + "wwf_J_mdecl P C (M,Static,Ts,T,pns,body) = + (length Ts = length pns \ distinct pns \ \sub_RI body \ fv body \ set pns)" +(*<*)by(simp add:wwf_J_mdecl_def)(*>*) + +abbreviation + wwf_J_prog :: "J_prog \ bool" where + "wwf_J_prog \ wf_prog wwf_J_mdecl" + + +lemma sees_wwf_nsub_RI: + "\ wwf_J_prog P; P \ C sees M,b : Ts\T = (pns, body) in D \ \ \sub_RI body" +apply(drule sees_wf_mdecl, simp) +apply(unfold wwf_J_mdecl_def wf_mdecl_def, simp) +done + +end diff --git a/thys/JinjaDCI/J/WellType.thy b/thys/JinjaDCI/J/WellType.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/J/WellType.thy @@ -0,0 +1,255 @@ +(* Title: JinjaDCI/J/WellType.thy + + Author: Tobias Nipkow, Susannah Mansky + Copyright 2003 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory J/WellType.thy by Tobias Nipkow +*) + +section \ Well-typedness of Jinja expressions \ + +theory WellType +imports "../Common/Objects" Expr +begin + +type_synonym + env = "vname \ ty" + +inductive + WT :: "[J_prog,env, expr , ty ] \ bool" + ("_,_ \ _ :: _" [51,51,51]50) + and WTs :: "[J_prog,env, expr list, ty list] \ bool" + ("_,_ \ _ [::] _" [51,51,51]50) + for P :: J_prog +where + + WTNew: + "is_class P C \ + P,E \ new C :: Class C" + +| WTCast: + "\ P,E \ e :: Class D; is_class P C; P \ C \\<^sup>* D \ P \ D \\<^sup>* C \ + \ P,E \ Cast C e :: Class C" + +| WTVal: + "typeof v = Some T \ + P,E \ Val v :: T" + +| WTVar: + "E V = Some T \ + P,E \ Var V :: T" + +| WTBinOpEq: + "\ P,E \ e\<^sub>1 :: T\<^sub>1; P,E \ e\<^sub>2 :: T\<^sub>2; P \ T\<^sub>1 \ T\<^sub>2 \ P \ T\<^sub>2 \ T\<^sub>1 \ + \ P,E \ e\<^sub>1 \Eq\ e\<^sub>2 :: Boolean" + +| WTBinOpAdd: + "\ P,E \ e\<^sub>1 :: Integer; P,E \ e\<^sub>2 :: Integer \ + \ P,E \ e\<^sub>1 \Add\ e\<^sub>2 :: Integer" + +| WTLAss: + "\ E V = Some T; P,E \ e :: T'; P \ T' \ T; V \ this \ + \ P,E \ V:=e :: Void" + +| WTFAcc: + "\ P,E \ e :: Class C; P \ C sees F,NonStatic:T in D \ + \ P,E \ e\F{D} :: T" + +| WTSFAcc: + "\ P \ C sees F,Static:T in D \ + \ P,E \ C\\<^sub>sF{D} :: T" + +| WTFAss: + "\ P,E \ e\<^sub>1 :: Class C; P \ C sees F,NonStatic:T in D; P,E \ e\<^sub>2 :: T'; P \ T' \ T \ + \ P,E \ e\<^sub>1\F{D}:=e\<^sub>2 :: Void" + +| WTSFAss: + "\ P \ C sees F,Static:T in D; P,E \ e\<^sub>2 :: T'; P \ T' \ T \ + \ P,E \ C\\<^sub>sF{D}:=e\<^sub>2 :: Void" + +| WTCall: + "\ P,E \ e :: Class C; P \ C sees M,NonStatic:Ts \ T = (pns,body) in D; + P,E \ es [::] Ts'; P \ Ts' [\] Ts \ + \ P,E \ e\M(es) :: T" + +| WTSCall: + "\ P \ C sees M,Static:Ts \ T = (pns,body) in D; + P,E \ es [::] Ts'; P \ Ts' [\] Ts; M \ clinit \ + \ P,E \ C\\<^sub>sM(es) :: T" + +| WTBlock: + "\ is_type P T; P,E(V \ T) \ e :: T' \ + \ P,E \ {V:T; e} :: T'" + +| WTSeq: + "\ P,E \ e\<^sub>1::T\<^sub>1; P,E \ e\<^sub>2::T\<^sub>2 \ + \ P,E \ e\<^sub>1;;e\<^sub>2 :: T\<^sub>2" + +| WTCond: + "\ P,E \ e :: Boolean; P,E \ e\<^sub>1::T\<^sub>1; P,E \ e\<^sub>2::T\<^sub>2; + P \ T\<^sub>1 \ T\<^sub>2 \ P \ T\<^sub>2 \ T\<^sub>1; P \ T\<^sub>1 \ T\<^sub>2 \ T = T\<^sub>2; P \ T\<^sub>2 \ T\<^sub>1 \ T = T\<^sub>1 \ + \ P,E \ if (e) e\<^sub>1 else e\<^sub>2 :: T" + +| WTWhile: + "\ P,E \ e :: Boolean; P,E \ c::T \ + \ P,E \ while (e) c :: Void" + +| WTThrow: + "P,E \ e :: Class C \ + P,E \ throw e :: Void" + +| WTTry: + "\ P,E \ e\<^sub>1 :: T; P,E(V \ Class C) \ e\<^sub>2 :: T; is_class P C \ + \ P,E \ try e\<^sub>1 catch(C V) e\<^sub>2 :: T" + +\ \well-typed expression lists\ + +| WTNil: + "P,E \ [] [::] []" + +| WTCons: + "\ P,E \ e :: T; P,E \ es [::] Ts \ + \ P,E \ e#es [::] T#Ts" + +(*<*) +declare WT_WTs.intros[intro!] (* WTNil[iff] *) + +lemmas WT_WTs_induct = WT_WTs.induct [split_format (complete)] + and WT_WTs_inducts = WT_WTs.inducts [split_format (complete)] +(*>*) + +lemma init_nwt [simp]:"\P,E \ INIT C (Cs,b) \ e :: T" + by(auto elim:WT.cases) +lemma ri_nwt [simp]:"\P,E \ RI(C,e);Cs \ e' :: T" + by(auto elim:WT.cases) + +lemma [iff]: "(P,E \ [] [::] Ts) = (Ts = [])" +(*<*) +apply(rule iffI) +apply (auto elim: WTs.cases) +done +(*>*) + +lemma [iff]: "(P,E \ e#es [::] T#Ts) = (P,E \ e :: T \ P,E \ es [::] Ts)" +(*<*) +apply(rule iffI) +apply (auto elim: WTs.cases) +done +(*>*) + +lemma [iff]: "(P,E \ (e#es) [::] Ts) = + (\U Us. Ts = U#Us \ P,E \ e :: U \ P,E \ es [::] Us)" +(*<*) +apply(rule iffI) +apply (auto elim: WTs.cases) +done +(*>*) + +lemma [iff]: "\Ts. (P,E \ es\<^sub>1 @ es\<^sub>2 [::] Ts) = + (\Ts\<^sub>1 Ts\<^sub>2. Ts = Ts\<^sub>1 @ Ts\<^sub>2 \ P,E \ es\<^sub>1 [::] Ts\<^sub>1 \ P,E \ es\<^sub>2[::]Ts\<^sub>2)" +(*<*) +apply(induct es\<^sub>1 type:list) + apply simp +apply clarsimp +apply(erule thin_rl) +apply (rule iffI) + apply clarsimp + apply(rule exI)+ + apply(rule conjI) + prefer 2 apply blast + apply simp +apply fastforce +done +(*>*) + +lemma [iff]: "P,E \ Val v :: T = (typeof v = Some T)" +(*<*) +apply(rule iffI) +apply (auto elim: WT.cases) +done +(*>*) + +lemma [iff]: "P,E \ Var V :: T = (E V = Some T)" +(*<*) +apply(rule iffI) +apply (auto elim: WT.cases) +done +(*>*) + +lemma [iff]: "P,E \ e\<^sub>1;;e\<^sub>2 :: T\<^sub>2 = (\T\<^sub>1. P,E \ e\<^sub>1::T\<^sub>1 \ P,E \ e\<^sub>2::T\<^sub>2)" +(*<*) +apply(rule iffI) +apply (auto elim: WT.cases) +done +(*>*) + +lemma [iff]: "(P,E \ {V:T; e} :: T') = (is_type P T \ P,E(V\T) \ e :: T')" +(*<*) +apply(rule iffI) +apply (auto elim: WT.cases) +done +(*>*) + +(*<*) +inductive_cases WT_elim_cases[elim!]: + "P,E \ V :=e :: T" + "P,E \ if (e) e\<^sub>1 else e\<^sub>2 :: T" + "P,E \ while (e) c :: T" + "P,E \ throw e :: T" + "P,E \ try e\<^sub>1 catch(C V) e\<^sub>2 :: T" + "P,E \ Cast D e :: T" + "P,E \ a\F{D} :: T" + "P,E \ C\\<^sub>sF{D} :: T" + "P,E \ a\F{D} := v :: T" + "P,E \ C\\<^sub>sF{D} := v :: T" + "P,E \ e\<^sub>1 \bop\ e\<^sub>2 :: T" + "P,E \ new C :: T" + "P,E \ e\M(ps) :: T" + "P,E \ C\\<^sub>sM(ps) :: T" +(*>*) + + +lemma wt_env_mono: + "P,E \ e :: T \ (\E'. E \\<^sub>m E' \ P,E' \ e :: T)" and + "P,E \ es [::] Ts \ (\E'. E \\<^sub>m E' \ P,E' \ es [::] Ts)" +(*<*) +apply(induct rule: WT_WTs_inducts) +apply(simp add: WTNew) +apply(fastforce simp: WTCast) +apply(fastforce simp: WTVal) +apply(simp add: WTVar map_le_def dom_def) +apply(fastforce simp: WTBinOpEq) +apply(fastforce simp: WTBinOpAdd) +apply(force simp:map_le_def) +apply(fastforce simp: WTFAcc) +apply(fastforce) +apply(fastforce simp: WTFAss del:WT_WTs.intros WT_elim_cases) +apply(fastforce) +apply(fastforce simp: WTCall) +apply(fastforce) +apply(fastforce simp: map_le_def WTBlock) +apply(fastforce simp: WTSeq) +apply(fastforce simp: WTCond) +apply(fastforce simp: WTWhile) +apply(fastforce simp: WTThrow) +apply(fastforce simp: WTTry map_le_def dom_def) +apply(simp add: WTNil) +apply(simp add: WTCons) +done +(*>*) + + +lemma WT_fv: "P,E \ e :: T \ fv e \ dom E" +and "P,E \ es [::] Ts \ fvs es \ dom E" +(*<*) +apply(induct rule:WT_WTs.inducts) +apply(simp_all del: fun_upd_apply) +apply fast+ +done + +lemma WT_nsub_RI: "P,E \ e :: T \ \sub_RI e" + and WTs_nsub_RIs: "P,E \ es [::] Ts \ \sub_RIs es" +proof(induct rule: WT_WTs.inducts) qed(simp_all) + +end +(*>*) diff --git a/thys/JinjaDCI/J/WellTypeRT.thy b/thys/JinjaDCI/J/WellTypeRT.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/J/WellTypeRT.thy @@ -0,0 +1,353 @@ +(* Title: JinjaDCI/J/WellTypeRT.thy + + Author: Tobias Nipkow, Susannah Mansky + Copyright 2003 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory J/WellTypeRT.thy by Tobias Nipkow +*) + +section \ Runtime Well-typedness \ + +theory WellTypeRT +imports WellType +begin + +inductive + WTrt :: "J_prog \ heap \ sheap \ env \ expr \ ty \ bool" + and WTrts :: "J_prog \ heap \ sheap \ env \ expr list \ ty list \ bool" + and WTrt2 :: "[J_prog,env,heap,sheap,expr,ty] \ bool" + ("_,_,_,_ \ _ : _" [51,51,51,51]50) + and WTrts2 :: "[J_prog,env,heap,sheap,expr list, ty list] \ bool" + ("_,_,_,_ \ _ [:] _" [51,51,51,51]50) + for P :: J_prog and h :: heap and sh :: sheap +where + + "P,E,h,sh \ e : T \ WTrt P h sh E e T" +| "P,E,h,sh \ es[:]Ts \ WTrts P h sh E es Ts" + +| WTrtNew: + "is_class P C \ + P,E,h,sh \ new C : Class C" + +| WTrtCast: + "\ P,E,h,sh \ e : T; is_refT T; is_class P C \ + \ P,E,h,sh \ Cast C e : Class C" + +| WTrtVal: + "typeof\<^bsub>h\<^esub> v = Some T \ + P,E,h,sh \ Val v : T" + +| WTrtVar: + "E V = Some T \ + P,E,h,sh \ Var V : T" + +| WTrtBinOpEq: + "\ P,E,h,sh \ e\<^sub>1 : T\<^sub>1; P,E,h,sh \ e\<^sub>2 : T\<^sub>2 \ + \ P,E,h,sh \ e\<^sub>1 \Eq\ e\<^sub>2 : Boolean" + +| WTrtBinOpAdd: + "\ P,E,h,sh \ e\<^sub>1 : Integer; P,E,h,sh \ e\<^sub>2 : Integer \ + \ P,E,h,sh \ e\<^sub>1 \Add\ e\<^sub>2 : Integer" + +| WTrtLAss: + "\ E V = Some T; P,E,h,sh \ e : T'; P \ T' \ T \ + \ P,E,h,sh \ V:=e : Void" + +| WTrtFAcc: + "\ P,E,h,sh \ e : Class C; P \ C has F,NonStatic:T in D \ \ + P,E,h,sh \ e\F{D} : T" + +| WTrtFAccNT: + "P,E,h,sh \ e : NT \ + P,E,h,sh \ e\F{D} : T" + +| WTrtSFAcc: + "\ P \ C has F,Static:T in D \ \ + P,E,h,sh \ C\\<^sub>sF{D} : T" + +| WTrtFAss: + "\ P,E,h,sh \ e\<^sub>1 : Class C; P \ C has F,NonStatic:T in D; P,E,h,sh \ e\<^sub>2 : T\<^sub>2; P \ T\<^sub>2 \ T \ + \ P,E,h,sh \ e\<^sub>1\F{D}:=e\<^sub>2 : Void" + +| WTrtFAssNT: + "\ P,E,h,sh \ e\<^sub>1:NT; P,E,h,sh \ e\<^sub>2 : T\<^sub>2 \ + \ P,E,h,sh \ e\<^sub>1\F{D}:=e\<^sub>2 : Void" + +| WTrtSFAss: + "\ P,E,h,sh \ e\<^sub>2 : T\<^sub>2; P \ C has F,Static:T in D; P \ T\<^sub>2 \ T \ + \ P,E,h,sh \ C\\<^sub>sF{D}:=e\<^sub>2 : Void" + +| WTrtCall: + "\ P,E,h,sh \ e : Class C; P \ C sees M,NonStatic:Ts \ T = (pns,body) in D; + P,E,h,sh \ es [:] Ts'; P \ Ts' [\] Ts \ + \ P,E,h,sh \ e\M(es) : T" + +| WTrtCallNT: + "\ P,E,h,sh \ e : NT; P,E,h,sh \ es [:] Ts \ + \ P,E,h,sh \ e\M(es) : T" + +| WTrtSCall: + "\ P \ C sees M,Static:Ts \ T = (pns,body) in D; + P,E,h,sh \ es [:] Ts'; P \ Ts' [\] Ts; + M = clinit \ sh D = \(sfs,Processing)\ \ es = map Val vs \ + \ P,E,h,sh \ C\\<^sub>sM(es) : T" + +| WTrtBlock: + "P,E(V\T),h,sh \ e : T' \ + P,E,h,sh \ {V:T; e} : T'" + +| WTrtSeq: + "\ P,E,h,sh \ e\<^sub>1:T\<^sub>1; P,E,h,sh \ e\<^sub>2:T\<^sub>2 \ + \ P,E,h,sh \ e\<^sub>1;;e\<^sub>2 : T\<^sub>2" + +| WTrtCond: + "\ P,E,h,sh \ e : Boolean; P,E,h,sh \ e\<^sub>1:T\<^sub>1; P,E,h,sh \ e\<^sub>2:T\<^sub>2; + P \ T\<^sub>1 \ T\<^sub>2 \ P \ T\<^sub>2 \ T\<^sub>1; P \ T\<^sub>1 \ T\<^sub>2 \ T = T\<^sub>2; P \ T\<^sub>2 \ T\<^sub>1 \ T = T\<^sub>1 \ + \ P,E,h,sh \ if (e) e\<^sub>1 else e\<^sub>2 : T" + +| WTrtWhile: + "\ P,E,h,sh \ e : Boolean; P,E,h,sh \ c:T \ + \ P,E,h,sh \ while(e) c : Void" + +| WTrtThrow: + "\ P,E,h,sh \ e : T\<^sub>r; is_refT T\<^sub>r \ \ + P,E,h,sh \ throw e : T" + +| WTrtTry: + "\ P,E,h,sh \ e\<^sub>1 : T\<^sub>1; P,E(V \ Class C),h,sh \ e\<^sub>2 : T\<^sub>2; P \ T\<^sub>1 \ T\<^sub>2 \ + \ P,E,h,sh \ try e\<^sub>1 catch(C V) e\<^sub>2 : T\<^sub>2" + +| WTrtInit: + "\ P,E,h,sh \ e : T; \C' \ set (C#Cs). is_class P C'; \sub_RI e; + \C' \ set (tl Cs). \sfs. sh C' = \(sfs,Processing)\; + b \ (\C' \ set Cs. \sfs. sh C' = \(sfs,Processing)\); + distinct Cs; supercls_lst P Cs \ + \ P,E,h,sh \ INIT C (Cs, b) \ e : T" + +| WTrtRI: + "\ P,E,h,sh \ e : T; P,E,h,sh \ e' : T'; \C' \ set (C#Cs). is_class P C'; \sub_RI e'; + \C' \ set (C#Cs). not_init C' e; + \C' \ set Cs. \sfs. sh C' = \(sfs,Processing)\; + \sfs. sh C = \(sfs, Processing)\ \ (sh C = \(sfs, Error)\ \ e = THROW NoClassDefFoundError); + distinct (C#Cs); supercls_lst P (C#Cs) \ + \ P,E,h,sh \ RI(C, e);Cs \ e' : T'" + +\ \well-typed expression lists\ + +| WTrtNil: + "P,E,h,sh \ [] [:] []" + +| WTrtCons: + "\ P,E,h,sh \ e : T; P,E,h,sh \ es [:] Ts \ + \ P,E,h,sh \ e#es [:] T#Ts" + +(*<*) +declare WTrt_WTrts.intros[intro!] WTrtNil[iff] +declare + WTrtFAcc[rule del] WTrtFAccNT[rule del] WTrtSFAcc[rule del] + WTrtFAss[rule del] WTrtFAssNT[rule del] WTrtSFAss[rule del] + WTrtCall[rule del] WTrtCallNT[rule del] WTrtSCall[rule del] + +lemmas WTrt_induct = WTrt_WTrts.induct [split_format (complete)] + and WTrt_inducts = WTrt_WTrts.inducts [split_format (complete)] +(*>*) + + +subsection\Easy consequences\ + +lemma [iff]: "(P,E,h,sh \ [] [:] Ts) = (Ts = [])" +(*<*) +apply(rule iffI) +apply (auto elim: WTrts.cases) +done +(*>*) + +lemma [iff]: "(P,E,h,sh \ e#es [:] T#Ts) = (P,E,h,sh \ e : T \ P,E,h,sh \ es [:] Ts)" +(*<*) +apply(rule iffI) +apply (auto elim: WTrts.cases) +done +(*>*) + +lemma [iff]: "(P,E,h,sh \ (e#es) [:] Ts) = + (\U Us. Ts = U#Us \ P,E,h,sh \ e : U \ P,E,h,sh \ es [:] Us)" +(*<*) +apply(rule iffI) +apply (auto elim: WTrts.cases) +done +(*>*) + +lemma [simp]: "\Ts. (P,E,h,sh \ es\<^sub>1 @ es\<^sub>2 [:] Ts) = + (\Ts\<^sub>1 Ts\<^sub>2. Ts = Ts\<^sub>1 @ Ts\<^sub>2 \ P,E,h,sh \ es\<^sub>1 [:] Ts\<^sub>1 & P,E,h,sh \ es\<^sub>2[:]Ts\<^sub>2)" +(*<*) +apply(induct_tac es\<^sub>1) + apply simp +apply clarsimp +apply(erule thin_rl) +apply (rule iffI) + apply clarsimp + apply(rule exI)+ + apply(rule conjI) + prefer 2 apply blast + apply simp +apply fastforce +done +(*>*) + +lemma [iff]: "P,E,h,sh \ Val v : T = (typeof\<^bsub>h\<^esub> v = Some T)" +(*<*) +apply(rule iffI) +apply (auto elim: WTrt.cases) +done +(*>*) + +lemma [iff]: "P,E,h,sh \ Var v : T = (E v = Some T)" +(*<*) +apply(rule iffI) +apply (auto elim: WTrt.cases) +done +(*>*) + +lemma [iff]: "P,E,h,sh \ e\<^sub>1;;e\<^sub>2 : T\<^sub>2 = (\T\<^sub>1. P,E,h,sh \ e\<^sub>1:T\<^sub>1 \ P,E,h,sh \ e\<^sub>2:T\<^sub>2)" +(*<*) +apply(rule iffI) +apply (auto elim: WTrt.cases) +done +(*>*) + +lemma [iff]: "P,E,h,sh \ {V:T; e} : T' = (P,E(V\T),h,sh \ e : T')" +(*<*) +apply(rule iffI) +apply (auto elim: WTrt.cases) +done +(*>*) +(*<*) +inductive_cases WTrt_elim_cases[elim!]: + "P,E,h,sh \ v :=e : T" + "P,E,h,sh \ if (e) e\<^sub>1 else e\<^sub>2 : T" + "P,E,h,sh \ while(e) c : T" + "P,E,h,sh \ throw e : T" + "P,E,h,sh \ try e\<^sub>1 catch(C V) e\<^sub>2 : T" + "P,E,h,sh \ Cast D e : T" + "P,E,h,sh \ e\F{D} : T" + "P,E,h,sh \ C\\<^sub>sF{D} : T" + "P,E,h,sh \ e\F{D} := v : T" + "P,E,h,sh \ C\\<^sub>sF{D} := v : T" + "P,E,h,sh \ e\<^sub>1 \bop\ e\<^sub>2 : T" + "P,E,h,sh \ new C : T" + "P,E,h,sh \ e\M{D}(es) : T" + "P,E,h,sh \ C\\<^sub>sM{D}(es) : T" + "P,E,h,sh \ INIT C (Cs,b) \ e : T" + "P,E,h,sh \ RI(C,e);Cs \ e' : T" +(*>*) + +subsection\Some interesting lemmas\ + +lemma WTrts_Val[simp]: + "\Ts. (P,E,h,sh \ map Val vs [:] Ts) = (map (typeof\<^bsub>h\<^esub>) vs = map Some Ts)" +(*<*) +apply(induct vs) + apply simp +apply(case_tac Ts) + apply simp +apply simp +done +(*>*) + + +lemma WTrts_same_length: "\Ts. P,E,h,sh \ es [:] Ts \ length es = length Ts" +(*<*)by(induct es type:list)auto(*>*) + + +lemma WTrt_env_mono: + "P,E,h,sh \ e : T \ (\E'. E \\<^sub>m E' \ P,E',h,sh \ e : T)" and + "P,E,h,sh \ es [:] Ts \ (\E'. E \\<^sub>m E' \ P,E',h,sh \ es [:] Ts)" +(*<*) +proof(induct rule: WTrt_inducts) + case (WTrtVar E V T) + then show ?case by(simp add: WTrtVar map_le_def dom_def) +next + case (WTrtLAss E V T e T') + then show ?case by(force simp: map_le_def) +qed(fastforce intro: WTrt_WTrts.intros)+ +(*>*) + + +lemma WTrt_hext_mono: "P,E,h,sh \ e : T \ h \ h' \ P,E,h',sh \ e : T" +and WTrts_hext_mono: "P,E,h,sh \ es [:] Ts \ h \ h' \ P,E,h',sh \ es [:] Ts" +(*<*) +apply(induct rule: WTrt_inducts) +apply(simp add: WTrtNew) +apply(fastforce simp: WTrtCast) +apply(fastforce simp: WTrtVal dest:hext_typeof_mono) +apply(simp add: WTrtVar) +apply(fastforce simp add: WTrtBinOpEq) +apply(fastforce simp add: WTrtBinOpAdd) +apply(fastforce simp add: WTrtLAss) +apply(fast intro: WTrtFAcc) +apply(simp add: WTrtFAccNT) +apply(fast intro: WTrtSFAcc) +apply(fastforce simp: WTrtFAss del:WTrt_WTrts.intros WTrt_elim_cases) +apply(fastforce simp: WTrtFAssNT) +apply(fastforce simp: WTrtSFAss del:WTrt_WTrts.intros WTrt_elim_cases) +apply(fastforce simp: WTrtCall) +apply(fastforce simp: WTrtCallNT) +using WTrtSCall apply blast +apply(fastforce) +apply(fastforce simp add: WTrtSeq) +apply(fastforce simp add: WTrtCond) +apply(fastforce simp add: WTrtWhile) +apply(fastforce simp add: WTrtThrow) +apply(fastforce simp: WTrtTry) +apply(simp add: WTrtInit) +apply(simp add: WTrtRI) +apply(simp add: WTrtNil) +apply(simp add: WTrtCons) +done +(*>*) + +lemma WTrt_shext_mono: "P,E,h,sh \ e : T \ sh \\<^sub>s sh' \ \sub_RI e \ P,E,h,sh' \ e : T" +and WTrts_shext_mono: "P,E,h,sh \ es [:] Ts \ sh \\<^sub>s sh' \ \sub_RIs es \ P,E,h,sh' \ es [:] Ts" +(*<*) +by(induct rule: WTrt_inducts) + (auto simp add: WTrt_WTrts.intros) +(*>*) + +lemma WTrt_hext_shext_mono: "P,E,h,sh \ e : T + \ h \ h' \ sh \\<^sub>s sh' \ \sub_RI e \ P,E,h',sh' \ e : T" + by(auto intro: WTrt_hext_mono WTrt_shext_mono) + +lemma WTrts_hext_shext_mono: "P,E,h,sh \ es [:] Ts + \ h \ h' \ sh \\<^sub>s sh' \ \sub_RIs es \ P,E,h',sh' \ es [:] Ts" + by(auto intro: WTrts_hext_mono WTrts_shext_mono) + + +lemma WT_implies_WTrt: "P,E \ e :: T \ P,E,h,sh \ e : T" +and WTs_implies_WTrts: "P,E \ es [::] Ts \ P,E,h,sh \ es [:] Ts" +(*<*) +apply(induct rule: WT_WTs_inducts) +apply fast +apply (fast) +apply(fastforce dest:typeof_lit_typeof) +apply(simp) +apply(fastforce) +apply(fastforce) +apply(fastforce) +apply(meson WTrtFAcc has_visible_field) +apply(meson WTrtSFAcc has_visible_field) +apply(meson WTrtFAss has_visible_field) +apply(meson WTrtSFAss has_visible_field) +apply(fastforce simp: WTrtCall) +apply(fastforce simp: WTrtSCall) +apply(fastforce) +apply(fastforce) +apply(fastforce simp: WTrtCond) +apply(fastforce) +apply(fastforce) +apply(fastforce) +apply(simp) +apply(simp) +done +(*>*) + +end diff --git a/thys/JinjaDCI/J/execute_Bigstep.thy b/thys/JinjaDCI/J/execute_Bigstep.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/J/execute_Bigstep.thy @@ -0,0 +1,557 @@ +(* Title: Jinja/J/execute_Bigstep.thy + Author: Tobias Nipkow + Copyright 2004 Technische Universitaet Muenchen + Expanded to include statics by Susannah Mansky + 2017, UIUC +*) + +section \ Code Generation For BigStep \ + +theory execute_Bigstep +imports + BigStep Examples + "HOL-Library.Code_Target_Numeral" +begin + +definition not_Done :: "cname \ sheap \ bool" where +"not_Done C sh \ sh C = None \ (\sfs i. sh C = Some(sfs,i) \ i \ Done)" + +lemma not_Done_conv: + "(\sfs. sh C = Some(sfs,Done)) = (not_Done C sh)" +apply(unfold not_Done_def) +apply(case_tac "sh C", simp) apply (rename_tac sfsi) +apply(case_tac sfsi, clarsimp) +done + +(* HERE: MOVE - MethodsAndFields? *) +(* HERE: to be computable, this also needs a def for when has_fields DNE: + such a thing exists in counter-form in MaF, but uses subcls/requires + something to be true of something above C - there are only finite things + above C, but this still might require some work (like proving finiteness *) +definition no_field :: "J_prog \ cname \ vname \ cname \ bool" where +"no_field P C F D \ (\FDTs. \ P \ C has_fields FDTs) \ (\FDTs. P \ C has_fields FDTs \ + ((map_of (map (\((F,D),b,T). (F,(D,b,T))) FDTs) F = None) \ + (\D' b T. D \ D' \ map_of (map (\((F,D),b,T). (F,(D,b,T))) FDTs) F = Some(D',b,T))))" + +lemma no_field_conv: + "(\(\b t. P \ C sees F,b:t in D)) = no_field P C F D" +apply(unfold no_field_def sees_field_def) +apply(case_tac "\FDTs. P \ C has_fields FDTs") + defer apply simp +apply(rule iffI) + apply clarsimp + apply(erule_tac x=FDTs in allE, clarsimp) apply(rename_tac D' b' t') + apply(erule disjE, simp) + apply fastforce +apply clarsimp +apply(erule disjE,simp) +apply clarsimp +apply((drule (1) has_fields_fun)+, simp) +done + +inductive map_val :: "expr list \ val list \ bool" +where + Nil: "map_val [] []" +| Cons: "map_val xs ys \ map_val (Val y # xs) (y # ys)" + +inductive map_val2 :: "expr list \ val list \ expr list \ bool" +where + Nil: "map_val2 [] [] []" +| Cons: "map_val2 xs ys zs \ map_val2 (Val y # xs) (y # ys) zs" +| Throw: "map_val2 (throw e # xs) [] (throw e # xs)" + +theorem map_val_conv: "(xs = map Val ys) = map_val xs ys" +(*<*) +proof - + have "\ys. xs = map Val ys \ map_val xs ys" + apply (induct xs type:list) + apply (case_tac ys) + apply simp + apply (rule map_val.Nil) + apply simp + apply (case_tac ys) + apply simp + apply simp + apply (erule conjE) + apply (rule map_val.Cons) + apply simp + done + moreover have "map_val xs ys \ xs = map Val ys" + by (erule map_val.induct) simp+ + ultimately show ?thesis .. +qed +(*>*) + +theorem map_val2_conv: + "(xs = map Val ys @ throw e # zs) = map_val2 xs ys (throw e # zs)" +(*<*) +proof - + have "\ys. xs = map Val ys @ throw e # zs \ map_val2 xs ys (throw e # zs)" + apply (induct xs type:list) + apply (case_tac ys) + apply simp + apply simp + apply simp + apply (case_tac ys) + apply simp + apply (rule map_val2.Throw) + apply simp + apply (rule map_val2.Cons) + apply simp + done + moreover have "map_val2 xs ys (throw e # zs) \ xs = map Val ys @ throw e # zs" + by (erule map_val2.induct) simp+ + ultimately show ?thesis .. +qed +(*>*) + +lemma NewInit2: + "\ not_Done C sh; P \ \C,(h,sh)\ \\<^sub>i \None,(h',sh')\; + new_Addr h' = Some a; h'' = h'(a\blank P C) \ + \ P \ \new C,(h,l,sh)\ \ \addr a,(h'',l,sh')\" +apply(rule NewInit) +apply(simp add: not_Done_conv[symmetric]) +apply(assumption+) +done + +lemma NewInitFail2: + "\ not_Done C sh; P \ \C,(h,sh)\ \\<^sub>i \Some e',(h',sh')\ \ + \ P \ \new C,(h,l,sh)\ \ \e',(h',l,sh')\" +apply(rule NewInitFail) +apply(simp add: not_Done_conv[symmetric]) +apply(assumption+) +done + +lemma NewInitOOM2: + "\ not_Done C sh; P \ \C,(h,sh)\ \\<^sub>i \None,(h',sh')\; + new_Addr h = None \ + \ P \ \new C,(h,l,sh)\ \ \THROW OutOfMemory,(h',l,sh')\" +apply(rule NewInitOOM) +apply(simp add: not_Done_conv[symmetric]) +apply(assumption+) +done + +(*| FAccNone: + "\ P \ \e,s\<^sub>0\ \ \addr a,(h,l,sh)\; h a = Some(C,fs); + \(\b t. P \ C sees F,b:t in D) \ + \ P \ \e\F{D},s\<^sub>0\ \ \THROW NoSuchFieldError,(h,l,sh)\"*) + +lemma SFAccInit2: + "\ P \ C sees F,Static:t in D; + not_Done D sh; P \ \D,(h,sh)\ \\<^sub>i \None,(h',sh')\; + sh' D = Some (sfs',Done); sfs' F = Some v \ + \ P \ \C\\<^sub>sF{D},(h,l,sh)\ \ \Val v,(h',l,sh')\" +apply(rule SFAccInit, assumption+) +apply(simp add: not_Done_conv[symmetric]) +apply(assumption+) +done + +lemma SFAccInitFail2: + "\ P \ C sees F,Static:t in D; + not_Done D sh; P \ \D,(h,sh)\ \\<^sub>i \Some e',(h',sh')\ \ + \ P \ \C\\<^sub>sF{D},(h,l,sh)\ \ \e',(h',l,sh')\" +apply(rule SFAccInitFail, assumption+) +apply(simp add: not_Done_conv[symmetric]) +apply(assumption+) +done + +(*| SFAccNone: + "\ \(\b t. P \ C sees F,b:t in D) \ + \ P \ \C\\<^sub>sF{D},s\ \ \THROW NoSuchFieldError,s\" + +| FAssNone: + "\ P \ \e\<^sub>1,s\<^sub>0\ \ \addr a,s\<^sub>1\; P \ \e\<^sub>2,s\<^sub>1\ \ \Val v,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\; + h\<^sub>2 a = Some(C,fs); \(\b t. P \ C sees F,b:t in D) \ + \ P \ \e\<^sub>1\F{D}:=e\<^sub>2,s\<^sub>0\ \ \THROW NoSuchFieldError,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\"*) + +lemma SFAssInit2: + "\ P \ \e\<^sub>2,s\<^sub>0\ \ \Val v,(h\<^sub>1,l\<^sub>1,sh\<^sub>1)\; + P \ C sees F,Static:t in D; + not_Done D sh\<^sub>1; P \ \D,(h\<^sub>1,sh\<^sub>1)\ \\<^sub>i \None,(h\<^sub>2,sh\<^sub>2)\; + sh\<^sub>2 D = Some(sfs\<^sub>2,Done); sfs\<^sub>2' = sfs\<^sub>2(F\v); sh\<^sub>2' = sh\<^sub>2(D\(sfs\<^sub>2',Done)) \ + \ P \ \C\\<^sub>sF{D}:=e\<^sub>2,s\<^sub>0\ \ \Val v,(h\<^sub>2,l\<^sub>1,sh\<^sub>2')\" +apply(rule SFAssInit, assumption+) +apply(simp add: not_Done_conv[symmetric]) +apply(assumption+) +done + +lemma SFAssInitFail2: + "\ P \ \e\<^sub>2,s\<^sub>0\ \ \Val v,(h\<^sub>1,l\<^sub>1,sh\<^sub>1)\; + P \ C sees F,Static:t in D; + not_Done D sh\<^sub>1; P \ \D,(h\<^sub>1,sh\<^sub>1)\ \\<^sub>i \Some e',(h\<^sub>2,sh\<^sub>2)\ \ + \ P \ \C\\<^sub>sF{D}:=e\<^sub>2,s\<^sub>0\ \ \e',(h\<^sub>2,l\<^sub>1,sh\<^sub>2)\" +apply(rule SFAssInitFail, assumption+) +apply(simp add: not_Done_conv[symmetric]) +apply(assumption+) +done + +(*| SFAssNone: + "\ P \ \e\<^sub>2,s\<^sub>0\ \ \Val v,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\; + \(\b t. P \ C sees F,b:t in D) \ + \ P \ \C\\<^sub>sF{D}:=e\<^sub>2,s\<^sub>0\ \ \THROW NoSuchFieldError,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\"*) + +lemma CallNull2: + "\ P \ \e,s\<^sub>0\ \ \null,s\<^sub>1\; P \ \ps,s\<^sub>1\ [\] \evs,s\<^sub>2\; map_val evs vs \ + \ P \ \e\M(ps),s\<^sub>0\ \ \THROW NullPointer,s\<^sub>2\" +apply(rule CallNull, assumption+) +apply(simp add: map_val_conv[symmetric]) +done + +lemma CallNone2: + "\ P \ \e,s\<^sub>0\ \ \addr a,s\<^sub>1\; P \ \ps,s\<^sub>1\ [\] \evs,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\; map_val evs vs; + h\<^sub>2 a = Some(C,fs); \(\b Ts T m D. P \ C sees M,b:Ts\T = m in D) \ + \ P \ \e\M(ps),s\<^sub>0\ \ \THROW NoSuchMethodError,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\" +apply(rule CallNone, assumption+) +apply(simp add: map_val_conv[symmetric]) +apply(assumption+) +done + +lemma CallStatic2: + "\ P \ \e,s\<^sub>0\ \ \addr a,s\<^sub>1\; P \ \ps,s\<^sub>1\ [\] \evs,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\; map_val evs vs; + h\<^sub>2 a = Some(C,fs); P \ C sees M,Static:Ts\T = m in D \ + \ P \ \e\M(ps),s\<^sub>0\ \ \THROW IncompatibleClassChangeError,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\" +apply(rule CallStatic, assumption+) +apply(simp add: map_val_conv[symmetric]) +apply(assumption+) +done + +lemma CallParamsThrow2: + "\ P \ \e,s\<^sub>0\ \ \Val v,s\<^sub>1\; P \ \es,s\<^sub>1\ [\] \evs,s\<^sub>2\; + map_val2 evs vs (throw ex # es'') \ + \ P \ \e\M(es),s\<^sub>0\ \ \throw ex,s\<^sub>2\" +apply(rule eval_evals_init_rinit.CallParamsThrow, assumption+) +apply(simp add: map_val2_conv[symmetric]) +done + +lemma Call2: + "\ P \ \e,s\<^sub>0\ \ \addr a,s\<^sub>1\; P \ \ps,s\<^sub>1\ [\] \evs,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\; + map_val evs vs; + h\<^sub>2 a = Some(C,fs); P \ C sees M,NonStatic:Ts\T = (pns,body) in D; + length vs = length pns; l\<^sub>2' = [this\Addr a, pns[\]vs]; + P \ \body,(h\<^sub>2,l\<^sub>2',sh\<^sub>2)\ \ \e',(h\<^sub>3,l\<^sub>3,sh\<^sub>3)\ \ + \ P \ \e\M(ps),s\<^sub>0\ \ \e',(h\<^sub>3,l\<^sub>2,sh\<^sub>3)\" +apply(rule Call, assumption+) +apply(simp add: map_val_conv[symmetric]) +apply assumption+ +done + +lemma SCallParamsThrow2: + "\ P \ \es,s\<^sub>0\ [\] \evs,s\<^sub>2\; + map_val2 evs vs (throw ex # es'') \ + \ P \ \C\\<^sub>sM(es),s\<^sub>0\ \ \throw ex,s\<^sub>2\" +apply(rule SCallParamsThrow) +apply(simp add: map_val2_conv[symmetric]) +done + +lemma SCallNone2: + "\ P \ \ps,s\<^sub>0\ [\] \evs,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\; map_val evs vs; + \(\b Ts T m D. P \ C sees M,b:Ts\T = m in D) \ + \ P \ \C\\<^sub>sM(ps),s\<^sub>0\ \ \THROW NoSuchMethodError,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\" +apply(rule SCallNone) +apply(simp add: map_val_conv[symmetric]) +apply assumption+ +done + +lemma SCallNonStatic2: + "\ P \ \ps,s\<^sub>0\ [\] \evs,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\; map_val evs vs; + P \ C sees M,NonStatic:Ts\T = m in D; + sh\<^sub>2 D = Some(sfs,Done) \ + \ P \ \C\\<^sub>sM(ps),s\<^sub>0\ \ \THROW IncompatibleClassChangeError,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\" +apply(rule SCallNonStatic) +apply(simp add: map_val_conv[symmetric]) +apply assumption+ +done + +lemma SCallInit2: + "\ P \ \ps,s\<^sub>0\ [\] \evs,(h\<^sub>1,l\<^sub>1,sh\<^sub>1)\; map_val evs vs; + P \ C sees M,Static:Ts\T = (pns,body) in D; + not_Done D sh\<^sub>1; + P \ \D,(h\<^sub>1,sh\<^sub>1)\ \\<^sub>i \None,(h\<^sub>2,sh\<^sub>2)\; + length vs = length pns; l\<^sub>2' = [pns[\]vs]; + P \ \body,(h\<^sub>2,l\<^sub>2',sh\<^sub>2)\ \ \e',(h\<^sub>3,l\<^sub>3,sh\<^sub>3)\ \ + \ P \ \C\\<^sub>sM(ps),s\<^sub>0\ \ \e',(h\<^sub>3,l\<^sub>1,sh\<^sub>3)\" +apply(rule SCallInit) +apply(simp add: map_val_conv[symmetric]) +apply assumption +apply(clarsimp simp: not_Done_def) +apply assumption+ +done + +lemma SCallInitFail2: + "\ P \ \ps,s\<^sub>0\ [\] \evs,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\; map_val evs vs; + P \ C sees M,Static:Ts\T = (pns,body) in D; + not_Done D sh\<^sub>2; + P \ \D,(h\<^sub>2,sh\<^sub>2)\ \\<^sub>i \Some e',(h\<^sub>3,sh\<^sub>3)\ \ + \ P \ \C\\<^sub>sM(ps),s\<^sub>0\ \ \e',(h\<^sub>3,l\<^sub>2,sh\<^sub>3)\" +apply(rule SCallInitFail) +apply(simp add: map_val_conv[symmetric]) +apply assumption +apply(clarsimp simp: not_Done_def) +apply assumption+ +done + +lemma SCall2: + "\ P \ \ps,s\<^sub>0\ [\] \evs,(h\<^sub>2,l\<^sub>2,sh\<^sub>2)\; + map_val evs vs; + P \ C sees M,Static:Ts\T = (pns,body) in D; + sh\<^sub>2 D = Some(sfs,Done); + length vs = length pns; l\<^sub>2' = [pns[\]vs]; + P \ \body,(h\<^sub>2,l\<^sub>2',sh\<^sub>2)\ \ \e',(h\<^sub>3,l\<^sub>3,sh\<^sub>3)\ \ + \ P \ \C\\<^sub>sM(ps),s\<^sub>0\ \ \e',(h\<^sub>3,l\<^sub>2,sh\<^sub>3)\" +apply(rule SCall) +apply(simp add: map_val_conv[symmetric]) +apply assumption+ +done + +declare not_Done_def [code_pred_def] + +code_pred + (modes: i \ o \ bool) + map_val +. + +code_pred + (modes: i \ o \ o \ bool) + map_val2 +. + +lemmas [code_pred_intro] = + eval_evals_init_rinit.New eval_evals_init_rinit.NewOOM + eval_evals_init_rinit.Cast eval_evals_init_rinit.CastNull eval_evals_init_rinit.CastFail eval_evals_init_rinit.CastThrow + eval_evals_init_rinit.Val eval_evals_init_rinit.Var + eval_evals_init_rinit.BinOp eval_evals_init_rinit.BinOpThrow1 eval_evals_init_rinit.BinOpThrow2 + eval_evals_init_rinit.LAss eval_evals_init_rinit.LAssThrow + eval_evals_init_rinit.FAcc eval_evals_init_rinit.FAccNull eval_evals_init_rinit.FAccThrow + eval_evals_init_rinit.FAccNone eval_evals_init_rinit.FAccStatic + eval_evals_init_rinit.SFAcc eval_evals_init_rinit.SFAccNone eval_evals_init_rinit.SFAccNonStatic + eval_evals_init_rinit.FAss eval_evals_init_rinit.FAssNull + eval_evals_init_rinit.FAssThrow1 eval_evals_init_rinit.FAssThrow2 + eval_evals_init_rinit.FAssNone eval_evals_init_rinit.FAssStatic + eval_evals_init_rinit.SFAss eval_evals_init_rinit.SFAssNone eval_evals_init_rinit.SFAssNonStatic + eval_evals_init_rinit.CallObjThrow + +declare NewInit2 [code_pred_intro NewInit2] +declare NewInitFail2 [code_pred_intro NewInitFail2] +declare NewInitOOM2 [code_pred_intro NewInitOOM2] +declare SFAccInit2 [code_pred_intro SFAccInit2] +declare SFAccInitFail2 [code_pred_intro SFAccInitFail2] +declare SFAssInit2 [code_pred_intro SFAssInit2] +declare SFAssInitFail2 [code_pred_intro SFAssInitFail2] +declare CallNull2 [code_pred_intro CallNull2] +declare CallParamsThrow2 [code_pred_intro CallParamsThrow2] +declare CallNone2 [code_pred_intro CallNone2] +declare CallStatic2 [code_pred_intro CallStatic2] +declare Call2 [code_pred_intro Call2] +declare SCallParamsThrow2 [code_pred_intro SCallParamsThrow2] +declare SCallNone2 [code_pred_intro SCallNone2] +declare SCallNonStatic2 [code_pred_intro SCallNonStatic2] +declare SCallInit2 [code_pred_intro SCallInit2] +declare SCallInitFail2 [code_pred_intro SCallInitFail2] +declare SCall2 [code_pred_intro SCall2] + +lemmas [code_pred_intro] = + eval_evals_init_rinit.Block + eval_evals_init_rinit.Seq eval_evals_init_rinit.SeqThrow + eval_evals_init_rinit.CondT eval_evals_init_rinit.CondF eval_evals_init_rinit.CondThrow + eval_evals_init_rinit.WhileF eval_evals_init_rinit.WhileT + eval_evals_init_rinit.WhileCondThrow + +declare eval_evals_init_rinit.WhileBodyThrow [code_pred_intro WhileBodyThrow2] + +lemmas [code_pred_intro] = + eval_evals_init_rinit.Throw eval_evals_init_rinit.ThrowNull + eval_evals_init_rinit.ThrowThrow + eval_evals_init_rinit.Try eval_evals_init_rinit.TryCatch eval_evals_init_rinit.TryThrow + eval_evals_init_rinit.Nil eval_evals_init_rinit.Cons eval_evals_init_rinit.ConsThrow + +lemmas [code_pred_intro] = + eval_evals_init_rinit.InitNone eval_evals_init_rinit.InitDone + eval_evals_init_rinit.InitProcessing eval_evals_init_rinit.InitError + eval_evals_init_rinit.InitObject eval_evals_init_rinit.InitNonObject eval_evals_init_rinit.InitFail + eval_evals_init_rinit.RInit eval_evals_init_rinit.RinitFail + +code_pred + (modes: i \ i \ i \ o \ o \ bool as execute) +(* [show_steps, + show_proof_trace, + show_intermediate_results, + show_mode_inference, + show_modes, + show_compilation, + show_invalid_clauses]*) + eval +proof - + case eval + from eval.prems show thesis + proof(cases (no_simp)) + case NewInit thus ?thesis + by-(rule eval.NewInit2[OF refl],simp_all add: not_Done_conv[symmetric]) + next + case NewInitFail thus ?thesis + by-(rule eval.NewInitFail2[OF refl],simp_all add: not_Done_conv[symmetric]) + next + case NewInitOOM thus ?thesis + by-(rule eval.NewInitOOM2[OF refl],simp_all add: not_Done_conv[symmetric]) + next + case SFAccInit thus ?thesis + using eval.SFAccInit2 not_Done_conv by auto + next + case SFAccInitFail thus ?thesis + by-(rule eval.SFAccInitFail2[OF refl],simp_all add: not_Done_conv[symmetric]) + next + case SFAssInit thus ?thesis + using eval.SFAssInit2 not_Done_conv by auto + next + case SFAssInitFail thus ?thesis + by-(rule eval.SFAssInitFail2[OF refl],simp_all add: not_Done_conv[symmetric]) + next + case CallNull thus ?thesis + by(rule eval.CallNull2[OF refl])(simp add: map_val_conv[symmetric]) + next + case CallParamsThrow thus ?thesis + by(rule eval.CallParamsThrow2[OF refl])(simp add: map_val2_conv[symmetric]) + next + case CallNone thus ?thesis + using eval.CallNone2[OF refl] map_val_conv[symmetric] by auto + next + case CallStatic thus ?thesis + using eval.CallStatic2 map_val_conv by blast + next + case Call thus ?thesis + by -(rule eval.Call2[OF refl], simp_all add: map_val_conv[symmetric]) + next + case SCallParamsThrow thus ?thesis + by(rule eval.SCallParamsThrow2[OF refl])(simp add: map_val2_conv[symmetric]) + next + case SCallNone thus ?thesis + by -(rule eval.SCallNone2[OF refl], simp_all add: map_val_conv[symmetric]) + next + case SCallNonStatic thus ?thesis + using eval.SCallNonStatic2 map_val_conv by blast + next + case SCallInit thus ?thesis + by -(rule eval.SCallInit2[OF refl], simp_all add: map_val_conv[symmetric] not_Done_conv[symmetric]) + next + case SCallInitFail thus ?thesis + by -(rule eval.SCallInitFail2[OF refl], simp_all add: map_val_conv[symmetric] not_Done_conv[symmetric]) + next + case SCall thus ?thesis + by -(rule eval.SCall2[OF refl], simp_all add: map_val_conv[symmetric]) + next + case WhileBodyThrow thus ?thesis by(rule eval.WhileBodyThrow2[OF refl]) + qed(assumption|erule (4) eval.that[OF refl]|erule (3) eval.that[OF refl])+ +next + case evals + from evals.prems show thesis + by(cases (no_simp))(assumption|erule (3) evals.that[OF refl])+ +next + case init + from init.prems show thesis + by(cases (no_simp))(assumption|erule (3) init.that[OF refl])+ +next + case rinit + from rinit.prems show thesis + by(cases (no_simp))(assumption|erule (3) rinit.that[OF refl])+ +qed + +notation execute ("_ \ ((1\_,/_\) \/ \'_, '_\)" [51,0,0] 81) + +definition "test1 = [] \ \testExpr1,(empty,empty,empty)\ \ \_,_\" +definition "test2 = [] \ \testExpr2,(empty,empty,empty)\ \ \_,_\" +definition "test3 = [] \ \testExpr3,(empty,empty(''V''\Intg 77),empty)\ \ \_,_\" +definition "test4 = [] \ \testExpr4,(empty,empty,empty)\ \ \_,_\" +definition "test5 = [(''Object'',('''',[],[])),(''C'',(''Object'',[(''F'',NonStatic,Integer)],[]))] \ \testExpr5,(empty,empty,empty)\ \ \_,_\" +definition "test6 = [(''Object'',('''',[],[])), classI] \ \testExpr6,(empty,empty,empty)\ \ \_,_\" + +definition "V = ''V''" +definition "C = ''C''" +definition "F = ''F''" + +(* HERE: MOVE THIS - also, don't really need *) +(* +lemma UNIV_staticb: "UNIV = {Static, NonStatic}" + by (auto intro: staticb.exhaust) + +instantiation staticb :: enum +begin + +definition + "enum_staticb = [Static, NonStatic]" + +definition + "enum_all_staticb P \ P NonStatic \ P Static" + +definition + "enum_ex_staticb P \ P NonStatic \ P Static" + +instance proof +qed (auto simp only: enum_staticb_def enum_all_staticb_def enum_ex_staticb_def UNIV_staticb, simp_all) + +end +*) + +ML_val \ + val SOME ((@{code Val} (@{code Intg} (@{code int_of_integer} 5)), _), _) = Predicate.yield @{code test1}; + val SOME ((@{code Val} (@{code Intg} (@{code int_of_integer} 11)), _), _) = Predicate.yield @{code test2}; + val SOME ((@{code Val} (@{code Intg} (@{code int_of_integer} 83)), _), _) = Predicate.yield @{code test3}; + + val SOME ((_, (_, l, _)), _) = Predicate.yield @{code test4}; + val SOME (@{code Intg} (@{code int_of_integer} 6)) = l @{code V}; + + val SOME ((_, (h, _)), _) = Predicate.yield @{code test5}; + val SOME (c, fs) = h (@{code nat_of_integer} 1); + val SOME (obj, _) = h (@{code nat_of_integer} 0); + val SOME (@{code Intg} i) = fs (@{code F}, @{code C}); + @{assert} (c = @{code C} andalso obj = @{code Object} andalso i = @{code int_of_integer} 42); + + val SOME ((@{code Val} (@{code Intg} (@{code int_of_integer} 160)), _), _) = Predicate.yield @{code test6}; +\ + +definition "test7 = [classObject, classL] \ \testExpr_BuildList, (empty,empty,empty)\ \ \_,_\" + +definition "L = ''L''" +definition "N = ''N''" + +ML_val \ + val SOME ((_, (h, _)), _) = Predicate.yield @{code test7}; + val SOME (_, fs1) = h (@{code nat_of_integer} 0); + val SOME (_, fs2) = h (@{code nat_of_integer} 1); + val SOME (_, fs3) = h (@{code nat_of_integer} 2); + val SOME (_, fs4) = h (@{code nat_of_integer} 3); + + val F = @{code "F"}; + val L = @{code "L"}; + val N = @{code "N"}; + + @{assert} (fs1 (F, L) = SOME (@{code Intg} (@{code int_of_integer} 1)) andalso + fs1 (N, L) = SOME (@{code Addr} (@{code nat_of_integer} 1)) andalso + fs2 (F, L) = SOME (@{code Intg} (@{code int_of_integer} 2)) andalso + fs2 (N, L) = SOME (@{code Addr} (@{code nat_of_integer} 2)) andalso + fs3 (F, L) = SOME (@{code Intg} (@{code int_of_integer} 3)) andalso + fs3 (N, L) = SOME (@{code Addr} (@{code nat_of_integer} 3)) andalso + fs4 (F, L) = SOME (@{code Intg} (@{code int_of_integer} 4)) andalso + fs4 (N, L) = SOME @{code Null}); +\ + +definition "test8 = [classObject, classA] \ \testExpr_ClassA, (empty,empty,empty)\ \ \_,_\" +definition "i = ''int''" +definition "t = ''test''" +definition "A = ''A''" + +ML_val \ + val SOME ((_, (h, l)), _) = Predicate.yield @{code test8}; + val SOME (_, fs1) = h (@{code nat_of_integer} 0); + val SOME (_, fs2) = h (@{code nat_of_integer} 1); + + val i = @{code "i"}; + val t = @{code "t"}; + val A = @{code "A"}; + + @{assert} (fs1 (i, A) = SOME (@{code Intg} (@{code int_of_integer} 10)) andalso + fs1 (t, A) = SOME @{code Null} andalso + fs2 (i, A) = SOME (@{code Intg} (@{code int_of_integer} 50)) andalso + fs2 (t, A) = SOME @{code Null}); +\ + +end + diff --git a/thys/JinjaDCI/J/execute_WellType.thy b/thys/JinjaDCI/J/execute_WellType.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/J/execute_WellType.thy @@ -0,0 +1,125 @@ +(* Title: Jinja/J/execute_WellType.thy + Author: Christoph Petzinger + Copyright 2004 Technische Universitaet Muenchen +*) +(* + Expanded to include support for static fields and methods. + Susannah Mansky + 2017, UIUC +*) + +section \ Code Generation For WellType \ + +theory execute_WellType +imports + WellType Examples +begin + +(* Replace WT_WTs.WTCond with new intros WT_WTs.WTCond1 and WT_WTs.WTCond2 *) + +lemma WTCond1: + "\P,E \ e :: Boolean; P,E \ e\<^sub>1::T\<^sub>1; P,E \ e\<^sub>2::T\<^sub>2; P \ T\<^sub>1 \ T\<^sub>2; + P \ T\<^sub>2 \ T\<^sub>1 \ T\<^sub>2 = T\<^sub>1 \ \ P,E \ if (e) e\<^sub>1 else e\<^sub>2 :: T\<^sub>2" +by (fastforce) + +lemma WTCond2: + "\P,E \ e :: Boolean; P,E \ e\<^sub>1::T\<^sub>1; P,E \ e\<^sub>2::T\<^sub>2; P \ T\<^sub>2 \ T\<^sub>1; + P \ T\<^sub>1 \ T\<^sub>2 \ T\<^sub>1 = T\<^sub>2 \ \ P,E \ if (e) e\<^sub>1 else e\<^sub>2 :: T\<^sub>1" +by (fastforce) + +lemmas [code_pred_intro] = + WT_WTs.WTNew + WT_WTs.WTCast + WT_WTs.WTVal + WT_WTs.WTVar + WT_WTs.WTBinOpEq + WT_WTs.WTBinOpAdd + WT_WTs.WTLAss + WT_WTs.WTFAcc + WT_WTs.WTSFAcc + WT_WTs.WTFAss + WT_WTs.WTSFAss + WT_WTs.WTCall + WT_WTs.WTSCall + WT_WTs.WTBlock + WT_WTs.WTSeq + +declare + WTCond1 [code_pred_intro WTCond1] + WTCond2 [code_pred_intro WTCond2] + +lemmas [code_pred_intro] = + WT_WTs.WTWhile + WT_WTs.WTThrow + WT_WTs.WTTry + WT_WTs.WTNil + WT_WTs.WTCons + +code_pred + (modes: i \ i \ i \ i \ bool as type_check, i \ i \ i \ o \ bool as infer_type) + WT +proof - + case WT + from WT.prems show thesis + proof(cases (no_simp)) + case (WTCond E e e1 T1 e2 T2 T) + from `x \ T1 \ T2 \ x \ T2 \ T1` show thesis + proof + assume "x \ T1 \ T2" + with `x \ T1 \ T2 \ T = T2` have "T = T2" .. + from `xa = E` `xb = if (e) e1 else e2` `xc = T` `x,E \ e :: Boolean` + `x,E \ e1 :: T1` `x,E \ e2 :: T2` `x \ T1 \ T2` `x \ T2 \ T1 \ T = T1` + show ?thesis unfolding `T = T2` by(rule WT.WTCond1[OF refl]) + next + assume "x \ T2 \ T1" + with `x \ T2 \ T1 \ T = T1` have "T = T1" .. + from `xa = E` `xb = if (e) e1 else e2` `xc = T` `x,E \ e :: Boolean` + `x,E \ e1 :: T1` `x,E \ e2 :: T2` `x \ T2 \ T1` `x \ T1 \ T2 \ T = T2` + show ?thesis unfolding `T = T1` by(rule WT.WTCond2[OF refl]) + qed + qed(assumption|erule (2) WT.that[OF refl])+ +next + case WTs + from WTs.prems show thesis + by(cases (no_simp))(assumption|erule (2) WTs.that[OF refl])+ +qed + +notation infer_type ("_,_ \ _ :: '_" [51,51,51]100) + +definition test1 where "test1 = [],empty \ testExpr1 :: _" +definition test2 where "test2 = [], empty \ testExpr2 :: _" +definition test3 where "test3 = [], empty(''V'' \ Integer) \ testExpr3 :: _" +definition test4 where "test4 = [], empty(''V'' \ Integer) \ testExpr4 :: _" +definition test5 where "test5 = [classObject, (''C'',(''Object'',[(''F'',NonStatic,Integer)],[]))], empty \ testExpr5 :: _" +definition test6 where "test6 = [classObject, classI], empty \ testExpr6 :: _" + +ML_val \ + val SOME(@{code Integer}, _) = Predicate.yield @{code test1}; + val SOME(@{code Integer}, _) = Predicate.yield @{code test2}; + val SOME(@{code Integer}, _) = Predicate.yield @{code test3}; + val SOME(@{code Void}, _) = Predicate.yield @{code test4}; + val SOME(@{code Void}, _) = Predicate.yield @{code test5}; + val SOME(@{code Integer}, _) = Predicate.yield @{code test6}; +\ + +definition testmb_isNull where "testmb_isNull = [classObject, classA], empty([this] [\] [Class ''A'']) \ mb_isNull :: _" +definition testmb_add where "testmb_add = [classObject, classA], empty([this,''i''] [\] [Class ''A'',Integer]) \ mb_add :: _" +definition testmb_mult_cond where "testmb_mult_cond = [classObject, classA], empty([this,''j''] [\] [Class ''A'',Integer]) \ mb_mult_cond :: _" +definition testmb_mult_block where "testmb_mult_block = [classObject, classA], empty([this,''i'',''j'',''temp''] [\] [Class ''A'',Integer,Integer,Integer]) \ mb_mult_block :: _" +definition testmb_mult where "testmb_mult = [classObject, classA], empty([this,''i'',''j''] [\] [Class ''A'',Integer,Integer]) \ mb_mult :: _" + +ML_val \ + val SOME(@{code Boolean}, _) = Predicate.yield @{code testmb_isNull}; + val SOME(@{code Integer}, _) = Predicate.yield @{code testmb_add}; + val SOME(@{code Boolean}, _) = Predicate.yield @{code testmb_mult_cond}; + val SOME(@{code Void}, _) = Predicate.yield @{code testmb_mult_block}; + val SOME(@{code Integer}, _) = Predicate.yield @{code testmb_mult}; +\ + +definition test where "test = [classObject, classA], empty \ testExpr_ClassA :: _" + +ML_val \ + val SOME(@{code Integer}, _) = Predicate.yield @{code test}; +\ + +end diff --git a/thys/JinjaDCI/JVM/JVMDefensive.thy b/thys/JinjaDCI/JVM/JVMDefensive.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/JVM/JVMDefensive.thy @@ -0,0 +1,220 @@ +(* Title: JinjaDCI/JVM/JVMDefensive.thy + Author: Gerwin Klein, Susannah Mansky + Copyright GPL + + Based on the Jinja theory JVM/JVMDefensive.thy by Gerwin Klein +*) + +section \ A Defensive JVM \ + +theory JVMDefensive +imports JVMExec "../Common/Conform" +begin + +text \ + Extend the state space by one element indicating a type error (or + other abnormal termination) \ +datatype 'a type_error = TypeError | Normal 'a + +fun is_Addr :: "val \ bool" where + "is_Addr (Addr a) \ True" +| "is_Addr v \ False" + +fun is_Intg :: "val \ bool" where + "is_Intg (Intg i) \ True" +| "is_Intg v \ False" + +fun is_Bool :: "val \ bool" where + "is_Bool (Bool b) \ True" +| "is_Bool v \ False" + +definition is_Ref :: "val \ bool" where + "is_Ref v \ v = Null \ is_Addr v" + +primrec check_instr :: "[instr, jvm_prog, heap, val list, val list, + cname, mname, pc, frame list, sheap] \ bool" where + check_instr_Load: + "check_instr (Load n) P h stk loc C M\<^sub>0 pc frs sh = + (n < length loc)" + +| check_instr_Store: + "check_instr (Store n) P h stk loc C\<^sub>0 M\<^sub>0 pc frs sh = + (0 < length stk \ n < length loc)" + +| check_instr_Push: + "check_instr (Push v) P h stk loc C\<^sub>0 M\<^sub>0 pc frs sh = + (\is_Addr v)" + +| check_instr_New: + "check_instr (New C) P h stk loc C\<^sub>0 M\<^sub>0 pc frs sh = + is_class P C" + +| check_instr_Getfield: + "check_instr (Getfield F C) P h stk loc C\<^sub>0 M\<^sub>0 pc frs sh = + (0 < length stk \ (\C' T. P \ C sees F,NonStatic:T in C') \ + (let (C', b, T) = field P C F; ref = hd stk in + C' = C \ is_Ref ref \ (ref \ Null \ + h (the_Addr ref) \ None \ + (let (D,vs) = the (h (the_Addr ref)) in + P \ D \\<^sup>* C \ vs (F,C) \ None \ P,h \ the (vs (F,C)) :\ T))))" + +| check_instr_Getstatic: + "check_instr (Getstatic C F D) P h stk loc C\<^sub>0 M\<^sub>0 pc frs sh = + ((\T. P \ C sees F,Static:T in D) \ + (let (C', b, T) = field P C F in + C' = D \ (sh D \ None \ + (let (sfs,i) = the (sh D) in + sfs F \ None \ P,h \ the (sfs F) :\ T))))" + +| check_instr_Putfield: + "check_instr (Putfield F C) P h stk loc C\<^sub>0 M\<^sub>0 pc frs sh = + (1 < length stk \ (\C' T. P \ C sees F,NonStatic:T in C') \ + (let (C', b, T) = field P C F; v = hd stk; ref = hd (tl stk) in + C' = C \ is_Ref ref \ (ref \ Null \ + h (the_Addr ref) \ None \ + (let D = fst (the (h (the_Addr ref))) in + P \ D \\<^sup>* C \ P,h \ v :\ T))))" + +| check_instr_Putstatic: + "check_instr (Putstatic C F D) P h stk loc C\<^sub>0 M\<^sub>0 pc frs sh = + (0 < length stk \ (\T. P \ C sees F,Static:T in D) \ + (let (C', b, T) = field P C F; v = hd stk in + C' = D \ P,h \ v :\ T))" + +| check_instr_Checkcast: + "check_instr (Checkcast C) P h stk loc C\<^sub>0 M\<^sub>0 pc frs sh = + (0 < length stk \ is_class P C \ is_Ref (hd stk))" + +| check_instr_Invoke: + "check_instr (Invoke M n) P h stk loc C\<^sub>0 M\<^sub>0 pc frs sh = + (n < length stk \ is_Ref (stk!n) \ + (stk!n \ Null \ + (let a = the_Addr (stk!n); + C = cname_of h a; + Ts = fst (snd (snd (method P C M))) + in h a \ None \ P \ C has M,NonStatic \ + P,h \ rev (take n stk) [:\] Ts)))" + +| check_instr_Invokestatic: + "check_instr (Invokestatic C M n) P h stk loc C\<^sub>0 M\<^sub>0 pc frs sh = + (n \ length stk \ + (let Ts = fst (snd (snd (method P C M))) + in P \ C has M,Static \ + P,h \ rev (take n stk) [:\] Ts))" + +| check_instr_Return: + "check_instr Return P h stk loc C\<^sub>0 M\<^sub>0 pc frs sh = + (case (M\<^sub>0 = clinit) of False \ (0 < length stk \ ((0 < length frs) \ + (\b. P \ C\<^sub>0 has M\<^sub>0,b) \ + (let v = hd stk; + T = fst (snd (snd (snd (method P C\<^sub>0 M\<^sub>0)))) + in P,h \ v :\ T))) + | True \ P \ C\<^sub>0 has M\<^sub>0,Static)" + +| check_instr_Pop: + "check_instr Pop P h stk loc C\<^sub>0 M\<^sub>0 pc frs sh = + (0 < length stk)" + +| check_instr_IAdd: + "check_instr IAdd P h stk loc C\<^sub>0 M\<^sub>0 pc frs sh = + (1 < length stk \ is_Intg (hd stk) \ is_Intg (hd (tl stk)))" + +| check_instr_IfFalse: + "check_instr (IfFalse b) P h stk loc C\<^sub>0 M\<^sub>0 pc frs sh = + (0 < length stk \ is_Bool (hd stk) \ 0 \ int pc+b)" + +| check_instr_CmpEq: + "check_instr CmpEq P h stk loc C\<^sub>0 M\<^sub>0 pc frs sh = + (1 < length stk)" + +| check_instr_Goto: + "check_instr (Goto b) P h stk loc C\<^sub>0 M\<^sub>0 pc frs sh = + (0 \ int pc+b)" + +| check_instr_Throw: + "check_instr Throw P h stk loc C\<^sub>0 M\<^sub>0 pc frs sh = + (0 < length stk \ is_Ref (hd stk))" + +definition check :: "jvm_prog \ jvm_state \ bool" where + "check P \ = (let (xcpt, h, frs, sh) = \ in + (case frs of [] \ True | (stk,loc,C,M,pc,ics)#frs' \ + \b. P \ C has M, b \ + (let (C',b,Ts,T,mxs,mxl\<^sub>0,ins,xt) = method P C M; i = ins!pc in + pc < size ins \ size stk \ mxs \ + check_instr i P h stk loc C M pc frs' sh)))" + + +definition exec_d :: "jvm_prog \ jvm_state \ jvm_state option type_error" where + "exec_d P \ = (if check P \ then Normal (exec (P, \)) else TypeError)" + + +inductive_set + exec_1_d :: "jvm_prog \ (jvm_state type_error \ jvm_state type_error) set" + and exec_1_d' :: "jvm_prog \ jvm_state type_error \ jvm_state type_error \ bool" + ("_ \ _ -jvmd\\<^sub>1 _" [61,61,61]60) + for P :: jvm_prog +where + "P \ \ -jvmd\\<^sub>1 \' \ (\,\') \ exec_1_d P" +| exec_1_d_ErrorI: "exec_d P \ = TypeError \ P \ Normal \ -jvmd\\<^sub>1 TypeError" +| exec_1_d_NormalI: "exec_d P \ = Normal (Some \') \ P \ Normal \ -jvmd\\<^sub>1 Normal \'" + +\ \reflexive transitive closure:\ +definition exec_all_d :: "jvm_prog \ jvm_state type_error \ jvm_state type_error \ bool" + ("_ \ _ -jvmd\ _" [61,61,61]60) where + exec_all_d_def1: "P \ \ -jvmd\ \' \ (\,\') \ (exec_1_d P)\<^sup>*" + +notation (ASCII) + "exec_all_d" ("_ |- _ -jvmd-> _" [61,61,61]60) + +lemma exec_1_d_eq: + "exec_1_d P = {(s,t). \\. s = Normal \ \ t = TypeError \ exec_d P \ = TypeError} \ + {(s,t). \\ \'. s = Normal \ \ t = Normal \' \ exec_d P \ = Normal (Some \')}" +by (auto elim!: exec_1_d.cases intro!: exec_1_d.intros) + + +declare split_paired_All [simp del] +declare split_paired_Ex [simp del] + +lemma if_neq [dest!]: + "(if P then A else B) \ B \ P" + by (cases P, auto) + +lemma exec_d_no_errorI [intro]: + "check P \ \ exec_d P \ \ TypeError" + by (unfold exec_d_def) simp + +theorem no_type_error_commutes: + "exec_d P \ \ TypeError \ exec_d P \ = Normal (exec (P, \))" + by (unfold exec_d_def, auto) + + +lemma defensive_imp_aggressive: + "P \ (Normal \) -jvmd\ (Normal \') \ P \ \ -jvm\ \'" +(*<*) +proof - + have "\x y. P \ x -jvmd\ y \ \\ \'. x = Normal \ \ y = Normal \' \ P \ \ -jvm\ \'" + proof - + fix x y assume xy: "P \ x -jvmd\ y" + then have "(x, y) \ (exec_1_d P)\<^sup>*" by (unfold exec_all_d_def1) + then show "\\ \'. x = Normal \ \ y = Normal \' \ P \ \ -jvm\ \'" + proof(induct rule: rtrancl_induct) + case base + then show ?case by (simp add: exec_all_def) + next + case (step y' z') + show ?case proof(induct rule: exec_1_d.cases[OF step.hyps(2)]) + case (2 \ \') + then have "(\, \') \ {(\, \'). exec (P, \) = \\'\}\<^sup>*" using step + by(fastforce simp: exec_d_def split: type_error.splits if_split_asm) + then show ?case using step 2 by (auto simp: exec_all_def) + qed simp + qed + qed + moreover + assume "P \ (Normal \) -jvmd\ (Normal \')" + ultimately + show "P \ \ -jvm\ \'" by blast +qed +(*>*) + +end diff --git a/thys/JinjaDCI/JVM/JVMExceptions.thy b/thys/JinjaDCI/JVM/JVMExceptions.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/JVM/JVMExceptions.thy @@ -0,0 +1,116 @@ +(* Title: JinjaDCI/JVM/JVMExceptions.thy + Author: Gerwin Klein, Martin Strecker, Susannah Mansky + Copyright 2001 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory JVM/JVMExceptions.thy by Gerwin Klein and Martin Strecker +*) + +section \ Exception handling in the JVM \ + +theory JVMExceptions imports "../Common/Exceptions" JVMInstructions +begin + +definition matches_ex_entry :: "'m prog \ cname \ pc \ ex_entry \ bool" +where + "matches_ex_entry P C pc xcp \ + let (s, e, C', h, d) = xcp in + s \ pc \ pc < e \ P \ C \\<^sup>* C'" + + +primrec match_ex_table :: "'m prog \ cname \ pc \ ex_table \ (pc \ nat) option" +where + "match_ex_table P C pc [] = None" +| "match_ex_table P C pc (e#es) = (if matches_ex_entry P C pc e + then Some (snd(snd(snd e))) + else match_ex_table P C pc es)" + +abbreviation + ex_table_of :: "jvm_prog \ cname \ mname \ ex_table" where + "ex_table_of P C M == snd (snd (snd (snd (snd (snd (snd (method P C M)))))))" + + +fun find_handler :: "jvm_prog \ addr \ heap \ frame list \ sheap \ jvm_state" +where + "find_handler P a h [] sh = (Some a, h, [], sh)" +| "find_handler P a h (fr#frs) sh = + (let (stk,loc,C,M,pc,ics) = fr in + case match_ex_table P (cname_of h a) pc (ex_table_of P C M) of + None \ + (case M = clinit of + True \ (case frs of (stk',loc',C',M',pc',ics')#frs' + \ (case ics' of Called Cs \ (None, h, (stk',loc',C',M',pc',Throwing (C#Cs) a)#frs', sh) + | _ \ (None, h, (stk',loc',C',M',pc',ics')#frs', sh) \ \this won't happen in wf code\ + ) + | [] \ (Some a, h, [], sh) + ) + | _ \ find_handler P a h frs sh + ) + | Some pc_d \ (None, h, (Addr a # drop (size stk - snd pc_d) stk, loc, C, M, fst pc_d, No_ics)#frs, sh))" + +lemma find_handler_cases: + "find_handler P a h frs sh = js + \ (\frs'. frs' \ [] \ js = (None, h, frs', sh)) \ (js = (Some a, h, [], sh))" +proof(induct P a h frs sh rule: find_handler.induct) + case 1 then show ?case by clarsimp +next + case (2 P a h fr frs sh) then show ?case + by(cases fr, auto split: bool.splits list.splits init_call_status.splits) +qed + +lemma find_handler_heap[simp]: +"find_handler P a h frs sh = (xp',h',frs',sh') \ h' = h" + by(auto dest: find_handler_cases) + +lemma find_handler_sheap[simp]: +"find_handler P a h frs sh = (xp',h',frs',sh') \ sh' = sh" + by(auto dest: find_handler_cases) + +lemma find_handler_frames[simp]: +"find_handler P a h frs sh = (xp',h',frs',sh') \ length frs' \ length frs" +proof(induct frs) + case Nil then show ?case by simp +next + case (Cons a frs) then show ?case + by(auto simp: split_beta split: bool.splits list.splits init_call_status.splits) +qed + +lemma find_handler_None: + "find_handler P a h frs sh = (None, h, frs', sh') \ frs' \ []" + by (drule find_handler_cases, clarsimp) + +lemma find_handler_Some: + "find_handler P a h frs sh = (Some x, h, frs', sh') \ frs' = []" + by (drule find_handler_cases, clarsimp) + +lemma find_handler_Some_same_error_same_heap[simp]: + "find_handler P a h frs sh = (Some x, h', frs', sh') \ x = a \ h = h' \ sh = sh'" + by(auto dest: find_handler_cases) + +lemma find_handler_prealloc_pres: +assumes "preallocated h" +and fh: "find_handler P a h frs sh = (xp',h',frs',sh')" +shows "preallocated h'" +using assms find_handler_heap[OF fh] by simp + +lemma find_handler_frs_tl_neq: + "ics_of f \ No_ics + \ (xp, h, f#frs, sh) \ find_handler P xa h' (f' # frs) sh'" +proof(induct frs arbitrary: f f') + case Nil then show ?case by(auto simp: split_beta split: bool.splits) +next + case (Cons a frs) + obtain xp1 h1 frs1 sh1 where fh: "find_handler P xa h' (a # frs) sh' = (xp1,h1,frs1,sh1)" + by(cases "find_handler P xa h' (a # frs) sh'") + then have "length frs1 \ length (a#frs)" + by(rule find_handler_frames[where P=P and a=xa and h=h' and frs="a#frs" and sh=sh']) + then have neq: "f#a#frs \ frs1" by(clarsimp dest: impossible_Cons) + then show ?case + proof(cases "find_handler P xa h' (f' # a # frs) sh' = find_handler P xa h' (a # frs) sh'") + case True then show ?thesis using neq fh by simp + next + case False then show ?thesis using Cons.prems + by(fastforce simp: split_beta split: bool.splits init_call_status.splits list.splits) + qed +qed + +end diff --git a/thys/JinjaDCI/JVM/JVMExec.thy b/thys/JinjaDCI/JVM/JVMExec.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/JVM/JVMExec.thy @@ -0,0 +1,238 @@ + +(* Title: JinjaDCI/JVM/JVMExec.thy + Author: Cornelia Pusch, Gerwin Klein, Susannah Mansky + Copyright 1999 Technische Universitaet Muenchen, 2019-20 + + Based on the Jinja theory JVM/JVMExec.thy by Cornelia Pusch and Gerwin Klein +*) + +section \ Program Execution in the JVM in full small step style \ + +theory JVMExec +imports JVMExecInstr +begin + +abbreviation + instrs_of :: "jvm_prog \ cname \ mname \ instr list" where + "instrs_of P C M == fst(snd(snd(snd(snd(snd(snd(method P C M)))))))" + +fun curr_instr :: "jvm_prog \ frame \ instr" where +"curr_instr P (stk,loc,C,M,pc,ics) = instrs_of P C M ! pc" + +\ \ execution of single step of the initialization procedure \ +fun exec_Calling :: "[cname, cname list, jvm_prog, heap, val list, val list, + cname, mname, pc, frame list, sheap] \ jvm_state" +where +"exec_Calling C Cs P h stk loc C\<^sub>0 M\<^sub>0 pc frs sh = + (case sh C of + None \ (None, h, (stk, loc, C\<^sub>0, M\<^sub>0, pc, Calling C Cs)#frs, sh(C := Some (sblank P C, Prepared))) + | Some (obj, iflag) \ + (case iflag of + Done \ (None, h, (stk, loc, C\<^sub>0, M\<^sub>0, pc, Called Cs)#frs, sh) + | Processing \ (None, h, (stk, loc, C\<^sub>0, M\<^sub>0, pc, Called Cs)#frs, sh) + | Error \ (None, h, (stk, loc, C\<^sub>0, M\<^sub>0, pc, + Throwing Cs (addr_of_sys_xcpt NoClassDefFoundError))#frs, sh) + | Prepared \ + let sh' = sh(C:=Some(fst(the(sh C)), Processing)); + D = fst(the(class P C)) + in if C = Object + then (None, h, (stk, loc, C\<^sub>0, M\<^sub>0, pc, Called (C#Cs))#frs, sh') + else (None, h, (stk, loc, C\<^sub>0, M\<^sub>0, pc, Calling D (C#Cs))#frs, sh') + ) + )" + +\ \ single step of execution without error handling \ +fun exec_step :: "[jvm_prog, heap, val list, val list, + cname, mname, pc, init_call_status, frame list, sheap] \ jvm_state" +where +"exec_step P h stk loc C M pc (Calling C' Cs) frs sh + = exec_Calling C' Cs P h stk loc C M pc frs sh" | +"exec_step P h stk loc C M pc (Called (C'#Cs)) frs sh + = (None, h, create_init_frame P C'#(stk, loc, C, M, pc, Called Cs)#frs, sh)" | +"exec_step P h stk loc C M pc (Throwing (C'#Cs) a) frs sh + = (None, h, (stk,loc,C,M,pc,Throwing Cs a)#frs, sh(C':=Some(fst(the(sh C')), Error)))" | +"exec_step P h stk loc C M pc (Throwing [] a) frs sh + = (\a\, h, (stk,loc,C,M,pc,No_ics)#frs, sh)" | +"exec_step P h stk loc C M pc ics frs sh + = exec_instr (instrs_of P C M ! pc) P h stk loc C M pc ics frs sh" + +\ \ execution including error handling \ +fun exec :: "jvm_prog \ jvm_state \ jvm_state option" \ \single step execution\ where +"exec (P, None, h, (stk,loc,C,M,pc,ics)#frs, sh) = + (let (xp', h', frs', sh') = exec_step P h stk loc C M pc ics frs sh + in case xp' of + None \ Some (None,h',frs',sh') + | Some x \ Some (find_handler P x h ((stk,loc,C,M,pc,ics)#frs) sh) + )" +| "exec _ = None" + +\ \relational view\ +inductive_set + exec_1 :: "jvm_prog \ (jvm_state \ jvm_state) set" + and exec_1' :: "jvm_prog \ jvm_state \ jvm_state \ bool" + ("_ \/ _ -jvm\\<^sub>1/ _" [61,61,61] 60) + for P :: jvm_prog +where + "P \ \ -jvm\\<^sub>1 \' \ (\,\') \ exec_1 P" +| exec_1I: "exec (P,\) = Some \' \ P \ \ -jvm\\<^sub>1 \'" + +\ \reflexive transitive closure:\ +definition exec_all :: "jvm_prog \ jvm_state \ jvm_state \ bool" + ("(_ \/ _ -jvm\/ _)" [61,61,61]60) where + exec_all_def1: "P \ \ -jvm\ \' \ (\,\') \ (exec_1 P)\<^sup>*" + +notation (ASCII) + exec_all ("_ |-/ _ -jvm->/ _" [61,61,61]60) + + +lemma exec_1_eq: + "exec_1 P = {(\,\'). exec (P,\) = Some \'}" +(*<*)by (auto intro: exec_1I elim: exec_1.cases)(*>*) + +lemma exec_1_iff: + "P \ \ -jvm\\<^sub>1 \' = (exec (P,\) = Some \')" +(*<*)by (simp add: exec_1_eq)(*>*) + +lemma exec_all_def: + "P \ \ -jvm\ \' = ((\,\') \ {(\,\'). exec (P,\) = Some \'}\<^sup>*)" +(*<*)by (simp add: exec_all_def1 exec_1_eq)(*>*) + +lemma jvm_refl[iff]: "P \ \ -jvm\ \" +(*<*)by(simp add: exec_all_def)(*>*) + +lemma jvm_trans[trans]: + "\ P \ \ -jvm\ \'; P \ \' -jvm\ \'' \ \ P \ \ -jvm\ \''" +(*<*)by(simp add: exec_all_def)(*>*) + +lemma jvm_one_step1[trans]: + "\ P \ \ -jvm\\<^sub>1 \'; P \ \' -jvm\ \'' \ \ P \ \ -jvm\ \''" +(*<*) by (simp add: exec_all_def1) (*>*) + +lemma jvm_one_step2[trans]: + "\ P \ \ -jvm\ \'; P \ \' -jvm\\<^sub>1 \'' \ \ P \ \ -jvm\ \''" +(*<*) by (simp add: exec_all_def1) (*>*) + +lemma exec_all_conf: + "\ P \ \ -jvm\ \'; P \ \ -jvm\ \'' \ + \ P \ \' -jvm\ \'' \ P \ \'' -jvm\ \'" +(*<*)by(simp add: exec_all_def single_valued_def single_valued_confluent)(*>*) + +lemma exec_1_exec_all_conf: + "\ exec (P, \) = Some \'; P \ \ -jvm\ \''; \ \ \'' \ + \ P \ \' -jvm\ \''" + by(auto elim: converse_rtranclE simp: exec_1_eq exec_all_def) + +lemma exec_all_finalD: "P \ (x, h, [], sh) -jvm\ \ \ \ = (x, h, [], sh)" +(*<*) +proof - + assume "P \ (x, h, [], sh) -jvm\ \" + then have "((x, h, [], sh), \) \ {(\, \'). exec (P, \) = \\'\}\<^sup>*" + by(simp only: exec_all_def) + then show ?thesis proof(rule converse_rtranclE) qed simp+ +qed +(*>*) + +lemma exec_all_deterministic: + "\ P \ \ -jvm\ (x,h,[],sh); P \ \ -jvm\ \' \ \ P \ \' -jvm\ (x,h,[],sh)" +(*<*) +proof - + assume assms: "P \ \ -jvm\ (x,h,[],sh)" "P \ \ -jvm\ \'" + show ?thesis using exec_all_conf[OF assms] + by(blast dest!: exec_all_finalD) +qed +(*>*) + +subsection "Preservation of preallocated" + +lemma exec_Calling_prealloc_pres: +assumes "preallocated h" + and "exec_Calling C Cs P h stk loc C\<^sub>0 M\<^sub>0 pc frs sh = (xp',h',frs',sh')" +shows "preallocated h'" +using assms +proof(cases "sh C") + case (Some a) + then obtain sfs i where sfsi:"a = (sfs, i)" by(cases a) + then show ?thesis using Some assms + proof(cases i) + case Prepared + then show ?thesis using sfsi Some assms by(cases "method P C clinit", auto split: if_split_asm) + next + case Error + then show ?thesis using sfsi Some assms by(cases "method P C clinit", auto) + qed(auto) +qed(auto) + +lemma exec_step_prealloc_pres: +assumes pre: "preallocated h" + and "exec_step P h stk loc C M pc ics frs sh = (xp',h',frs',sh')" +shows "preallocated h'" +proof(cases ics) + case No_ics + then show ?thesis using exec_instr_prealloc_pres assms by auto +next + case Calling + then show ?thesis using exec_Calling_prealloc_pres assms by auto +next + case (Called Cs) + then show ?thesis using exec_instr_prealloc_pres assms by(cases Cs, auto) +next + case (Throwing Cs a) + then show ?thesis using assms by(cases Cs, auto) +qed + +lemma exec_prealloc_pres: +assumes pre: "preallocated h" + and "exec (P, xp, h, frs, sh) = Some(xp',h',frs',sh')" +shows "preallocated h'" +using assms +proof(cases "\x. xp = \x\ \ frs = []") + case False + then obtain f1 frs1 where frs: "frs = f1#frs1" by(cases frs, simp+) + then obtain stk1 loc1 C1 M1 pc1 ics1 where f1: "f1 = (stk1,loc1,C1,M1,pc1,ics1)" by(cases f1) + let ?i = "instrs_of P C1 M1 ! pc1" + obtain xp2 h2 frs2 sh2 + where exec_step: "exec_step P h stk1 loc1 C1 M1 pc1 ics1 frs1 sh = (xp2,h2,frs2,sh2)" + by(cases "exec_step P h stk1 loc1 C1 M1 pc1 ics1 frs1 sh") + then show ?thesis using exec_step_prealloc_pres[OF pre exec_step] f1 frs False assms + proof(cases xp2) + case (Some a) + show ?thesis + using find_handler_prealloc_pres[OF pre, where a=a] + exec_step_prealloc_pres[OF pre] + exec_step f1 frs Some False assms + by(auto split: bool.splits init_call_status.splits list.splits) + qed(auto split: init_call_status.splits) +qed(auto) + +subsection "Start state" + +text \ The @{term Start} class is defined based on a given initial class + and method. It has two methods: one that calls the initial method in the + initial class, which is called by the starting program, and @{term clinit}, + as required for the class to be well-formed. \ +definition start_method :: "cname \ mname \ jvm_method mdecl" where +"start_method C M = (start_m, Static, [], Void, (1,0,[Invokestatic C M 0,Return],[]))" +abbreviation start_clinit :: "jvm_method mdecl" where +"start_clinit \ (clinit, Static, [], Void, (1,0,[Push Unit,Return],[]))" +definition start_class :: "cname \ mname \ jvm_method cdecl" where +"start_class C M = (Start, Object, [], [start_method C M, start_clinit])" + +text \ + The start configuration of the JVM in program @{text P}: + in the start heap, we call the ``start'' method of the + ``Start''; this method performs @{text Invokestatic} on the + class and method given to create the start program's @{term Start} class. + This allows the initialization procedure to be called on the + initial class in a natural way before the initial method is performed. + There is no @{text this} pointer of the frame as @{term start} is @{term Static}. + The start sheap has every class pre-prepared; this decision is not + necessary. + The starting program includes the added @{term Start} class, given a + method @{text M} of class @{text C}, added to program @{text P}. +\ +definition start_state :: "jvm_prog \ jvm_state" where + "start_state P = (None, start_heap P, [([], [], Start, start_m, 0, No_ics)], start_sheap)" +abbreviation start_prog :: "jvm_prog \ cname \ mname \ jvm_prog" where +"start_prog P C M \ start_class C M # P" + +end \ No newline at end of file diff --git a/thys/JinjaDCI/JVM/JVMExecInstr.thy b/thys/JinjaDCI/JVM/JVMExecInstr.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/JVM/JVMExecInstr.thy @@ -0,0 +1,393 @@ + +(* Title: JinjaDCI/JVM/JVMExecInstr.thy + Author: Cornelia Pusch, Gerwin Klein, Susannah Mansky + Copyright 1999 Technische Universitaet Muenchen + + Based on the Jinja theory JVM/JVMExecInstr.thy by Cornelia Pusch and Gerwin Klein +*) + +section \ Program Execution in the JVM \ + +theory JVMExecInstr +imports JVMInstructions JVMExceptions +begin + + \ \ frame calling the class initialization method for the given class + in the given program \ +fun create_init_frame :: "[jvm_prog, cname] \ frame" where +"create_init_frame P C = + (let (D,b,Ts,T,(mxs,mxl\<^sub>0,ins,xt)) = method P C clinit + in ([],(replicate mxl\<^sub>0 undefined),D,clinit,0,No_ics) + )" + +primrec exec_instr :: "[instr, jvm_prog, heap, val list, val list, + cname, mname, pc, init_call_status, frame list, sheap] \ jvm_state" +where + exec_instr_Load: +"exec_instr (Load n) P h stk loc C\<^sub>0 M\<^sub>0 pc ics frs sh = + (None, h, ((loc ! n) # stk, loc, C\<^sub>0, M\<^sub>0, Suc pc, ics)#frs, sh)" + +| exec_instr_Store: +"exec_instr (Store n) P h stk loc C\<^sub>0 M\<^sub>0 pc ics frs sh = + (None, h, (tl stk, loc[n:=hd stk], C\<^sub>0, M\<^sub>0, Suc pc, ics)#frs, sh)" + +| exec_instr_Push: +"exec_instr (Push v) P h stk loc C\<^sub>0 M\<^sub>0 pc ics frs sh = + (None, h, (v # stk, loc, C\<^sub>0, M\<^sub>0, Suc pc, ics)#frs, sh)" + +| exec_instr_New: +"exec_instr (New C) P h stk loc C\<^sub>0 M\<^sub>0 pc ics frs sh = + (case (ics, sh C) of + (Called Cs, _) \ + (case new_Addr h of + None \ (\addr_of_sys_xcpt OutOfMemory\, h, (stk, loc, C\<^sub>0, M\<^sub>0, pc, No_ics)#frs, sh) + | Some a \ (None, h(a\blank P C), (Addr a#stk, loc, C\<^sub>0, M\<^sub>0, Suc pc, No_ics)#frs, sh) + ) + | (_, Some(obj, Done)) \ + (case new_Addr h of + None \ (\addr_of_sys_xcpt OutOfMemory\, h, (stk, loc, C\<^sub>0, M\<^sub>0, pc, ics)#frs, sh) + | Some a \ (None, h(a\blank P C), (Addr a#stk, loc, C\<^sub>0, M\<^sub>0, Suc pc, ics)#frs, sh) + ) + | _ \ (None, h, (stk, loc, C\<^sub>0, M\<^sub>0, pc, Calling C [])#frs, sh) + )" + +| exec_instr_Getfield: +"exec_instr (Getfield F C) P h stk loc C\<^sub>0 M\<^sub>0 pc ics frs sh = + (let v = hd stk; + (D,fs) = the(h(the_Addr v)); + (D',b,t) = field P C F; + xp' = if v=Null then \addr_of_sys_xcpt NullPointer\ + else if \(\t b. P \ D has F,b:t in C) + then \addr_of_sys_xcpt NoSuchFieldError\ + else case b of Static \ \addr_of_sys_xcpt IncompatibleClassChangeError\ + | NonStatic \ None + in case xp' of None \ (xp', h, (the(fs(F,C))#(tl stk), loc, C\<^sub>0, M\<^sub>0, pc+1, ics)#frs, sh) + | Some x \ (xp', h, (stk, loc, C\<^sub>0, M\<^sub>0, pc, ics)#frs, sh))" + +| exec_instr_Getstatic: +"exec_instr (Getstatic C F D) P h stk loc C\<^sub>0 M\<^sub>0 pc ics frs sh = + (let (D',b,t) = field P D F; + xp' = if \(\t b. P \ C has F,b:t in D) + then \addr_of_sys_xcpt NoSuchFieldError\ + else case b of NonStatic \ \addr_of_sys_xcpt IncompatibleClassChangeError\ + | Static \ None + in (case (xp', ics, sh D') of + (Some a, _) \ (xp', h, (stk, loc, C\<^sub>0, M\<^sub>0, pc, ics)#frs, sh) + | (_, Called Cs, _) \ let (sfs, i) = the(sh D'); + v = the(sfs F) + in (xp', h, (v#stk, loc, C\<^sub>0, M\<^sub>0, Suc pc, No_ics)#frs, sh) + | (_, _, Some (sfs, Done)) \ let v = the (sfs F) + in (xp', h, (v#stk, loc, C\<^sub>0, M\<^sub>0, Suc pc, ics)#frs, sh) + | _ \ (xp', h, (stk, loc, C\<^sub>0, M\<^sub>0, pc, Calling D' [])#frs, sh) + ) + )" + +| exec_instr_Putfield: +"exec_instr (Putfield F C) P h stk loc C\<^sub>0 M\<^sub>0 pc ics frs sh = + (let v = hd stk; + r = hd (tl stk); + a = the_Addr r; + (D,fs) = the (h a); + (D',b,t) = field P C F; + xp' = if r=Null then \addr_of_sys_xcpt NullPointer\ + else if \(\t b. P \ D has F,b:t in C) + then \addr_of_sys_xcpt NoSuchFieldError\ + else case b of Static \ \addr_of_sys_xcpt IncompatibleClassChangeError\ + | NonStatic \ None; + h' = h(a \ (D, fs((F,C) \ v))) + in case xp' of None \ (xp', h', (tl (tl stk), loc, C\<^sub>0, M\<^sub>0, pc+1, ics)#frs, sh) + | Some x \ (xp', h, (stk, loc, C\<^sub>0, M\<^sub>0, pc, ics)#frs, sh) + )" + +| exec_instr_Putstatic: +"exec_instr (Putstatic C F D) P h stk loc C\<^sub>0 M\<^sub>0 pc ics frs sh = + (let (D',b,t) = field P D F; + xp' = if \(\t b. P \ C has F,b:t in D) + then \addr_of_sys_xcpt NoSuchFieldError\ + else case b of NonStatic \ \addr_of_sys_xcpt IncompatibleClassChangeError\ + | Static \ None + in (case (xp', ics, sh D') of + (Some a, _) \ (xp', h, (stk, loc, C\<^sub>0, M\<^sub>0, pc, ics)#frs, sh) + | (_, Called Cs, _) + \ let (sfs, i) = the(sh D') + in (xp', h, (tl stk, loc, C\<^sub>0, M\<^sub>0, Suc pc, No_ics)#frs, sh(D':=Some ((sfs(F \ hd stk)), i))) + | (_, _, Some (sfs, Done)) + \ (xp', h, (tl stk, loc, C\<^sub>0, M\<^sub>0, Suc pc, ics)#frs, sh(D':=Some ((sfs(F \ hd stk)), Done))) + | _ \ (xp', h, (stk, loc, C\<^sub>0, M\<^sub>0, pc, Calling D' [])#frs, sh) + ) + )" + +| exec_instr_Checkcast: +"exec_instr (Checkcast C) P h stk loc C\<^sub>0 M\<^sub>0 pc ics frs sh = + (if cast_ok P C h (hd stk) + then (None, h, (stk, loc, C\<^sub>0, M\<^sub>0, Suc pc, ics)#frs, sh) + else (\addr_of_sys_xcpt ClassCast\, h, (stk, loc, C\<^sub>0, M\<^sub>0, pc, ics)#frs, sh) + )" + +| exec_instr_Invoke: +"exec_instr (Invoke M n) P h stk loc C\<^sub>0 M\<^sub>0 pc ics frs sh = + (let ps = take n stk; + r = stk!n; + C = fst(the(h(the_Addr r))); + (D,b,Ts,T,mxs,mxl\<^sub>0,ins,xt)= method P C M; + xp' = if r=Null then \addr_of_sys_xcpt NullPointer\ + else if \(\Ts T m D b. P \ C sees M,b:Ts \ T = m in D) + then \addr_of_sys_xcpt NoSuchMethodError\ + else case b of Static \ \addr_of_sys_xcpt IncompatibleClassChangeError\ + | NonStatic \ None; + f' = ([],[r]@(rev ps)@(replicate mxl\<^sub>0 undefined),D,M,0,No_ics) + in case xp' of None \ (xp', h, f'#(stk, loc, C\<^sub>0, M\<^sub>0, pc, ics)#frs, sh) + | Some a \ (xp', h, (stk, loc, C\<^sub>0, M\<^sub>0, pc, ics)#frs, sh) + )" + +| exec_instr_Invokestatic: +"exec_instr (Invokestatic C M n) P h stk loc C\<^sub>0 M\<^sub>0 pc ics frs sh = + (let ps = take n stk; + (D,b,Ts,T,mxs,mxl\<^sub>0,ins,xt)= method P C M; + xp' = if \(\Ts T m D b. P \ C sees M,b:Ts \ T = m in D) + then \addr_of_sys_xcpt NoSuchMethodError\ + else case b of NonStatic \ \addr_of_sys_xcpt IncompatibleClassChangeError\ + | Static \ None; + f' = ([],(rev ps)@(replicate mxl\<^sub>0 undefined),D,M,0,No_ics) + in (case (xp', ics, sh D) of + (Some a, _) \ (xp', h, (stk, loc, C\<^sub>0, M\<^sub>0, pc, ics)#frs, sh) + | (_, Called Cs, _) \ (xp', h, f'#(stk, loc, C\<^sub>0, M\<^sub>0, pc, No_ics)#frs, sh) + | (_, _, Some (sfs, Done)) \ (xp', h, f'#(stk, loc, C\<^sub>0, M\<^sub>0, pc, ics)#frs, sh) + | _ \ (xp', h, (stk, loc, C\<^sub>0, M\<^sub>0, pc, Calling D [])#frs, sh) + ) + )" + +| exec_instr_Return: + "exec_instr Return P h stk\<^sub>0 loc\<^sub>0 C\<^sub>0 M\<^sub>0 pc ics frs sh = + (case frs of + [] \ let sh' = (case M\<^sub>0 = clinit of True \ sh(C\<^sub>0:=Some(fst(the(sh C\<^sub>0)), Done)) + | _ \ sh + ) + in (None, h, [], sh') + | (stk',loc',C',m',pc',ics')#frs' + \ let (D,b,Ts,T,(mxs,mxl\<^sub>0,ins,xt)) = method P C\<^sub>0 M\<^sub>0; + offset = case b of NonStatic \ 1 | Static \ 0; + (sh'', stk'', pc'') = (case M\<^sub>0 = clinit of True \ (sh(C\<^sub>0:=Some(fst(the(sh C\<^sub>0)), Done)), stk', pc') + | _ \ (sh, (hd stk\<^sub>0)#(drop (length Ts + offset) stk'), Suc pc') + ) + in (None, h, (stk'',loc',C',m',pc'',ics')#frs', sh'') + )" + +| exec_instr_Pop: +"exec_instr Pop P h stk loc C\<^sub>0 M\<^sub>0 pc ics frs sh = (None, h, (tl stk, loc, C\<^sub>0, M\<^sub>0, Suc pc, ics)#frs, sh)" + +| exec_instr_IAdd: +"exec_instr IAdd P h stk loc C\<^sub>0 M\<^sub>0 pc ics frs sh = + (None, h, (Intg (the_Intg (hd (tl stk)) + the_Intg (hd stk))#(tl (tl stk)), loc, C\<^sub>0, M\<^sub>0, Suc pc, ics)#frs, sh)" + +| exec_instr_IfFalse: +"exec_instr (IfFalse i) P h stk loc C\<^sub>0 M\<^sub>0 pc ics frs sh = + (let pc' = if hd stk = Bool False then nat(int pc+i) else pc+1 + in (None, h, (tl stk, loc, C\<^sub>0, M\<^sub>0, pc', ics)#frs, sh))" + +| exec_instr_CmpEq: +"exec_instr CmpEq P h stk loc C\<^sub>0 M\<^sub>0 pc ics frs sh = + (None, h, (Bool (hd (tl stk) = hd stk) # tl (tl stk), loc, C\<^sub>0, M\<^sub>0, Suc pc, ics)#frs, sh)" + +| exec_instr_Goto: +"exec_instr (Goto i) P h stk loc C\<^sub>0 M\<^sub>0 pc ics frs sh = + (None, h, (stk, loc, C\<^sub>0, M\<^sub>0, nat(int pc+i), ics)#frs, sh)" + +| exec_instr_Throw: +"exec_instr Throw P h stk loc C\<^sub>0 M\<^sub>0 pc ics frs sh = + (let xp' = if hd stk = Null then \addr_of_sys_xcpt NullPointer\ + else \the_Addr(hd stk)\ + in (xp', h, (stk, loc, C\<^sub>0, M\<^sub>0, pc, ics)#frs, sh))" + + + +text "Given a preallocated heap, a thrown exception is either a system exception or + thrown directly by @{term Throw}." +lemma exec_instr_xcpts: +assumes "\' = exec_instr i P h stk loc C M pc ics' frs sh" + and "fst \' = Some a" +shows "i = (JVMInstructions.Throw) \ a \ {a. \x \ sys_xcpts. a = addr_of_sys_xcpt x}" +using assms +proof(cases i) + case (New C1) then show ?thesis using assms + proof(cases "sh C1") + case (Some a) + then obtain sfs i where sfsi: "a = (sfs,i)" by(cases a) + then show ?thesis using Some New assms + proof(cases i) qed(cases ics', auto)+ + qed(cases ics', auto) +next + case (Getfield F1 C1) + obtain D' b t where field: "field P C1 F1 = (D',b,t)" by(cases "field P C1 F1") + obtain D fs where addr: "the (h (the_Addr (hd stk))) = (D,fs)" by(cases "the (h (the_Addr (hd stk)))") + show ?thesis using addr field Getfield assms + proof(cases "hd stk = Null") + case nNull:False then show ?thesis using addr field Getfield assms + proof(cases "\t b. P \ (cname_of h (the_Addr (hd stk))) has F1,b:t in C1") + case exists:False show ?thesis + proof(cases "fst(snd(field P C1 F1))") + case Static + then show ?thesis using exists nNull addr field Getfield assms + by(auto simp: sys_xcpts_def split_beta split: staticb.splits) + next + case NonStatic + then show ?thesis using exists nNull addr field Getfield assms + by(auto simp: sys_xcpts_def split_beta split: staticb.splits) + qed + qed(auto) + qed(auto) +next + case (Getstatic C1 F1 D1) + obtain D' b t where field: "field P D1 F1 = (D',b,t)" by(cases "field P D1 F1") + show ?thesis using field Getstatic assms + proof(cases "\t b. P \ C1 has F1,b:t in D1") + case exists:False then show ?thesis using field Getstatic assms + proof(cases "fst(snd(field P D1 F1))") + case Static + then obtain sfs i where "the(sh D') = (sfs, i)" by(cases "the(sh D')") + then show ?thesis using exists field Static Getstatic assms by(cases ics'; cases i, auto) + qed(auto) + qed(auto) +next + case (Putfield F1 C1) + let ?r = "hd(tl stk)" + obtain D' b t where field: "field P C1 F1 = (D',b,t)" by(cases "field P C1 F1") + obtain D fs where addr: "the (h (the_Addr ?r)) = (D,fs)" + by(cases "the (h (the_Addr ?r))") + show ?thesis using addr field Putfield assms + proof(cases "?r = Null") + case nNull:False then show ?thesis using addr field Putfield assms + proof(cases "\t b. P \ (cname_of h (the_Addr ?r)) has F1,b:t in C1") + case exists:False show ?thesis + proof(cases b) + case Static + then show ?thesis using exists nNull addr field Putfield assms + by(auto simp: sys_xcpts_def split_beta split: staticb.splits) + next + case NonStatic + then show ?thesis using exists nNull addr field Putfield assms + by(auto simp: sys_xcpts_def split_beta split: staticb.splits) + qed + qed(auto) + qed(auto) +next + case (Putstatic C1 F1 D1) + obtain D' b t where field: "field P D1 F1 = (D',b,t)" by(cases "field P D1 F1") + show ?thesis using field Putstatic assms + proof(cases "\t b. P \ C1 has F1,b:t in D1") + case exists:False then show ?thesis using field Putstatic assms + proof(cases b) + case Static + then obtain sfs i where "the(sh D') = (sfs, i)" by(cases "the(sh D')") + then show ?thesis using exists field Static Putstatic assms by(cases ics'; cases i, auto) + qed(auto) + qed(auto) +next + case (Checkcast C1) then show ?thesis using assms by(cases "cast_ok P C1 h (hd stk)", auto) +next + case (Invoke M n) + let ?r = "stk!n" + let ?C = "cname_of h (the_Addr ?r)" + show ?thesis using Invoke assms + proof(cases "?r = Null") + case nNull:False then show ?thesis using Invoke assms + proof(cases "\(\Ts T m D b. P \ ?C sees M,b:Ts \ T = m in D)") + case exists:False then show ?thesis using nNull Invoke assms + proof(cases "fst(snd(method P ?C M))") + case Static + then show ?thesis using exists nNull Invoke assms + by(auto simp: sys_xcpts_def split_beta split: staticb.splits) + next + case NonStatic + then show ?thesis using exists nNull Invoke assms + by(auto simp: sys_xcpts_def split_beta split: staticb.splits) + qed + qed(auto) + qed(auto) +next + case (Invokestatic C1 M n) + show ?thesis using Invokestatic assms + proof(cases "\(\Ts T m D b. P \ C1 sees M,b:Ts \ T = m in D)") + case exists:False then show ?thesis using Invokestatic assms + proof(cases "fst(snd(method P C1 M))") + case Static + then obtain sfs i where "the(sh (fst(method P C1 M))) = (sfs, i)" + by(cases "the(sh (fst(method P C1 M)))") + then show ?thesis using exists Static Invokestatic assms + by(auto split: init_call_status.splits init_state.splits) + qed(auto) + qed(auto) +next + case Return then show ?thesis using assms + proof(cases frs) + case (Cons f frs') then show ?thesis using Return assms + by(cases f, cases "method P C M", cases "M=clinit", auto) + qed(auto) +next + case (IfFalse x17) then show ?thesis using assms + proof(cases "hd stk") + case (Bool b) then show ?thesis using IfFalse assms by(cases b, auto) + qed(auto) +qed(auto) + +lemma exec_instr_prealloc_pres: +assumes "preallocated h" + and "exec_instr i P h stk loc C\<^sub>0 M\<^sub>0 pc ics frs sh = (xp',h',frs',sh')" +shows "preallocated h'" +using assms +proof(cases i) + case (New C1) + then obtain sfs i where sfsi: "the(sh C1) = (sfs,i)" by(cases "the(sh C1)") + then show ?thesis using preallocated_new[of h] New assms + by(cases "blank P C1", auto dest: new_Addr_SomeD split: init_call_status.splits init_state.splits) +next + case (Getfield F1 C1) then show ?thesis using assms + by(cases "the (h (the_Addr (hd stk)))", cases "field P C1 F1", auto) +next + case (Getstatic C1 F1 D1) + then obtain sfs i where sfsi: "the(sh (fst (field P D1 F1))) = (sfs, i)" + by(cases "the(sh (fst (field P D1 F1)))") + then show ?thesis using Getstatic assms + by(cases "field P D1 F1", auto split: init_call_status.splits init_state.splits) +next + case (Putfield F1 C1) then show ?thesis using preallocated_new preallocated_upd_obj assms + by(cases "the (h (the_Addr (hd (tl stk))))", cases "field P C1 F1", auto, metis option.collapse) +next + case (Putstatic C1 F1 D1) + then obtain sfs i where sfsi: "the(sh (fst (field P D1 F1))) = (sfs, i)" + by(cases "the(sh (fst (field P D1 F1)))") + then show ?thesis using Putstatic assms + by(cases "field P D1 F1", auto split: init_call_status.splits init_state.splits) +next + case (Checkcast C1) + then show ?thesis using assms + proof(cases "hd stk = Null") + case False then show ?thesis + using Checkcast assms + by(cases "P \ cname_of h (the_Addr (hd stk)) \\<^sup>* C1", auto simp: cast_ok_def) + qed(simp add: cast_ok_def) +next + case (Invoke M n) + then show ?thesis using assms by(cases "method P (cname_of h (the_Addr (stk ! n))) M", auto) +next + case (Invokestatic C1 M n) + show ?thesis + proof(cases "sh (fst (method P C1 M))") + case None then show ?thesis using Invokestatic assms + by(cases "method P C1 M", auto split: init_call_status.splits) + next + case (Some a) + then obtain sfs i where sfsi: "a = (sfs, i)" by(cases a) + then show ?thesis using Some Invokestatic assms + proof(cases i) qed(cases "method P C1 M", auto split: init_call_status.splits)+ + qed +next + case Return + then show ?thesis using assms by(cases "method P C\<^sub>0 M\<^sub>0", auto simp: split_beta split: list.splits) +next + case (IfFalse x17) then show ?thesis using assms by(auto split: val.splits bool.splits) +next + case Throw then show ?thesis using assms by(auto split: val.splits) +qed(auto) + +end diff --git a/thys/JinjaDCI/JVM/JVMInstructions.thy b/thys/JinjaDCI/JVM/JVMInstructions.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/JVM/JVMInstructions.thy @@ -0,0 +1,64 @@ +(* Title: JinjaDCI/JVM/JVMInstructions.thy + + Author: Gerwin Klein, Susannah Mansky + Copyright 2000 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory JVM/JVMInstructions.thy by Gerwin Klein +*) + +section \ Instructions of the JVM \ + + +theory JVMInstructions imports JVMState begin + + +datatype + instr = Load nat \ \load from local variable\ + | Store nat \ \store into local variable\ + | Push val \ \push a value (constant)\ + | New cname \ \create object\ + | Getfield vname cname \ \Fetch field from object\ + | Getstatic cname vname cname \ \Fetch static field from class\ + | Putfield vname cname \ \Set field in object \ + | Putstatic cname vname cname \ \Set static field in class\ + | Checkcast cname \ \Check whether object is of given type\ + | Invoke mname nat \ \inv. instance meth of an object\ + | Invokestatic cname mname nat \ \inv. static method of a class\ + | Return \ \return from method\ + | Pop \ \pop top element from opstack\ + | IAdd \ \integer addition\ + | Goto int \ \goto relative address\ + | CmpEq \ \equality comparison\ + | IfFalse int \ \branch if top of stack false\ + | Throw \ \throw top of stack as exception\ + +type_synonym + bytecode = "instr list" + +type_synonym + ex_entry = "pc \ pc \ cname \ pc \ nat" + \ \start-pc, end-pc, exception type, handler-pc, remaining stack depth\ + +type_synonym + ex_table = "ex_entry list" + +type_synonym + jvm_method = "nat \ nat \ bytecode \ ex_table" + \ \max stacksize\ + \ \number of local variables. Add 1 + no. of parameters to get no. of registers\ + \ \instruction sequence\ + \ \exception handler table\ + +type_synonym + jvm_prog = "jvm_method prog" + +(*<*) +translations + (type) "bytecode" <= (type) "instr list" + (type) "ex_entry" <= (type) "nat \ nat \ char list \ nat \ nat" + (type) "ex_table" <= (type) "ex_entry list" + (type) "jvm_method" <= (type) "nat \ nat \ bytecode \ ex_table" + (type) "jvm_prog" <= (type) "jvm_method prog" +(*>*) + +end diff --git a/thys/JinjaDCI/JVM/JVMState.thy b/thys/JinjaDCI/JVM/JVMState.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/JVM/JVMState.thy @@ -0,0 +1,84 @@ +(* Title: Jinja/JVM/JVMState.thy + + Author: Cornelia Pusch, Gerwin Klein, Susannah Mansky + Copyright 1999 Technische Universitaet Muenchen, 2019-20 UIUC + + Based on the Jinja theory JVM/JVMState.thy by Cornelia Pusch and Gerwin Klein +*) + +chapter \ Jinja Virtual Machine \label{cha:jvm} \ + +section \ State of the JVM \ + +theory JVMState imports "../Common/Objects" begin + + +type_synonym + pc = nat + +abbreviation start_sheap :: "sheap" +where "start_sheap \ (\x. None)(Start \ (Map.empty,Done))" + +definition start_sheap_preloaded :: "'m prog \ sheap" +where + "start_sheap_preloaded P \ fold (\(C,cl) f. f(C := Some (sblank P C, Prepared))) P (\x. None)" + +subsection \ Frame Stack \ + +datatype init_call_status = No_ics | Calling cname "cname list" + | Called "cname list" | Throwing "cname list" addr + \ \@{text "No_ics"} = not currently calling or waiting for the result of an initialization procedure call\ + \ \@{text "Calling C Cs"} = current instruction is calling for initialization of classes @{text "C#Cs"} (last class + is the original) -- still collecting classes to be initialized, @{text "C"} most recently collected\ + \ \@{text "Called Cs"} = current instruction called initialization and is waiting for the result + -- now initializing classes in the list\ + \ \@{text "Throwing Cs a"} = frame threw or was thrown an error causing erroneous end of initialization + procedure for classes @{text "Cs"}\ + +type_synonym + frame = "val list \ val list \ cname \ mname \ pc \ init_call_status" + \ \operand stack\ + \ \registers (including this pointer, method parameters, and local variables)\ + \ \name of class where current method is defined\ + \ \current method\ + \ \program counter within frame\ + \ \indicates frame's initialization call status\ + +translations + (type) "frame" <= (type) "val list \ val list \ char list \ char list \ nat \ init_call_status" + +fun curr_stk :: "frame \ val list" where +"curr_stk (stk, loc, C, M, pc, ics) = stk" + +fun curr_class :: "frame \ cname" where +"curr_class (stk, loc, C, M, pc, ics) = C" + +fun curr_method :: "frame \ mname" where +"curr_method (stk, loc, C, M, pc, ics) = M" + +fun curr_pc :: "frame \ nat" where +"curr_pc (stk, loc, C, M, pc, ics) = pc" + +fun init_status :: "frame \ init_call_status" where + "init_status (stk, loc, C, M, pc, ics) = ics" + +fun ics_of :: "frame \ init_call_status" where + "ics_of fr = snd(snd(snd(snd(snd fr))))" + + +subsection \ Runtime State \ + +type_synonym + jvm_state = "addr option \ heap \ frame list \ sheap" + \ \exception flag, heap, frames, static heap\ + +translations + (type) "jvm_state" <= (type) "nat option \ heap \ frame list \ sheap" + +fun frames_of :: "jvm_state \ frame list" where +"frames_of (xp, h, frs, sh) = frs" + +abbreviation sheap :: "jvm_state \ sheap" where +"sheap js \ snd (snd (snd js))" + +end diff --git a/thys/JinjaDCI/JinjaDCI.thy b/thys/JinjaDCI/JinjaDCI.thy new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/JinjaDCI.thy @@ -0,0 +1,12 @@ +theory JinjaDCI +imports + "J/Equivalence" + "J/Annotate" + "JVM/JVMDefensive" + "BV/BVExec" + "BV/LBVJVM" + "BV/BVNoTypeError" + "Compiler/TypeComp" +begin + +end diff --git a/thys/JinjaDCI/ROOT b/thys/JinjaDCI/ROOT new file mode 100644 --- /dev/null +++ b/thys/JinjaDCI/ROOT @@ -0,0 +1,18 @@ +chapter AFP + +session JinjaDCI (AFP) = "HOL-Library" + + options [timeout = 1200, document = pdf] + sessions + "List-Index" + "Jinja" + directories + "BV" + "Common" + "Compiler" + "J" + "JVM" + theories + JinjaDCI + document_files + "root.bib" + "root.tex" diff --git a/thys/JinjaDCI/document/root.bib b/thys/JinjaDCI/document/root.bib new file mode 100755 --- /dev/null +++ b/thys/JinjaDCI/document/root.bib @@ -0,0 +1,16 @@ +@inproceedings{mansky2019dynamic, +author = {Mansky, Susannah and Gunter, Elsa L.}, +title = {Dynamic Class Initialization Semantics: A Jinja Extension}, +year = {2019}, +isbn = {9781450362221}, +publisher = {Association for Computing Machinery}, +address = {New York, NY, USA}, +url = {https://doi.org/10.1145/3293880.3294104}, +doi = {10.1145/3293880.3294104}, +booktitle = {Proceedings of the 8th ACM SIGPLAN International Conference on Certified Programs and Proofs}, +pages = {209–221}, +numpages = {13}, +keywords = {type safety, compilation, interactive theorem proving, Java, dynamic class initialization, operational semantics, Java Virtual Machine}, +location = {Cascais, Portugal}, +series = {CPP 2019} +} \ No newline at end of file diff --git a/thys/JinjaDCI/document/root.tex b/thys/JinjaDCI/document/root.tex new file mode 100644 --- /dev/null +++ b/thys/JinjaDCI/document/root.tex @@ -0,0 +1,74 @@ +%\documentclass[11pt,a4paper]{article} +\documentclass[11pt,a4paper]{book} +\usepackage[english]{babel} +\usepackage{graphicx,latexsym,isabelle,isabellesym,amssymb,pdfsetup} + +% proper setup for best-style documents +\urlstyle{rm} +\isabellestyle{it} + +\pagestyle{myheadings} + +%make a bit more space +\addtolength{\hoffset}{-1,5cm} +\addtolength{\textwidth}{3cm} +\addtolength{\voffset}{-1cm} +\addtolength{\textheight}{2cm} + +\renewcommand{\setisabellecontext}[1]{\markright{Theory~#1}} + +\newcommand{\secref}[1]{Section~\ref{#1}} +\newcommand{\secrefs}[1]{Sections~\ref{#1}} +\newcommand{\charef}[1]{Chapter~\ref{#1}} +\newcommand{\charefs}[1]{Chapters~\ref{#1}} + +%remove clutter from the toc +\setcounter{secnumdepth}{2} +\setcounter{tocdepth}{1} + +\begin{document} + +\title{JinjaDCI: a Java semantics with dynamic class initialization} +\author{Susannah Mansky} +\maketitle + +%\begin{abstract} +%((FIXME: add abstract)) +%\end{abstract} +\begin{trivlist} +\item \textbf{Abstract.} +This work is an extension of the Jinja semantics for Java and the JVM by Klein and Nipkow to include static fields and methods and dynamic class initialization. +In Java, class initialization methods are run dynamically, called when classes are first used. Such calls are handled by the running of an initialization procedure, which interrupts execution and determines which initialization methods must be run before execution continues. This interrupting is modeled here in a couple of ways. +In the Java semantics, evaluation is performed via expressions that are manipulated through evaluation until a final value is reached. In JinjaDCI, we have added two types of initialization expressions whose evaluations produce the steps of the initialization procedure. These expressions can occur during evaluation and store the calling expression away to continue being evaluated once the procedure is complete. +In the JVM semantics, since programs are static sequences of instructions, the initialization procedure is run instead by the execution function. This function performs steps of the procedure rather than calling instructions when the initialization procedure has been called. + +This extension includes the necessary updates to all major proofs from the original Jinja, including type safety and correctness of compilation from the Java semantics to the JVM semantics. + +This work is partially described in \cite{mansky2019dynamic}. +\end{trivlist} + + +\tableofcontents + +%\section{Theory Dependencies} + +%Figure \ref{theory-deps} shows the dependencies between +%the Isabelle theories in the following sections. + +%\begin{figure}[h!t] +%\begin{center} +% \includegraphics[width=\textwidth]{session_graph} +%\end{center} +%\caption{Theory Dependency Graph\label{theory-deps}} +%\end{figure} + +\clearpage +\input{session} + +%\newpage +%\nocite{*} +\bibliographystyle{abbrv} +%\bibliographystyle{plain} +\bibliography{root} + +\end{document} diff --git a/thys/ROOTS b/thys/ROOTS --- a/thys/ROOTS +++ b/thys/ROOTS @@ -1,580 +1,581 @@ ADS_Functor AI_Planning_Languages_Semantics AODV AVL-Trees AWN Abortable_Linearizable_Modules Abs_Int_ITP2012 Abstract-Hoare-Logics Abstract-Rewriting Abstract_Completeness Abstract_Soundness Adaptive_State_Counting Affine_Arithmetic Aggregation_Algebras Akra_Bazzi Algebraic_Numbers Algebraic_VCs Allen_Calculus Amicable_Numbers Amortized_Complexity AnselmGod Applicative_Lifting Approximation_Algorithms Architectural_Design_Patterns Aristotles_Assertoric_Syllogistic Arith_Prog_Rel_Primes ArrowImpossibilityGS Attack_Trees Auto2_HOL Auto2_Imperative_HOL AutoFocus-Stream Automated_Stateful_Protocol_Verification Automatic_Refinement AxiomaticCategoryTheory BDD BNF_CC BNF_Operations Banach_Steinhaus Bell_Numbers_Spivey Berlekamp_Zassenhaus Bernoulli Bertrands_Postulate Bicategory BinarySearchTree Binding_Syntax_Theory Binomial-Heaps Binomial-Queues BirdKMP Bondy Boolean_Expression_Checkers Bounded_Deducibility_Security Buchi_Complementation Budan_Fourier Buffons_Needle Buildings BytecodeLogicJmlTypes C2KA_DistributedSystems CAVA_Automata CAVA_LTL_Modelchecker CCS CISC-Kernel CRDT CYK CakeML CakeML_Codegen Call_Arity Card_Equiv_Relations Card_Multisets Card_Number_Partitions Card_Partitions Cartan_FP Case_Labeling Catalan_Numbers Category Category2 Category3 Cauchy Cayley_Hamilton Certification_Monads Chandy_Lamport Chord_Segments Circus Clean ClockSynchInst Closest_Pair_Points CofGroups Coinductive Coinductive_Languages Collections Comparison_Sort_Lower_Bound Compiling-Exceptions-Correctly Complete_Non_Orders Completeness Complex_Geometry Complx ComponentDependencies ConcurrentGC ConcurrentIMP Concurrent_Ref_Alg Concurrent_Revisions Consensus_Refined Constructive_Cryptography Constructor_Funs Containers CoreC++ Core_DOM Core_SC_DOM Count_Complex_Roots CryptHOL CryptoBasedCompositionalProperties CSP_RefTK DFS_Framework DPT-SAT-Solver DataRefinementIBP Datatype_Order_Generator Decl_Sem_Fun_PL Decreasing-Diagrams Decreasing-Diagrams-II Deep_Learning Delta_System_Lemma Density_Compiler Dependent_SIFUM_Refinement Dependent_SIFUM_Type_Systems Depth-First-Search Derangements Deriving Descartes_Sign_Rule Dict_Construction Differential_Dynamic_Logic Differential_Game_Logic Dijkstra_Shortest_Path Diophantine_Eqns_Lin_Hom Dirichlet_L Dirichlet_Series DiscretePricing Discrete_Summation DiskPaxos DOM_Components DynamicArchitectures Dynamic_Tables E_Transcendental Echelon_Form EdmondsKarp_Maxflow Efficient-Mergesort Elliptic_Curves_Group_Law Encodability_Process_Calculi Epistemic_Logic Ergodic_Theory Error_Function Euler_MacLaurin Euler_Partition Example-Submission Extended_Finite_State_Machine_Inference Extended_Finite_State_Machines FFT FLP FOL-Fitting FOL_Harrison FOL_Seq_Calc1 Factored_Transition_System_Bounding Falling_Factorial_Sum Farkas FeatherweightJava Featherweight_OCL Fermat3_4 FileRefinement FinFun Finger-Trees Finite-Map-Extras Finite_Automata_HF First_Order_Terms First_Welfare_Theorem Fishburn_Impossibility Fisher_Yates Flow_Networks Floyd_Warshall Flyspeck-Tame FocusStreamsCaseStudies Forcing Formal_SSA Formula_Derivatives Fourier Free-Boolean-Algebra Free-Groups FunWithFunctions FunWithTilings Functional-Automata Functional_Ordered_Resolution_Prover Furstenberg_Topology GPU_Kernel_PL Gabow_SCC Game_Based_Crypto Gauss-Jordan-Elim-Fun Gauss_Jordan Gauss_Sums Gaussian_Integers GenClock General-Triangle Generalized_Counting_Sort Generic_Deriving Generic_Join GewirthPGCProof Girth_Chromatic GoedelGod Goedel_HFSet_Semantic Goedel_HFSet_Semanticless Goedel_Incompleteness Goodstein_Lambda GraphMarkingIBP Graph_Saturation Graph_Theory Green Groebner_Bases Groebner_Macaulay Gromov_Hyperbolicity Group-Ring-Module HOL-CSP HOLCF-Prelude HRB-Slicing Heard_Of Hello_World HereditarilyFinite Hermite Hidden_Markov_Models Higher_Order_Terms Hoare_Time Hood_Melville_Queue HotelKeyCards Huffman Hybrid_Logic Hybrid_Multi_Lane_Spatial_Logic Hybrid_Systems_VCs HyperCTL IEEE_Floating_Point IMAP-CRDT IMO2019 IMP2 IMP2_Binary_Heap IP_Addresses Imperative_Insertion_Sort Impossible_Geometry Incompleteness Incredible_Proof_Machine Inductive_Confidentiality Inductive_Inference InfPathElimination InformationFlowSlicing InformationFlowSlicing_Inter Integration Interpreter_Optimizations Interval_Arithmetic_Word32 Iptables_Semantics Irrational_Series_Erdos_Straus Irrationality_J_Hancl Isabelle_C Isabelle_Marries_Dirac Isabelle_Meta_Model Jacobson_Basic_Algebra Jinja +JinjaDCI JinjaThreads JiveDataStoreModel Jordan_Hoelder Jordan_Normal_Form KAD KAT_and_DRA KBPs KD_Tree Key_Agreement_Strong_Adversaries Kleene_Algebra Knuth_Bendix_Order Knot_Theory Knuth_Bendix_Order Knuth_Morris_Pratt Koenigsberg_Friendship Kruskal Kuratowski_Closure_Complement LLL_Basis_Reduction LLL_Factorization LOFT LTL LTL_Master_Theorem LTL_Normal_Form LTL_to_DRA LTL_to_GBA Lam-ml-Normalization LambdaAuth LambdaMu Lambda_Free_EPO Lambda_Free_KBOs Lambda_Free_RPOs Lambert_W Landau_Symbols Laplace_Transform Latin_Square LatticeProperties Launchbury Lazy-Lists-II Lazy_Case Lehmer Lifting_Definition_Option LightweightJava LinearQuantifierElim Linear_Inequalities Linear_Programming Linear_Recurrences Liouville_Numbers List-Index List-Infinite List_Interleaving List_Inversions List_Update LocalLexing Localization_Ring Locally-Nameless-Sigma Lowe_Ontological_Argument Lower_Semicontinuous Lp Lucas_Theorem MFMC_Countable MFODL_Monitor_Optimized MFOTL_Monitor MSO_Regex_Equivalence Markov_Models Marriage Mason_Stothers Matrices_for_ODEs Matrix Matrix_Tensor Matroids Max-Card-Matching Median_Of_Medians_Selection Menger Mersenne_Primes MiniML Minimal_SSA Minkowskis_Theorem Minsky_Machines Modal_Logics_for_NTS Modular_Assembly_Kit_Security Monad_Memo_DP Monad_Normalisation MonoBoolTranAlgebra MonoidalCategory Monomorphic_Monad MuchAdoAboutTwo Multi_Party_Computation Multirelations Myhill-Nerode Name_Carrying_Type_Inference Nash_Williams Nat-Interval-Logic Native_Word Nested_Multisets_Ordinals Network_Security_Policy_Verification Neumann_Morgenstern_Utility No_FTL_observers Nominal2 Noninterference_CSP Noninterference_Concurrent_Composition Noninterference_Generic_Unwinding Noninterference_Inductive_Unwinding Noninterference_Ipurge_Unwinding Noninterference_Sequential_Composition NormByEval Nullstellensatz Octonions OpSets Open_Induction Optics Optimal_BST Orbit_Stabiliser Order_Lattice_Props Ordered_Resolution_Prover Ordinal Ordinal_Partitions Ordinals_and_Cardinals Ordinary_Differential_Equations PAC_Checker PCF PLM POPLmark-deBruijn PSemigroupsConvolution Pairing_Heap Paraconsistency Parity_Game Partial_Function_MR Partial_Order_Reduction Password_Authentication_Protocol Pell Perfect-Number-Thm Perron_Frobenius Physical_Quantities Pi_Calculus Pi_Transcendental Planarity_Certificates Poincare_Bendixson Poincare_Disc Polynomial_Factorization Polynomial_Interpolation Polynomials Pop_Refinement Posix-Lexing Possibilistic_Noninterference Power_Sum_Polynomials Pratt_Certificate Presburger-Automata Prim_Dijkstra_Simple Prime_Distribution_Elementary Prime_Harmonic_Series Prime_Number_Theorem Priority_Queue_Braun Priority_Search_Trees Probabilistic_Noninterference Probabilistic_Prime_Tests Probabilistic_System_Zoo Probabilistic_Timed_Automata Probabilistic_While Program-Conflict-Analysis Projective_Geometry Promela Proof_Strategy_Language PropResPI Propositional_Proof_Systems Prpu_Maxflow PseudoHoops Psi_Calculi Ptolemys_Theorem QHLProver QR_Decomposition Quantales Quaternions Quick_Sort_Cost RIPEMD-160-SPARK ROBDD RSAPSS Ramsey-Infinite Random_BSTs Random_Graph_Subgraph_Threshold Randomised_BSTs Randomised_Social_Choice Rank_Nullity_Theorem Real_Impl Recursion-Addition Recursion-Theory-I Refine_Imperative_HOL Refine_Monadic RefinementReactive Regex_Equivalence Regular-Sets Regular_Algebras Relation_Algebra Relational-Incorrectness-Logic Relational_Disjoint_Set_Forests Relational_Method Relational_Minimum_Spanning_Trees Relational_Paths Rep_Fin_Groups Residuated_Lattices Resolution_FOL Rewriting_Z Ribbon_Proofs Robbins-Conjecture Robinson_Arithmetic Root_Balanced_Tree Routing Roy_Floyd_Warshall SATSolverVerification SC_DOM_Components SDS_Impossibility SIFPL SIFUM_Type_Systems SPARCv8 Safe_Distance Safe_OCL Saturation_Framework Saturation_Framework_Extensions Shadow_DOM Secondary_Sylow Security_Protocol_Refinement Selection_Heap_Sort SenSocialChoice Separata Separation_Algebra Separation_Logic_Imperative_HOL SequentInvertibility Shadow_SC_DOM Shivers-CFA ShortestPath Show Sigma_Commit_Crypto Signature_Groebner Simpl Simple_Firewall Simplex Skew_Heap Skip_Lists Slicing Sliding_Window_Algorithm Smith_Normal_Form Smooth_Manifolds Sort_Encodings Source_Coding_Theorem Special_Function_Bounds Splay_Tree Sqrt_Babylonian Stable_Matching Statecharts Stateful_Protocol_Composition_and_Typing Stellar_Quorums Stern_Brocot Stewart_Apollonius Stirling_Formula Stochastic_Matrices Stone_Algebras Stone_Kleene_Relation_Algebras Stone_Relation_Algebras Store_Buffer_Reduction Stream-Fusion Stream_Fusion_Code Strong_Security Sturm_Sequences Sturm_Tarski Stuttering_Equivalence Subresultants Subset_Boolean_Algebras SumSquares SuperCalc Surprise_Paradox Symmetric_Polynomials Syntax_Independent_Logic Szpilrajn TESL_Language TLA Tail_Recursive_Functions Tarskis_Geometry Taylor_Models Timed_Automata Topological_Semantics Topology TortoiseHare Transcendence_Series_Hancl_Rucki Transformer_Semantics Transition_Systems_and_Automata Transitive-Closure Transitive-Closure-II Treaps Tree-Automata Tree_Decomposition Triangle Trie Twelvefold_Way Tycon Types_Tableaus_and_Goedels_God UPF UPF_Firewall UTP Universal_Turing_Machine UpDown_Scheme Valuation VectorSpace VeriComp Verified-Prover Verified_SAT_Based_AI_Planning VerifyThis2018 VerifyThis2019 Vickrey_Clarke_Groves VolpanoSmith WHATandWHERE_Security WOOT_Strong_Eventual_Consistency WebAssembly Weight_Balanced_Trees Well_Quasi_Orders Winding_Number_Eval Word_Lib WorkerWrapper XML ZFC_in_HOL Zeta_3_Irrational Zeta_Function pGCL diff --git a/web/entries/Jinja.html b/web/entries/Jinja.html --- a/web/entries/Jinja.html +++ b/web/entries/Jinja.html @@ -1,289 +1,289 @@ Jinja is not Java - Archive of Formal Proofs

 

 

 

 

 

 

Jinja is not Java

 

- +
Title: Jinja is not Java
Authors: Gerwin Klein and Tobias Nipkow
Submission date: 2005-06-01
Abstract: We introduce Jinja, a Java-like programming language with a formal semantics designed to exhibit core features of the Java language architecture. Jinja is a compromise between realism of the language and tractability and clarity of the formal semantics. The following aspects are formalised: a big and a small step operational semantics for Jinja and a proof of their equivalence; a type system and a definite initialisation analysis; a type safety proof of the small step semantics; a virtual machine (JVM), its operational semantics and its type system; a type safety proof for the JVM; a bytecode verifier, i.e. data flow analyser for the JVM; a correctness proof of the bytecode verifier w.r.t. the type system; a compiler and a proof that it preserves semantics and well-typedness. The emphasis of this work is not on particular language features but on providing a unified model of the source language, the virtual machine and the compiler. The whole development has been carried out in the theorem prover Isabelle/HOL.
BibTeX:
@article{Jinja-AFP,
   author  = {Gerwin Klein and Tobias Nipkow},
   title   = {Jinja is not Java},
   journal = {Archive of Formal Proofs},
   month   = jun,
   year    = 2005,
   note    = {\url{https://isa-afp.org/entries/Jinja.html},
             Formal proof development},
   ISSN    = {2150-914x},
 }
License: BSD License
Depends on: List-Index
Used by:HRB-Slicing, Slicing
HRB-Slicing, JinjaDCI, Slicing

\ No newline at end of file diff --git a/web/entries/JinjaDCI.html b/web/entries/JinjaDCI.html new file mode 100644 --- /dev/null +++ b/web/entries/JinjaDCI.html @@ -0,0 +1,198 @@ + + + + +JinjaDCI: a Java semantics with dynamic class initialization - Archive of Formal Proofs + + + + + + + + + + + + + + + + + + + + + + + + +
+

 

+ + + +

 

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

 

+

 

+
+
+

 

+

JinjaDCI: + + a + + Java + + semantics + + with + + dynamic + + class + + initialization + +

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Title:JinjaDCI: a Java semantics with dynamic class initialization
+ Author: + + Susannah Mansky (sjohnsn2 /at/ illinois /dot/ edu) +
Submission date:2021-01-11
Abstract: +We extend Jinja to include static fields, methods, and instructions, +and dynamic class initialization, based on the Java SE 8 +specification. This includes extension of definitions and proofs. This +work is partially described in Mansky and Gunter's paper at CPP +2019 and Mansky's doctoral thesis (UIUC, 2020).
BibTeX: +
@article{JinjaDCI-AFP,
+  author  = {Susannah Mansky},
+  title   = {JinjaDCI: a Java semantics with dynamic class initialization},
+  journal = {Archive of Formal Proofs},
+  month   = jan,
+  year    = 2021,
+  note    = {\url{https://isa-afp.org/entries/JinjaDCI.html},
+            Formal proof development},
+  ISSN    = {2150-914x},
+}
+
License:BSD License
Depends on:Jinja, List-Index
+ +

+ + + + + + + + + + + + + + + + + + +
+
+ + + + + + \ No newline at end of file diff --git a/web/entries/List-Index.html b/web/entries/List-Index.html --- a/web/entries/List-Index.html +++ b/web/entries/List-Index.html @@ -1,257 +1,257 @@ List Index - Archive of Formal Proofs

 

 

 

 

 

 

List Index

 

- +
Title: List Index
Author: Tobias Nipkow
Submission date: 2010-02-20
Abstract: This theory provides functions for finding the index of an element in a list, by predicate and by value.
BibTeX:
@article{List-Index-AFP,
   author  = {Tobias Nipkow},
   title   = {List Index},
   journal = {Archive of Formal Proofs},
   month   = feb,
   year    = 2010,
   note    = {\url{https://isa-afp.org/entries/List-Index.html},
             Formal proof development},
   ISSN    = {2150-914x},
 }
License: BSD License
Used by:Affine_Arithmetic, Comparison_Sort_Lower_Bound, Formula_Derivatives, Higher_Order_Terms, Jinja, List_Update, LTL_to_DRA, MSO_Regex_Equivalence, Nested_Multisets_Ordinals, Ordinary_Differential_Equations, Planarity_Certificates, Quick_Sort_Cost, Randomised_Social_Choice, Refine_Imperative_HOL, Smith_Normal_Form, Verified_SAT_Based_AI_Planning
Affine_Arithmetic, Comparison_Sort_Lower_Bound, Formula_Derivatives, Higher_Order_Terms, Jinja, JinjaDCI, List_Update, LTL_to_DRA, MSO_Regex_Equivalence, Nested_Multisets_Ordinals, Ordinary_Differential_Equations, Planarity_Certificates, Quick_Sort_Cost, Randomised_Social_Choice, Refine_Imperative_HOL, Smith_Normal_Form, Verified_SAT_Based_AI_Planning

\ No newline at end of file diff --git a/web/index.html b/web/index.html --- a/web/index.html +++ b/web/index.html @@ -1,5308 +1,5316 @@ Archive of Formal Proofs

 

 

 

 

 

 

Archive of Formal Proofs

 

The Archive of Formal Proofs is a collection of proof libraries, examples, and larger scientific developments, mechanically checked in the theorem prover Isabelle. It is organized in the way of a scientific journal, is indexed by dblp and has an ISSN: 2150-914x. Submissions are refereed. The preferred citation style is available [here]. We encourage companion AFP submissions to conference and journal publications.

A development version of the archive is available as well.

 

 

+ + +
2021
2021-01-18: Hood-Melville Queue
Author: Alejandro Gómez-Londoño
+ 2021-01-11: JinjaDCI: a Java semantics with dynamic class initialization +
+ Author: + Susannah Mansky +

 

2020
2020-12-27: Cofinality and the Delta System Lemma
Author: Pedro Sánchez Terraf
2020-12-17: Topological semantics for paraconsistent and paracomplete logics
Author: David Fuenmayor
2020-12-08: Relational Minimum Spanning Tree Algorithms
Authors: Walter Guttmann and Nicolas Robinson-O'Brien
2020-12-07: Inline Caching and Unboxing Optimization for Interpreters
Author: Martin Desharnais
2020-12-05: The Relational Method with Message Anonymity for the Verification of Cryptographic Protocols
Author: Pasquale Noce
2020-11-22: Isabelle Marries Dirac: a Library for Quantum Computation and Quantum Information
Authors: Anthony Bordg, Hanna Lachnitt and Yijun He
2020-11-19: The HOL-CSP Refinement Toolkit
Authors: Safouan Taha, Burkhart Wolff and Lina Ye
2020-10-29: Verified SAT-Based AI Planning
Authors: Mohammad Abdulaziz and Friedrich Kurz
2020-10-29: AI Planning Languages Semantics
Authors: Mohammad Abdulaziz and Peter Lammich
2020-10-20: A Sound Type System for Physical Quantities, Units, and Measurements
Authors: Simon Foster and Burkhart Wolff
2020-10-12: Finite Map Extras
Author: Javier Díaz
2020-09-28: A Formal Model of the Safely Composable Document Object Model with Shadow Roots
Authors: Achim D. Brucker and Michael Herzberg
2020-09-28: A Formal Model of the Document Object Model with Shadow Roots
Authors: Achim D. Brucker and Michael Herzberg
2020-09-28: A Formalization of Safely Composable Web Components
Authors: Achim D. Brucker and Michael Herzberg
2020-09-28: A Formalization of Web Components
Authors: Achim D. Brucker and Michael Herzberg
2020-09-28: The Safely Composable DOM
Authors: Achim D. Brucker and Michael Herzberg
2020-09-16: Syntax-Independent Logic Infrastructure
Authors: Andrei Popescu and Dmitriy Traytel
2020-09-16: Robinson Arithmetic
Authors: Andrei Popescu and Dmitriy Traytel
2020-09-16: An Abstract Formalization of Gödel's Incompleteness Theorems
Authors: Andrei Popescu and Dmitriy Traytel
2020-09-16: From Abstract to Concrete Gödel's Incompleteness Theorems—Part II
Authors: Andrei Popescu and Dmitriy Traytel
2020-09-16: From Abstract to Concrete Gödel's Incompleteness Theorems—Part I
Authors: Andrei Popescu and Dmitriy Traytel
2020-09-07: A Formal Model of Extended Finite State Machines
Authors: Michael Foster, Achim D. Brucker, Ramsay G. Taylor and John Derrick
2020-09-07: Inference of Extended Finite State Machines
Authors: Michael Foster, Achim D. Brucker, Ramsay G. Taylor and John Derrick
2020-08-31: Practical Algebraic Calculus Checker
Authors: Mathias Fleury and Daniela Kaufmann
2020-08-31: Some classical results in inductive inference of recursive functions
Author: Frank J. Balbach
2020-08-26: Relational Disjoint-Set Forests
Author: Walter Guttmann
2020-08-25: Extensions to the Comprehensive Framework for Saturation Theorem Proving
Authors: Jasmin Blanchette and Sophie Tourret
2020-08-25: Putting the `K' into Bird's derivation of Knuth-Morris-Pratt string matching
Author: Peter Gammie
2020-08-04: Amicable Numbers
Author: Angeliki Koutsoukou-Argyraki
2020-08-03: Ordinal Partitions
Author: Lawrence C. Paulson
2020-07-21: A Formal Proof of The Chandy--Lamport Distributed Snapshot Algorithm
Authors: Ben Fiedler and Dmitriy Traytel
2020-07-13: Relational Characterisations of Paths
Authors: Walter Guttmann and Peter Höfner
2020-06-01: A Formally Verified Checker of the Safe Distance Traffic Rules for Autonomous Vehicles
Authors: Albert Rizaldi and Fabian Immler
2020-05-23: A verified algorithm for computing the Smith normal form of a matrix
Author: Jose Divasón
2020-05-16: The Nash-Williams Partition Theorem
Author: Lawrence C. Paulson
2020-05-13: A Formalization of Knuth–Bendix Orders
Authors: Christian Sternagel and René Thiemann
2020-05-12: Irrationality Criteria for Series by Erdős and Straus
Authors: Angeliki Koutsoukou-Argyraki and Wenda Li
2020-05-11: Recursion Theorem in ZF
Author: Georgy Dunaev
2020-05-08: An Efficient Normalisation Procedure for Linear Temporal Logic: Isabelle/HOL Formalisation
Author: Salomon Sickert
2020-05-06: Formalization of Forcing in Isabelle/ZF
Authors: Emmanuel Gunther, Miguel Pagano and Pedro Sánchez Terraf
2020-05-02: Banach-Steinhaus Theorem
Authors: Dominique Unruh and Jose Manuel Rodriguez Caballero
2020-04-27: Attack Trees in Isabelle for GDPR compliance of IoT healthcare systems
Author: Florian Kammueller
2020-04-24: Power Sum Polynomials
Author: Manuel Eberl
2020-04-24: The Lambert W Function on the Reals
Author: Manuel Eberl
2020-04-24: Gaussian Integers
Author: Manuel Eberl
2020-04-19: Matrices for ODEs
Author: Jonathan Julian Huerta y Munive
2020-04-16: Authenticated Data Structures As Functors
Authors: Andreas Lochbihler and Ognjen Marić
2020-04-10: Formalization of an Algorithm for Greedily Computing Associative Aggregations on Sliding Windows
Authors: Lukas Heimes, Dmitriy Traytel and Joshua Schneider
2020-04-09: A Comprehensive Framework for Saturation Theorem Proving
Author: Sophie Tourret
2020-04-09: Formalization of an Optimized Monitoring Algorithm for Metric First-Order Dynamic Logic with Aggregations
Authors: Thibault Dardinier, Lukas Heimes, Martin Raszyk, Joshua Schneider and Dmitriy Traytel
2020-04-08: Stateful Protocol Composition and Typing
Authors: Andreas V. Hess, Sebastian Mödersheim and Achim D. Brucker
2020-04-08: Automated Stateful Protocol Verification
Authors: Andreas V. Hess, Sebastian Mödersheim, Achim D. Brucker and Anders Schlichtkrull
2020-04-07: Lucas's Theorem
Author: Chelsea Edmonds
2020-03-25: Strong Eventual Consistency of the Collaborative Editing Framework WOOT
Authors: Emin Karayel and Edgar Gonzàlez
2020-03-22: Furstenberg's topology and his proof of the infinitude of primes
Author: Manuel Eberl
2020-03-12: An Under-Approximate Relational Logic
Author: Toby Murray
2020-03-07: Hello World
Authors: Cornelius Diekmann and Lars Hupel
2020-02-21: Implementing the Goodstein Function in λ-Calculus
Author: Bertram Felgenhauer
2020-02-10: A Generic Framework for Verified Compilers
Author: Martin Desharnais
2020-02-01: Arithmetic progressions and relative primes
Author: José Manuel Rodríguez Caballero
2020-01-31: A Hierarchy of Algebras for Boolean Subsets
Authors: Walter Guttmann and Bernhard Möller
2020-01-17: Mersenne primes and the Lucas–Lehmer test
Author: Manuel Eberl
2020-01-16: Verified Approximation Algorithms
Authors: Robin Eßmann, Tobias Nipkow and Simon Robillard
2020-01-13: Closest Pair of Points Algorithms
Authors: Martin Rau and Tobias Nipkow
2020-01-09: Skip Lists
Authors: Max W. Haslbeck and Manuel Eberl
2020-01-06: Bicategories
Author: Eugene W. Stark

 

2019
2019-12-27: The Irrationality of ζ(3)
Author: Manuel Eberl
2019-12-20: Formalizing a Seligman-Style Tableau System for Hybrid Logic
Author: Asta Halkjær From
2019-12-18: The Poincaré-Bendixson Theorem
Authors: Fabian Immler and Yong Kiam Tan
2019-12-16: Poincaré Disc Model
Authors: Danijela Simić, Filip Marić and Pierre Boutry
2019-12-16: Complex Geometry
Authors: Filip Marić and Danijela Simić
2019-12-10: Gauss Sums and the Pólya–Vinogradov Inequality
Authors: Rodrigo Raya and Manuel Eberl
2019-12-04: An Efficient Generalization of Counting Sort for Large, possibly Infinite Key Ranges
Author: Pasquale Noce
2019-11-27: Interval Arithmetic on 32-bit Words
Author: Brandon Bohrer
2019-10-24: Zermelo Fraenkel Set Theory in Higher-Order Logic
Author: Lawrence C. Paulson
2019-10-22: Isabelle/C
Authors: Frédéric Tuong and Burkhart Wolff
2019-10-16: VerifyThis 2019 -- Polished Isabelle Solutions
Authors: Peter Lammich and Simon Wimmer
2019-10-08: Aristotle's Assertoric Syllogistic
Author: Angeliki Koutsoukou-Argyraki
2019-10-07: Sigma Protocols and Commitment Schemes
Authors: David Butler and Andreas Lochbihler
2019-10-04: Clean - An Abstract Imperative Programming Language and its Theory
Authors: Frédéric Tuong and Burkhart Wolff
2019-09-16: Formalization of Multiway-Join Algorithms
Author: Thibault Dardinier
2019-09-10: Verification Components for Hybrid Systems
Author: Jonathan Julian Huerta y Munive
2019-09-06: Fourier Series
Author: Lawrence C Paulson
2019-08-30: A Case Study in Basic Algebra
Author: Clemens Ballarin
2019-08-16: Formalisation of an Adaptive State Counting Algorithm
Author: Robert Sachtleben
2019-08-14: Laplace Transform
Author: Fabian Immler
2019-08-06: Linear Programming
Authors: Julian Parsert and Cezary Kaliszyk
2019-08-06: Communicating Concurrent Kleene Algebra for Distributed Systems Specification
Authors: Maxime Buyse and Jason Jaskolka
2019-08-05: Selected Problems from the International Mathematical Olympiad 2019
Author: Manuel Eberl
2019-08-01: Stellar Quorum Systems
Author: Giuliano Losa
2019-07-30: A Formal Development of a Polychronous Polytimed Coordination Language
Authors: Hai Nguyen Van, Frédéric Boulanger and Burkhart Wolff
2019-07-27: Szpilrajn Extension Theorem
Author: Peter Zeller
2019-07-18: A Sequent Calculus for First-Order Logic
Author: Asta Halkjær From
2019-07-08: A Verified Code Generator from Isabelle/HOL to CakeML
Author: Lars Hupel
2019-07-04: Formalization of a Monitoring Algorithm for Metric First-Order Temporal Logic
Authors: Joshua Schneider and Dmitriy Traytel
2019-06-27: Complete Non-Orders and Fixed Points
Authors: Akihisa Yamada and Jérémy Dubut
2019-06-25: Priority Search Trees
Authors: Peter Lammich and Tobias Nipkow
2019-06-25: Purely Functional, Simple, and Efficient Implementation of Prim and Dijkstra
Authors: Peter Lammich and Tobias Nipkow
2019-06-21: Linear Inequalities
Authors: Ralph Bottesch, Alban Reynaud and René Thiemann
2019-06-16: Hilbert's Nullstellensatz
Author: Alexander Maletzky
2019-06-15: Gröbner Bases, Macaulay Matrices and Dubé's Degree Bounds
Author: Alexander Maletzky
2019-06-13: Binary Heaps for IMP2
Author: Simon Griebel
2019-06-03: Differential Game Logic
Author: André Platzer
2019-05-30: Multidimensional Binary Search Trees
Author: Martin Rau
2019-05-14: Formalization of Generic Authenticated Data Structures
Authors: Matthias Brun and Dmitriy Traytel
2019-05-09: Multi-Party Computation
Authors: David Aspinall and David Butler
2019-04-26: HOL-CSP Version 2.0
Authors: Safouan Taha, Lina Ye and Burkhart Wolff
2019-04-16: A Compositional and Unified Translation of LTL into ω-Automata
Authors: Benedikt Seidl and Salomon Sickert
2019-04-06: A General Theory of Syntax with Bindings
Authors: Lorenzo Gheri and Andrei Popescu
2019-03-27: The Transcendence of Certain Infinite Series
Authors: Angeliki Koutsoukou-Argyraki and Wenda Li
2019-03-24: Quantum Hoare Logic
Authors: Junyi Liu, Bohua Zhan, Shuling Wang, Shenggang Ying, Tao Liu, Yangjia Li, Mingsheng Ying and Naijun Zhan
2019-03-09: Safe OCL
Author: Denis Nikiforov
2019-02-21: Elementary Facts About the Distribution of Primes
Author: Manuel Eberl
2019-02-14: Kruskal's Algorithm for Minimum Spanning Forest
Authors: Maximilian P.L. Haslbeck, Peter Lammich and Julian Biendarra
2019-02-11: Probabilistic Primality Testing
Authors: Daniel Stüwe and Manuel Eberl
2019-02-08: Universal Turing Machine
Authors: Jian Xu, Xingyuan Zhang, Christian Urban and Sebastiaan J. C. Joosten
2019-02-01: Isabelle/UTP: Mechanised Theory Engineering for Unifying Theories of Programming
Authors: Simon Foster, Frank Zeyda, Yakoub Nemouchi, Pedro Ribeiro and Burkhart Wolff
2019-02-01: The Inversions of a List
Author: Manuel Eberl
2019-01-17: Farkas' Lemma and Motzkin's Transposition Theorem
Authors: Ralph Bottesch, Max W. Haslbeck and René Thiemann
2019-01-15: IMP2 – Simple Program Verification in Isabelle/HOL
Authors: Peter Lammich and Simon Wimmer
2019-01-15: An Algebra for Higher-Order Terms
Author: Lars Hupel
2019-01-07: A Reduction Theorem for Store Buffers
Authors: Ernie Cohen and Norbert Schirmer

 

2018
2018-12-26: A Formal Model of the Document Object Model
Authors: Achim D. Brucker and Michael Herzberg
2018-12-25: Formalization of Concurrent Revisions
Author: Roy Overbeek
2018-12-21: Verifying Imperative Programs using Auto2
Author: Bohua Zhan
2018-12-17: Constructive Cryptography in HOL
Authors: Andreas Lochbihler and S. Reza Sefidgar
2018-12-11: Transformer Semantics
Author: Georg Struth
2018-12-11: Quantales
Author: Georg Struth
2018-12-11: Properties of Orderings and Lattices
Author: Georg Struth
2018-11-23: Graph Saturation
Author: Sebastiaan J. C. Joosten
2018-11-23: A Verified Functional Implementation of Bachmair and Ganzinger's Ordered Resolution Prover
Authors: Anders Schlichtkrull, Jasmin Christian Blanchette and Dmitriy Traytel
2018-11-20: Auto2 Prover
Author: Bohua Zhan
2018-11-16: Matroids
Author: Jonas Keinholz
2018-11-06: Deriving generic class instances for datatypes
Authors: Jonas Rädle and Lars Hupel
2018-10-30: Formalisation and Evaluation of Alan Gewirth's Proof for the Principle of Generic Consistency in Isabelle/HOL
Authors: David Fuenmayor and Christoph Benzmüller
2018-10-29: Epistemic Logic
Author: Asta Halkjær From
2018-10-22: Smooth Manifolds
Authors: Fabian Immler and Bohua Zhan
2018-10-19: Randomised Binary Search Trees
Author: Manuel Eberl
2018-10-19: Formalization of the Embedding Path Order for Lambda-Free Higher-Order Terms
Author: Alexander Bentkamp
2018-10-12: Upper Bounding Diameters of State Spaces of Factored Transition Systems
Authors: Friedrich Kurz and Mohammad Abdulaziz
2018-09-28: The Transcendence of π
Author: Manuel Eberl
2018-09-25: Symmetric Polynomials
Author: Manuel Eberl
2018-09-20: Signature-Based Gröbner Basis Algorithms
Author: Alexander Maletzky
2018-09-19: The Prime Number Theorem
Authors: Manuel Eberl and Lawrence C. Paulson
2018-09-15: Aggregation Algebras
Author: Walter Guttmann
2018-09-14: Octonions
Author: Angeliki Koutsoukou-Argyraki
2018-09-05: Quaternions
Author: Lawrence C. Paulson
2018-09-02: The Budan-Fourier Theorem and Counting Real Roots with Multiplicity
Author: Wenda Li
2018-08-24: An Incremental Simplex Algorithm with Unsatisfiable Core Generation
Authors: Filip Marić, Mirko Spasić and René Thiemann
2018-08-14: Minsky Machines
Author: Bertram Felgenhauer
2018-07-16: Pricing in discrete financial models
Author: Mnacho Echenim
2018-07-04: Von-Neumann-Morgenstern Utility Theorem
Authors: Julian Parsert and Cezary Kaliszyk
2018-06-23: Pell's Equation
Author: Manuel Eberl
2018-06-14: Projective Geometry
Author: Anthony Bordg
2018-06-14: The Localization of a Commutative Ring
Author: Anthony Bordg
2018-06-05: Partial Order Reduction
Author: Julian Brunner
2018-05-27: Optimal Binary Search Trees
Authors: Tobias Nipkow and Dániel Somogyi
2018-05-25: Hidden Markov Models
Author: Simon Wimmer
2018-05-24: Probabilistic Timed Automata
Authors: Simon Wimmer and Johannes Hölzl
2018-05-23: Irrational Rapidly Convergent Series
Authors: Angeliki Koutsoukou-Argyraki and Wenda Li
2018-05-23: Axiom Systems for Category Theory in Free Logic
Authors: Christoph Benzmüller and Dana Scott
2018-05-22: Monadification, Memoization and Dynamic Programming
Authors: Simon Wimmer, Shuwei Hu and Tobias Nipkow
2018-05-10: OpSets: Sequential Specifications for Replicated Datatypes
Authors: Martin Kleppmann, Victor B. F. Gomes, Dominic P. Mulligan and Alastair R. Beresford
2018-05-07: An Isabelle/HOL Formalization of the Modular Assembly Kit for Security Properties
Authors: Oliver Bračevac, Richard Gay, Sylvia Grewe, Heiko Mantel, Henning Sudbrock and Markus Tasch
2018-04-29: WebAssembly
Author: Conrad Watt
2018-04-27: VerifyThis 2018 - Polished Isabelle Solutions
Authors: Peter Lammich and Simon Wimmer
2018-04-24: Bounded Natural Functors with Covariance and Contravariance
Authors: Andreas Lochbihler and Joshua Schneider
2018-03-22: The Incompatibility of Fishburn-Strategyproofness and Pareto-Efficiency
Authors: Felix Brandt, Manuel Eberl, Christian Saile and Christian Stricker
2018-03-13: Weight-Balanced Trees
Authors: Tobias Nipkow and Stefan Dirix
2018-03-12: CakeML
Authors: Lars Hupel and Yu Zhang
2018-03-01: A Theory of Architectural Design Patterns
Author: Diego Marmsoler
2018-02-26: Hoare Logics for Time Bounds
Authors: Maximilian P. L. Haslbeck and Tobias Nipkow
2018-02-06: Treaps
Authors: Maximilian Haslbeck, Manuel Eberl and Tobias Nipkow
2018-02-06: A verified factorization algorithm for integer polynomials with polynomial complexity
Authors: Jose Divasón, Sebastiaan Joosten, René Thiemann and Akihisa Yamada
2018-02-06: First-Order Terms
Authors: Christian Sternagel and René Thiemann
2018-02-06: The Error Function
Author: Manuel Eberl
2018-02-02: A verified LLL algorithm
Authors: Ralph Bottesch, Jose Divasón, Maximilian Haslbeck, Sebastiaan Joosten, René Thiemann and Akihisa Yamada
2018-01-18: Formalization of Bachmair and Ganzinger's Ordered Resolution Prover
Authors: Anders Schlichtkrull, Jasmin Christian Blanchette, Dmitriy Traytel and Uwe Waldmann
2018-01-16: Gromov Hyperbolicity
Author: Sebastien Gouezel
2018-01-11: An Isabelle/HOL formalisation of Green's Theorem
Authors: Mohammad Abdulaziz and Lawrence C. Paulson
2018-01-08: Taylor Models
Authors: Christoph Traut and Fabian Immler

 

2017
2017-12-22: The Falling Factorial of a Sum
Author: Lukas Bulwahn
2017-12-21: The Median-of-Medians Selection Algorithm
Author: Manuel Eberl
2017-12-21: The Mason–Stothers Theorem
Author: Manuel Eberl
2017-12-21: Dirichlet L-Functions and Dirichlet's Theorem
Author: Manuel Eberl
2017-12-19: Operations on Bounded Natural Functors
Authors: Jasmin Christian Blanchette, Andrei Popescu and Dmitriy Traytel
2017-12-18: The string search algorithm by Knuth, Morris and Pratt
Authors: Fabian Hellauer and Peter Lammich
2017-11-22: Stochastic Matrices and the Perron-Frobenius Theorem
Author: René Thiemann
2017-11-09: The IMAP CmRDT
Authors: Tim Jungnickel, Lennart Oldenburg and Matthias Loibl
2017-11-06: Hybrid Multi-Lane Spatial Logic
Author: Sven Linker
2017-10-26: The Kuratowski Closure-Complement Theorem
Authors: Peter Gammie and Gianpaolo Gioiosa
2017-10-19: Transition Systems and Automata
Author: Julian Brunner
2017-10-19: Büchi Complementation
Author: Julian Brunner
2017-10-17: Evaluate Winding Numbers through Cauchy Indices
Author: Wenda Li
2017-10-17: Count the Number of Complex Roots
Author: Wenda Li
2017-10-14: Homogeneous Linear Diophantine Equations
Authors: Florian Messner, Julian Parsert, Jonas Schöpf and Christian Sternagel
2017-10-12: The Hurwitz and Riemann ζ Functions
Author: Manuel Eberl
2017-10-12: Linear Recurrences
Author: Manuel Eberl
2017-10-12: Dirichlet Series
Author: Manuel Eberl
2017-09-21: Computer-assisted Reconstruction and Assessment of E. J. Lowe's Modal Ontological Argument
Authors: David Fuenmayor and Christoph Benzmüller
2017-09-17: Representation and Partial Automation of the Principia Logico-Metaphysica in Isabelle/HOL
Author: Daniel Kirchner
2017-09-06: Anselm's God in Isabelle/HOL
Author: Ben Blumson
2017-09-01: Microeconomics and the First Welfare Theorem
Authors: Julian Parsert and Cezary Kaliszyk
2017-08-20: Root-Balanced Tree
Author: Tobias Nipkow
2017-08-20: Orbit-Stabiliser Theorem with Application to Rotational Symmetries
Author: Jonas Rädle
2017-08-16: The LambdaMu-calculus
Authors: Cristina Matache, Victor B. F. Gomes and Dominic P. Mulligan
2017-07-31: Stewart's Theorem and Apollonius' Theorem
Author: Lukas Bulwahn
2017-07-28: Dynamic Architectures
Author: Diego Marmsoler
2017-07-21: Declarative Semantics for Functional Languages
Author: Jeremy Siek
2017-07-15: HOLCF-Prelude
Authors: Joachim Breitner, Brian Huffman, Neil Mitchell and Christian Sternagel
2017-07-13: Minkowski's Theorem
Author: Manuel Eberl
2017-07-09: Verified Metatheory and Type Inference for a Name-Carrying Simply-Typed Lambda Calculus
Author: Michael Rawson
2017-07-07: A framework for establishing Strong Eventual Consistency for Conflict-free Replicated Datatypes
Authors: Victor B. F. Gomes, Martin Kleppmann, Dominic P. Mulligan and Alastair R. Beresford
2017-07-06: Stone-Kleene Relation Algebras
Author: Walter Guttmann
2017-06-21: Propositional Proof Systems
Authors: Julius Michaelis and Tobias Nipkow
2017-06-13: Partial Semigroups and Convolution Algebras
Authors: Brijesh Dongol, Victor B. F. Gomes, Ian J. Hayes and Georg Struth
2017-06-06: Buffon's Needle Problem
Author: Manuel Eberl
2017-06-01: Formalizing Push-Relabel Algorithms
Authors: Peter Lammich and S. Reza Sefidgar
2017-06-01: Flow Networks and the Min-Cut-Max-Flow Theorem
Authors: Peter Lammich and S. Reza Sefidgar
2017-05-25: Optics
Authors: Simon Foster and Frank Zeyda
2017-05-24: Developing Security Protocols by Refinement
Authors: Christoph Sprenger and Ivano Somaini
2017-05-24: Dictionary Construction
Author: Lars Hupel
2017-05-08: The Floyd-Warshall Algorithm for Shortest Paths
Authors: Simon Wimmer and Peter Lammich
2017-05-05: Probabilistic while loop
Author: Andreas Lochbihler
2017-05-05: Effect polymorphism in higher-order logic
Author: Andreas Lochbihler
2017-05-05: Monad normalisation
Authors: Joshua Schneider, Manuel Eberl and Andreas Lochbihler
2017-05-05: Game-based cryptography in HOL
Authors: Andreas Lochbihler, S. Reza Sefidgar and Bhargav Bhatt
2017-05-05: CryptHOL
Author: Andreas Lochbihler
2017-05-04: Monoidal Categories
Author: Eugene W. Stark
2017-05-01: Types, Tableaus and Gödel’s God in Isabelle/HOL
Authors: David Fuenmayor and Christoph Benzmüller
2017-04-28: Local Lexing
Author: Steven Obua
2017-04-19: Constructor Functions
Author: Lars Hupel
2017-04-18: Lazifying case constants
Author: Lars Hupel
2017-04-06: Subresultants
Authors: Sebastiaan Joosten, René Thiemann and Akihisa Yamada
2017-04-04: Expected Shape of Random Binary Search Trees
Author: Manuel Eberl
2017-03-15: The number of comparisons in QuickSort
Author: Manuel Eberl
2017-03-15: Lower bound on comparison-based sorting algorithms
Author: Manuel Eberl
2017-03-10: The Euler–MacLaurin Formula
Author: Manuel Eberl
2017-02-28: The Group Law for Elliptic Curves
Author: Stefan Berghofer
2017-02-26: Menger's Theorem
Author: Christoph Dittmann
2017-02-13: Differential Dynamic Logic
Author: Brandon Bohrer
2017-02-10: Abstract Soundness
Authors: Jasmin Christian Blanchette, Andrei Popescu and Dmitriy Traytel
2017-02-07: Stone Relation Algebras
Author: Walter Guttmann
2017-01-31: Refining Authenticated Key Agreement with Strong Adversaries
Authors: Joseph Lallemand and Christoph Sprenger
2017-01-24: Bernoulli Numbers
Authors: Lukas Bulwahn and Manuel Eberl
2017-01-17: Minimal Static Single Assignment Form
Authors: Max Wagner and Denis Lohner
2017-01-17: Bertrand's postulate
Authors: Julian Biendarra and Manuel Eberl
2017-01-12: The Transcendence of e
Author: Manuel Eberl
2017-01-08: Formal Network Models and Their Application to Firewall Policies
Authors: Achim D. Brucker, Lukas Brügger and Burkhart Wolff
2017-01-03: Verification of a Diffie-Hellman Password-based Authentication Protocol by Extending the Inductive Method
Author: Pasquale Noce
2017-01-01: First-Order Logic According to Harrison
Authors: Alexander Birch Jensen, Anders Schlichtkrull and Jørgen Villadsen

 

2016
2016-12-30: Concurrent Refinement Algebra and Rely Quotients
Authors: Julian Fell, Ian J. Hayes and Andrius Velykis
2016-12-29: The Twelvefold Way
Author: Lukas Bulwahn
2016-12-20: Proof Strategy Language
Author: Yutaka Nagashima
2016-12-07: Paraconsistency
Authors: Anders Schlichtkrull and Jørgen Villadsen
2016-11-29: COMPLX: A Verification Framework for Concurrent Imperative Programs
Authors: Sidney Amani, June Andronick, Maksym Bortin, Corey Lewis, Christine Rizkallah and Joseph Tuong
2016-11-23: Abstract Interpretation of Annotated Commands
Author: Tobias Nipkow
2016-11-16: Separata: Isabelle tactics for Separation Algebra
Authors: Zhe Hou, David Sanan, Alwen Tiu, Rajeev Gore and Ranald Clouston
2016-11-12: Formalization of Nested Multisets, Hereditary Multisets, and Syntactic Ordinals
Authors: Jasmin Christian Blanchette, Mathias Fleury and Dmitriy Traytel
2016-11-12: Formalization of Knuth–Bendix Orders for Lambda-Free Higher-Order Terms
Authors: Heiko Becker, Jasmin Christian Blanchette, Uwe Waldmann and Daniel Wand
2016-11-10: Expressiveness of Deep Learning
Author: Alexander Bentkamp
2016-10-25: Modal Logics for Nominal Transition Systems
Authors: Tjark Weber, Lars-Henrik Eriksson, Joachim Parrow, Johannes Borgström and Ramunas Gutkovas
2016-10-24: Stable Matching
Author: Peter Gammie
2016-10-21: LOFT — Verified Migration of Linux Firewalls to SDN
Authors: Julius Michaelis and Cornelius Diekmann
2016-10-19: Source Coding Theorem
Authors: Quentin Hibon and Lawrence C. Paulson
2016-10-19: A formal model for the SPARCv8 ISA and a proof of non-interference for the LEON3 processor
Authors: Zhe Hou, David Sanan, Alwen Tiu and Yang Liu
2016-10-14: The Factorization Algorithm of Berlekamp and Zassenhaus
Authors: Jose Divasón, Sebastiaan Joosten, René Thiemann and Akihisa Yamada
2016-10-11: Intersecting Chords Theorem
Author: Lukas Bulwahn
2016-10-05: Lp spaces
Author: Sebastien Gouezel
2016-09-30: Fisher–Yates shuffle
Author: Manuel Eberl
2016-09-29: Allen's Interval Calculus
Author: Fadoua Ghourabi
2016-09-23: Formalization of Recursive Path Orders for Lambda-Free Higher-Order Terms
Authors: Jasmin Christian Blanchette, Uwe Waldmann and Daniel Wand
2016-09-09: Iptables Semantics
Authors: Cornelius Diekmann and Lars Hupel
2016-09-06: A Variant of the Superposition Calculus
Author: Nicolas Peltier
2016-09-06: Stone Algebras
Author: Walter Guttmann
2016-09-01: Stirling's formula
Author: Manuel Eberl
2016-08-31: Routing
Authors: Julius Michaelis and Cornelius Diekmann
2016-08-24: Simple Firewall
Authors: Cornelius Diekmann, Julius Michaelis and Maximilian Haslbeck
2016-08-18: Infeasible Paths Elimination by Symbolic Execution Techniques: Proof of Correctness and Preservation of Paths
Authors: Romain Aissat, Frederic Voisin and Burkhart Wolff
2016-08-12: Formalizing the Edmonds-Karp Algorithm
Authors: Peter Lammich and S. Reza Sefidgar
2016-08-08: The Imperative Refinement Framework
Author: Peter Lammich
2016-08-07: Ptolemy's Theorem
Author: Lukas Bulwahn
2016-07-17: Surprise Paradox
Author: Joachim Breitner
2016-07-14: Pairing Heap
Authors: Hauke Brinkop and Tobias Nipkow
2016-07-05: A Framework for Verifying Depth-First Search Algorithms
Authors: Peter Lammich and René Neumann
2016-07-01: Chamber Complexes, Coxeter Systems, and Buildings
Author: Jeremy Sylvestre
2016-06-30: The Z Property
Authors: Bertram Felgenhauer, Julian Nagele, Vincent van Oostrom and Christian Sternagel
2016-06-30: The Resolution Calculus for First-Order Logic
Author: Anders Schlichtkrull
2016-06-28: IP Addresses
Authors: Cornelius Diekmann, Julius Michaelis and Lars Hupel
2016-06-28: Compositional Security-Preserving Refinement for Concurrent Imperative Programs
Authors: Toby Murray, Robert Sison, Edward Pierzchalski and Christine Rizkallah
2016-06-26: Category Theory with Adjunctions and Limits
Author: Eugene W. Stark
2016-06-26: Cardinality of Multisets
Author: Lukas Bulwahn
2016-06-25: A Dependent Security Type System for Concurrent Imperative Programs
Authors: Toby Murray, Robert Sison, Edward Pierzchalski and Christine Rizkallah
2016-06-21: Catalan Numbers
Author: Manuel Eberl
2016-06-18: Program Construction and Verification Components Based on Kleene Algebra
Authors: Victor B. F. Gomes and Georg Struth
2016-06-13: Conservation of CSP Noninterference Security under Concurrent Composition
Author: Pasquale Noce
2016-06-09: Finite Machine Word Library
Authors: Joel Beeren, Matthew Fernandez, Xin Gao, Gerwin Klein, Rafal Kolanski, Japheth Lim, Corey Lewis, Daniel Matichuk and Thomas Sewell
2016-05-31: Tree Decomposition
Author: Christoph Dittmann
2016-05-24: POSIX Lexing with Derivatives of Regular Expressions
Authors: Fahad Ausaf, Roy Dyckhoff and Christian Urban
2016-05-24: Cardinality of Equivalence Relations
Author: Lukas Bulwahn
2016-05-20: Perron-Frobenius Theorem for Spectral Radius Analysis
Authors: Jose Divasón, Ondřej Kunčar, René Thiemann and Akihisa Yamada
2016-05-20: The meta theory of the Incredible Proof Machine
Authors: Joachim Breitner and Denis Lohner
2016-05-18: A Constructive Proof for FLP
Authors: Benjamin Bisping, Paul-David Brodmann, Tim Jungnickel, Christina Rickmann, Henning Seidler, Anke Stüber, Arno Wilhelm-Weidner, Kirstin Peters and Uwe Nestmann
2016-05-09: A Formal Proof of the Max-Flow Min-Cut Theorem for Countable Networks
Author: Andreas Lochbihler
2016-05-05: Randomised Social Choice Theory
Author: Manuel Eberl
2016-05-04: The Incompatibility of SD-Efficiency and SD-Strategy-Proofness
Author: Manuel Eberl
2016-05-04: Spivey's Generalized Recurrence for Bell Numbers
Author: Lukas Bulwahn
2016-05-02: Gröbner Bases Theory
Authors: Fabian Immler and Alexander Maletzky
2016-04-28: No Faster-Than-Light Observers
Authors: Mike Stannett and István Németi
2016-04-27: Algorithms for Reduced Ordered Binary Decision Diagrams
Authors: Julius Michaelis, Maximilian Haslbeck, Peter Lammich and Lars Hupel
2016-04-27: A formalisation of the Cocke-Younger-Kasami algorithm
Author: Maksym Bortin
2016-04-26: Conservation of CSP Noninterference Security under Sequential Composition
Author: Pasquale Noce
2016-04-12: Kleene Algebras with Domain
Authors: Victor B. F. Gomes, Walter Guttmann, Peter Höfner, Georg Struth and Tjark Weber
2016-03-11: Propositional Resolution and Prime Implicates Generation
Author: Nicolas Peltier
2016-03-08: Timed Automata
Author: Simon Wimmer
2016-03-08: The Cartan Fixed Point Theorems
Author: Lawrence C. Paulson
2016-03-01: Linear Temporal Logic
Author: Salomon Sickert
2016-02-17: Analysis of List Update Algorithms
Authors: Maximilian P.L. Haslbeck and Tobias Nipkow
2016-02-05: Verified Construction of Static Single Assignment Form
Authors: Sebastian Ullrich and Denis Lohner
2016-01-29: Polynomial Interpolation
Authors: René Thiemann and Akihisa Yamada
2016-01-29: Polynomial Factorization
Authors: René Thiemann and Akihisa Yamada
2016-01-20: Knot Theory
Author: T.V.H. Prathamesh
2016-01-18: Tensor Product of Matrices
Author: T.V.H. Prathamesh
2016-01-14: Cardinality of Number Partitions
Author: Lukas Bulwahn

 

2015
2015-12-28: Basic Geometric Properties of Triangles
Author: Manuel Eberl
2015-12-28: The Divergence of the Prime Harmonic Series
Author: Manuel Eberl
2015-12-28: Liouville numbers
Author: Manuel Eberl
2015-12-28: Descartes' Rule of Signs
Author: Manuel Eberl
2015-12-22: The Stern-Brocot Tree
Authors: Peter Gammie and Andreas Lochbihler
2015-12-22: Applicative Lifting
Authors: Andreas Lochbihler and Joshua Schneider
2015-12-22: Algebraic Numbers in Isabelle/HOL
Authors: René Thiemann, Akihisa Yamada and Sebastiaan Joosten
2015-12-12: Cardinality of Set Partitions
Author: Lukas Bulwahn
2015-12-02: Latin Square
Author: Alexander Bentkamp
2015-12-01: Ergodic Theory
Author: Sebastien Gouezel
2015-11-19: Euler's Partition Theorem
Author: Lukas Bulwahn
2015-11-18: The Tortoise and Hare Algorithm
Author: Peter Gammie
2015-11-11: Planarity Certificates
Author: Lars Noschinski
2015-11-02: Positional Determinacy of Parity Games
Author: Christoph Dittmann
2015-09-16: A Meta-Model for the Isabelle API
Authors: Frédéric Tuong and Burkhart Wolff
2015-09-04: Converting Linear Temporal Logic to Deterministic (Generalized) Rabin Automata
Author: Salomon Sickert
2015-08-21: Matrices, Jordan Normal Forms, and Spectral Radius Theory
Authors: René Thiemann and Akihisa Yamada
2015-08-20: Decreasing Diagrams II
Author: Bertram Felgenhauer
2015-08-18: The Inductive Unwinding Theorem for CSP Noninterference Security
Author: Pasquale Noce
2015-08-12: Representations of Finite Groups
Author: Jeremy Sylvestre
2015-08-10: Analysing and Comparing Encodability Criteria for Process Calculi
Authors: Kirstin Peters and Rob van Glabbeek
2015-07-21: Generating Cases from Labeled Subgoals
Author: Lars Noschinski
2015-07-14: Landau Symbols
Author: Manuel Eberl
2015-07-14: The Akra-Bazzi theorem and the Master theorem
Author: Manuel Eberl
2015-07-07: Hermite Normal Form
Authors: Jose Divasón and Jesús Aransay
2015-06-27: Derangements Formula
Author: Lukas Bulwahn
2015-06-11: The Ipurge Unwinding Theorem for CSP Noninterference Security
Author: Pasquale Noce
2015-06-11: The Generic Unwinding Theorem for CSP Noninterference Security
Author: Pasquale Noce
2015-06-11: Binary Multirelations
Authors: Hitoshi Furusawa and Georg Struth
2015-06-11: Reasoning about Lists via List Interleaving
Author: Pasquale Noce
2015-06-07: Parameterized Dynamic Tables
Author: Tobias Nipkow
2015-05-28: Derivatives of Logical Formulas
Author: Dmitriy Traytel
2015-05-27: A Zoo of Probabilistic Systems
Authors: Johannes Hölzl, Andreas Lochbihler and Dmitriy Traytel
2015-04-30: VCG - Combinatorial Vickrey-Clarke-Groves Auctions
Authors: Marco B. Caminati, Manfred Kerber, Christoph Lange and Colin Rowat
2015-04-15: Residuated Lattices
Authors: Victor B. F. Gomes and Georg Struth
2015-04-13: Concurrent IMP
Author: Peter Gammie
2015-04-13: Relaxing Safely: Verified On-the-Fly Garbage Collection for x86-TSO
Authors: Peter Gammie, Tony Hosking and Kai Engelhardt
2015-03-30: Trie
Authors: Andreas Lochbihler and Tobias Nipkow
2015-03-18: Consensus Refined
Authors: Ognjen Maric and Christoph Sprenger
2015-03-11: Deriving class instances for datatypes
Authors: Christian Sternagel and René Thiemann
2015-02-20: The Safety of Call Arity
Author: Joachim Breitner
2015-02-12: QR Decomposition
Authors: Jose Divasón and Jesús Aransay
2015-02-12: Echelon Form
Authors: Jose Divasón and Jesús Aransay
2015-02-05: Finite Automata in Hereditarily Finite Set Theory
Author: Lawrence C. Paulson
2015-01-28: Verification of the UpDown Scheme
Author: Johannes Hölzl

 

2014
2014-11-28: The Unified Policy Framework (UPF)
Authors: Achim D. Brucker, Lukas Brügger and Burkhart Wolff
2014-10-23: Loop freedom of the (untimed) AODV routing protocol
Authors: Timothy Bourke and Peter Höfner
2014-10-13: Lifting Definition Option
Author: René Thiemann
2014-10-10: Stream Fusion in HOL with Code Generation
Authors: Andreas Lochbihler and Alexandra Maximova
2014-10-09: A Verified Compiler for Probability Density Functions
Authors: Manuel Eberl, Johannes Hölzl and Tobias Nipkow
2014-10-08: Formalization of Refinement Calculus for Reactive Systems
Author: Viorel Preoteasa
2014-10-03: XML
Authors: Christian Sternagel and René Thiemann
2014-10-03: Certification Monads
Authors: Christian Sternagel and René Thiemann
2014-09-25: Imperative Insertion Sort
Author: Christian Sternagel
2014-09-19: The Sturm-Tarski Theorem
Author: Wenda Li
2014-09-15: The Cayley-Hamilton Theorem
Authors: Stephan Adelsberger, Stefan Hetzl and Florian Pollak
2014-09-09: The Jordan-Hölder Theorem
Author: Jakob von Raumer
2014-09-04: Priority Queues Based on Braun Trees
Author: Tobias Nipkow
2014-09-03: Gauss-Jordan Algorithm and Its Applications
Authors: Jose Divasón and Jesús Aransay
2014-08-29: Vector Spaces
Author: Holden Lee
2014-08-29: Real-Valued Special Functions: Upper and Lower Bounds
Author: Lawrence C. Paulson
2014-08-13: Skew Heap
Author: Tobias Nipkow
2014-08-12: Splay Tree
Author: Tobias Nipkow
2014-07-29: Haskell's Show Class in Isabelle/HOL
Authors: Christian Sternagel and René Thiemann
2014-07-18: Formal Specification of a Generic Separation Kernel
Authors: Freek Verbeek, Sergey Tverdyshev, Oto Havle, Holger Blasum, Bruno Langenstein, Werner Stephan, Yakoub Nemouchi, Abderrahmane Feliachi, Burkhart Wolff and Julien Schmaltz
2014-07-13: pGCL for Isabelle
Author: David Cock
2014-07-07: Amortized Complexity Verified
Author: Tobias Nipkow
2014-07-04: Network Security Policy Verification
Author: Cornelius Diekmann
2014-07-03: Pop-Refinement
Author: Alessandro Coglio
2014-06-12: Decision Procedures for MSO on Words Based on Derivatives of Regular Expressions
Authors: Dmitriy Traytel and Tobias Nipkow
2014-06-08: Boolean Expression Checkers
Author: Tobias Nipkow
2014-05-28: Promela Formalization
Author: René Neumann
2014-05-28: Converting Linear-Time Temporal Logic to Generalized Büchi Automata
Authors: Alexander Schimpf and Peter Lammich
2014-05-28: Verified Efficient Implementation of Gabow's Strongly Connected Components Algorithm
Author: Peter Lammich
2014-05-28: A Fully Verified Executable LTL Model Checker
Authors: Javier Esparza, Peter Lammich, René Neumann, Tobias Nipkow, Alexander Schimpf and Jan-Georg Smaus
2014-05-28: The CAVA Automata Library
Author: Peter Lammich
2014-05-23: Transitive closure according to Roy-Floyd-Warshall
Author: Makarius Wenzel
2014-05-23: Noninterference Security in Communicating Sequential Processes
Author: Pasquale Noce
2014-05-21: Regular Algebras
Authors: Simon Foster and Georg Struth
2014-04-28: Formalisation and Analysis of Component Dependencies
Author: Maria Spichkova
2014-04-23: A Formalization of Declassification with WHAT-and-WHERE-Security
Authors: Sylvia Grewe, Alexander Lux, Heiko Mantel and Jens Sauer
2014-04-23: A Formalization of Strong Security
Authors: Sylvia Grewe, Alexander Lux, Heiko Mantel and Jens Sauer
2014-04-23: A Formalization of Assumptions and Guarantees for Compositional Noninterference
Authors: Sylvia Grewe, Heiko Mantel and Daniel Schoepe
2014-04-22: Bounded-Deducibility Security
Authors: Andrei Popescu and Peter Lammich
2014-04-16: A shallow embedding of HyperCTL*
Authors: Markus N. Rabe, Peter Lammich and Andrei Popescu
2014-04-16: Abstract Completeness
Authors: Jasmin Christian Blanchette, Andrei Popescu and Dmitriy Traytel
2014-04-13: Discrete Summation
Author: Florian Haftmann
2014-04-03: Syntax and semantics of a GPU kernel programming language
Author: John Wickerson
2014-03-11: Probabilistic Noninterference
Authors: Andrei Popescu and Johannes Hölzl
2014-03-08: Mechanization of the Algebra for Wireless Networks (AWN)
Author: Timothy Bourke
2014-02-18: Mutually Recursive Partial Functions
Author: René Thiemann
2014-02-13: Properties of Random Graphs -- Subgraph Containment
Author: Lars Hupel
2014-02-11: Verification of Selection and Heap Sort Using Locales
Author: Danijela Petrovic
2014-02-07: Affine Arithmetic
Author: Fabian Immler
2014-02-06: Implementing field extensions of the form Q[sqrt(b)]
Author: René Thiemann
2014-01-30: Unified Decision Procedures for Regular Expression Equivalence
Authors: Tobias Nipkow and Dmitriy Traytel
2014-01-28: Secondary Sylow Theorems
Author: Jakob von Raumer
2014-01-25: Relation Algebra
Authors: Alasdair Armstrong, Simon Foster, Georg Struth and Tjark Weber
2014-01-23: Kleene Algebra with Tests and Demonic Refinement Algebras
Authors: Alasdair Armstrong, Victor B. F. Gomes and Georg Struth
2014-01-16: Featherweight OCL: A Proposal for a Machine-Checked Formal Semantics for OCL 2.5
Authors: Achim D. Brucker, Frédéric Tuong and Burkhart Wolff
2014-01-11: Sturm's Theorem
Author: Manuel Eberl
2014-01-11: Compositional Properties of Crypto-Based Components
Author: Maria Spichkova

 

2013
2013-12-01: A General Method for the Proof of Theorems on Tail-recursive Functions
Author: Pasquale Noce
2013-11-17: Gödel's Incompleteness Theorems
Author: Lawrence C. Paulson
2013-11-17: The Hereditarily Finite Sets
Author: Lawrence C. Paulson
2013-11-15: A Codatatype of Formal Languages
Author: Dmitriy Traytel
2013-11-14: Stream Processing Components: Isabelle/HOL Formalisation and Case Studies
Author: Maria Spichkova
2013-11-12: Gödel's God in Isabelle/HOL
Authors: Christoph Benzmüller and Bruno Woltzenlogel Paleo
2013-11-01: Decreasing Diagrams
Author: Harald Zankl
2013-10-02: Automatic Data Refinement
Author: Peter Lammich
2013-09-17: Native Word
Author: Andreas Lochbihler
2013-07-27: A Formal Model of IEEE Floating Point Arithmetic
Author: Lei Yu
2013-07-22: Pratt's Primality Certificates
Authors: Simon Wimmer and Lars Noschinski
2013-07-22: Lehmer's Theorem
Authors: Simon Wimmer and Lars Noschinski
2013-07-19: The Königsberg Bridge Problem and the Friendship Theorem
Author: Wenda Li
2013-06-27: Sound and Complete Sort Encodings for First-Order Logic
Authors: Jasmin Christian Blanchette and Andrei Popescu
2013-05-22: An Axiomatic Characterization of the Single-Source Shortest Path Problem
Author: Christine Rizkallah
2013-04-28: Graph Theory
Author: Lars Noschinski
2013-04-15: Light-weight Containers
Author: Andreas Lochbihler
2013-02-21: Nominal 2
Authors: Christian Urban, Stefan Berghofer and Cezary Kaliszyk
2013-01-31: The Correctness of Launchbury's Natural Semantics for Lazy Evaluation
Author: Joachim Breitner
2013-01-19: Ribbon Proofs
Author: John Wickerson
2013-01-16: Rank-Nullity Theorem in Linear Algebra
Authors: Jose Divasón and Jesús Aransay
2013-01-15: Kleene Algebra
Authors: Alasdair Armstrong, Georg Struth and Tjark Weber
2013-01-03: Computing N-th Roots using the Babylonian Method
Author: René Thiemann

 

2012
2012-11-14: A Separation Logic Framework for Imperative HOL
Authors: Peter Lammich and Rene Meis
2012-11-02: Open Induction
Authors: Mizuhito Ogawa and Christian Sternagel
2012-10-30: The independence of Tarski's Euclidean axiom
Author: T. J. M. Makarios
2012-10-27: Bondy's Theorem
Authors: Jeremy Avigad and Stefan Hetzl
2012-09-10: Possibilistic Noninterference
Authors: Andrei Popescu and Johannes Hölzl
2012-08-07: Generating linear orders for datatypes
Author: René Thiemann
2012-08-05: Proving the Impossibility of Trisecting an Angle and Doubling the Cube
Authors: Ralph Romanos and Lawrence C. Paulson
2012-07-27: Verifying Fault-Tolerant Distributed Algorithms in the Heard-Of Model
Authors: Henri Debrat and Stephan Merz
2012-07-01: Logical Relations for PCF
Author: Peter Gammie
2012-06-26: Type Constructor Classes and Monad Transformers
Author: Brian Huffman
2012-05-29: Psi-calculi in Isabelle
Author: Jesper Bengtson
2012-05-29: The pi-calculus in nominal logic
Author: Jesper Bengtson
2012-05-29: CCS in nominal logic
Author: Jesper Bengtson
2012-05-27: Isabelle/Circus
Authors: Abderrahmane Feliachi, Burkhart Wolff and Marie-Claude Gaudel
2012-05-11: Separation Algebra
Authors: Gerwin Klein, Rafal Kolanski and Andrew Boyton
2012-05-07: Stuttering Equivalence
Author: Stephan Merz
2012-05-02: Inductive Study of Confidentiality
Author: Giampaolo Bella
2012-04-26: Ordinary Differential Equations
Authors: Fabian Immler and Johannes Hölzl
2012-04-13: Well-Quasi-Orders
Author: Christian Sternagel
2012-03-01: Abortable Linearizable Modules
Authors: Rachid Guerraoui, Viktor Kuncak and Giuliano Losa
2012-02-29: Executable Transitive Closures
Author: René Thiemann
2012-02-06: A Probabilistic Proof of the Girth-Chromatic Number Theorem
Author: Lars Noschinski
2012-01-30: Refinement for Monadic Programs
Author: Peter Lammich
2012-01-30: Dijkstra's Shortest Path Algorithm
Authors: Benedikt Nordhoff and Peter Lammich
2012-01-03: Markov Models
Authors: Johannes Hölzl and Tobias Nipkow

 

2011
2011-11-19: A Definitional Encoding of TLA* in Isabelle/HOL
Authors: Gudmund Grov and Stephan Merz
2011-11-09: Efficient Mergesort
Author: Christian Sternagel
2011-09-22: Pseudo Hoops
Authors: George Georgescu, Laurentiu Leustean and Viorel Preoteasa
2011-09-22: Algebra of Monotonic Boolean Transformers
Author: Viorel Preoteasa
2011-09-22: Lattice Properties
Author: Viorel Preoteasa
2011-08-26: The Myhill-Nerode Theorem Based on Regular Expressions
Authors: Chunhan Wu, Xingyuan Zhang and Christian Urban
2011-08-19: Gauss-Jordan Elimination for Matrices Represented as Functions
Author: Tobias Nipkow
2011-07-21: Maximum Cardinality Matching
Author: Christine Rizkallah
2011-05-17: Knowledge-based programs
Author: Peter Gammie
2011-04-01: The General Triangle Is Unique
Author: Joachim Breitner
2011-03-14: Executable Transitive Closures of Finite Relations
Authors: Christian Sternagel and René Thiemann
2011-02-23: Interval Temporal Logic on Natural Numbers
Author: David Trachtenherz
2011-02-23: Infinite Lists
Author: David Trachtenherz
2011-02-23: AutoFocus Stream Processing for Single-Clocking and Multi-Clocking Semantics
Author: David Trachtenherz
2011-02-07: Lightweight Java
Authors: Rok Strniša and Matthew Parkinson
2011-01-10: RIPEMD-160
Author: Fabian Immler
2011-01-08: Lower Semicontinuous Functions
Author: Bogdan Grechuk

 

2010
2010-12-17: Hall's Marriage Theorem
Authors: Dongchen Jiang and Tobias Nipkow
2010-11-16: Shivers' Control Flow Analysis
Author: Joachim Breitner
2010-10-28: Finger Trees
Authors: Benedikt Nordhoff, Stefan Körner and Peter Lammich
2010-10-28: Functional Binomial Queues
Author: René Neumann
2010-10-28: Binomial Heaps and Skew Binomial Heaps
Authors: Rene Meis, Finn Nielsen and Peter Lammich
2010-08-29: Strong Normalization of Moggis's Computational Metalanguage
Author: Christian Doczkal
2010-08-10: Executable Multivariate Polynomials
Authors: Christian Sternagel, René Thiemann, Alexander Maletzky, Fabian Immler, Florian Haftmann, Andreas Lochbihler and Alexander Bentkamp
2010-08-08: Formalizing Statecharts using Hierarchical Automata
Authors: Steffen Helke and Florian Kammüller
2010-06-24: Free Groups
Author: Joachim Breitner
2010-06-20: Category Theory
Author: Alexander Katovsky
2010-06-17: Executable Matrix Operations on Matrices of Arbitrary Dimensions
Authors: Christian Sternagel and René Thiemann
2010-06-14: Abstract Rewriting
Authors: Christian Sternagel and René Thiemann
2010-05-28: Verification of the Deutsch-Schorr-Waite Graph Marking Algorithm using Data Refinement
Authors: Viorel Preoteasa and Ralph-Johan Back
2010-05-28: Semantics and Data Refinement of Invariant Based Programs
Authors: Viorel Preoteasa and Ralph-Johan Back
2010-05-22: A Complete Proof of the Robbins Conjecture
Author: Matthew Wampler-Doty
2010-05-12: Regular Sets and Expressions
Authors: Alexander Krauss and Tobias Nipkow
2010-04-30: Locally Nameless Sigma Calculus
Authors: Ludovic Henrio, Florian Kammüller, Bianca Lutz and Henry Sudhof
2010-03-29: Free Boolean Algebra
Author: Brian Huffman
2010-03-23: Inter-Procedural Information Flow Noninterference via Slicing
Author: Daniel Wasserrab
2010-03-23: Information Flow Noninterference via Slicing
Author: Daniel Wasserrab
2010-02-20: List Index
Author: Tobias Nipkow
2010-02-12: Coinductive
Author: Andreas Lochbihler

 

2009
2009-12-09: A Fast SAT Solver for Isabelle in Standard ML
Author: Armin Heller
2009-12-03: Formalizing the Logic-Automaton Connection
Authors: Stefan Berghofer and Markus Reiter
2009-11-25: Tree Automata
Author: Peter Lammich
2009-11-25: Collections Framework
Author: Peter Lammich
2009-11-22: Perfect Number Theorem
Author: Mark Ijbema
2009-11-13: Backing up Slicing: Verifying the Interprocedural Two-Phase Horwitz-Reps-Binkley Slicer
Author: Daniel Wasserrab
2009-10-30: The Worker/Wrapper Transformation
Author: Peter Gammie
2009-09-01: Ordinals and Cardinals
Author: Andrei Popescu
2009-08-28: Invertibility in Sequent Calculi
Author: Peter Chapman
2009-08-04: An Example of a Cofinitary Group in Isabelle/HOL
Author: Bart Kastermans
2009-05-06: Code Generation for Functions as Data
Author: Andreas Lochbihler
2009-04-29: Stream Fusion
Author: Brian Huffman

 

2008
2008-12-12: A Bytecode Logic for JML and Types
Authors: Lennart Beringer and Martin Hofmann
2008-11-10: Secure information flow and program logics
Authors: Lennart Beringer and Martin Hofmann
2008-11-09: Some classical results in Social Choice Theory
Author: Peter Gammie
2008-11-07: Fun With Tilings
Authors: Tobias Nipkow and Lawrence C. Paulson
2008-10-15: The Textbook Proof of Huffman's Algorithm
Author: Jasmin Christian Blanchette
2008-09-16: Towards Certified Slicing
Author: Daniel Wasserrab
2008-09-02: A Correctness Proof for the Volpano/Smith Security Typing System
Authors: Gregor Snelting and Daniel Wasserrab
2008-09-01: Arrow and Gibbard-Satterthwaite
Author: Tobias Nipkow
2008-08-26: Fun With Functions
Author: Tobias Nipkow
2008-07-23: Formal Verification of Modern SAT Solvers
Author: Filip Marić
2008-04-05: Recursion Theory I
Author: Michael Nedzelsky
2008-02-29: A Sequential Imperative Programming Language Syntax, Semantics, Hoare Logics and Verification Environment
Author: Norbert Schirmer
2008-02-29: BDD Normalisation
Authors: Veronika Ortner and Norbert Schirmer
2008-02-18: Normalization by Evaluation
Authors: Klaus Aehlig and Tobias Nipkow
2008-01-11: Quantifier Elimination for Linear Arithmetic
Author: Tobias Nipkow

 

2007
2007-12-14: Formalization of Conflict Analysis of Programs with Procedures, Thread Creation, and Monitors
Authors: Peter Lammich and Markus Müller-Olm
2007-12-03: Jinja with Threads
Author: Andreas Lochbihler
2007-11-06: Much Ado About Two
Author: Sascha Böhme
2007-08-12: Sums of Two and Four Squares
Author: Roelof Oosterhuis
2007-08-12: Fermat's Last Theorem for Exponents 3 and 4 and the Parametrisation of Pythagorean Triples
Author: Roelof Oosterhuis
2007-08-08: Fundamental Properties of Valuation Theory and Hensel's Lemma
Author: Hidetsune Kobayashi
2007-08-02: POPLmark Challenge Via de Bruijn Indices
Author: Stefan Berghofer
2007-08-02: First-Order Logic According to Fitting
Author: Stefan Berghofer

 

2006
2006-09-09: Hotel Key Card System
Author: Tobias Nipkow
2006-08-08: Abstract Hoare Logics
Author: Tobias Nipkow
2006-05-22: Flyspeck I: Tame Graphs
Authors: Gertrud Bauer and Tobias Nipkow
2006-05-15: CoreC++
Author: Daniel Wasserrab
2006-03-31: A Theory of Featherweight Java in Isabelle/HOL
Authors: J. Nathan Foster and Dimitrios Vytiniotis
2006-03-15: Instances of Schneider's generalized protocol of clock synchronization
Author: Damián Barsotti
2006-03-14: Cauchy's Mean Theorem and the Cauchy-Schwarz Inequality
Author: Benjamin Porter

 

2005
2005-11-11: Countable Ordinals
Author: Brian Huffman
2005-10-12: Fast Fourier Transform
Author: Clemens Ballarin
2005-06-24: Formalization of a Generalized Protocol for Clock Synchronization
Author: Alwen Tiu
2005-06-22: Proving the Correctness of Disk Paxos
Authors: Mauro Jaskelioff and Stephan Merz
2005-06-20: Jive Data and Store Model
Authors: Nicole Rauch and Norbert Schirmer
2005-06-01: Jinja is not Java
Authors: Gerwin Klein and Tobias Nipkow
2005-05-02: SHA1, RSA, PSS and more
Authors: Christina Lindenberg and Kai Wirt
2005-04-21: Category Theory to Yoneda's Lemma
Author: Greg O'Keefe

 

2004
2004-12-09: File Refinement
Authors: Karen Zee and Viktor Kuncak
2004-11-19: Integration theory and random variables
Author: Stefan Richter
2004-09-28: A Mechanically Verified, Efficient, Sound and Complete Theorem Prover For First Order Logic
Author: Tom Ridge
2004-09-20: Ramsey's theorem, infinitary version
Author: Tom Ridge
2004-09-20: Completeness theorem
Authors: James Margetson and Tom Ridge
2004-07-09: Compiling Exceptions Correctly
Author: Tobias Nipkow
2004-06-24: Depth First Search
Authors: Toshiaki Nishihara and Yasuhiko Minamide
2004-05-18: Groups, Rings and Modules
Authors: Hidetsune Kobayashi, L. Chen and H. Murao
2004-04-26: Topology
Author: Stefan Friedrich
2004-04-26: Lazy Lists II
Author: Stefan Friedrich
2004-04-05: Binary Search Trees
Author: Viktor Kuncak
2004-03-30: Functional Automata
Author: Tobias Nipkow
2004-03-19: Mini ML
Authors: Wolfgang Naraschewski and Tobias Nipkow
2004-03-19: AVL Trees
Authors: Tobias Nipkow and Cornelia Pusch
\ No newline at end of file diff --git a/web/rss.xml b/web/rss.xml --- a/web/rss.xml +++ b/web/rss.xml @@ -1,607 +1,607 @@ Archive of Formal Proofs https://www.isa-afp.org The Archive of Formal Proofs is a collection of proof libraries, examples, and larger scientific developments, mechanically checked in the theorem prover Isabelle. 18 Jan 2021 00:00:00 +0000 Hood-Melville Queue https://www.isa-afp.org/entries/Hood_Melville_Queue.html https://www.isa-afp.org/entries/Hood_Melville_Queue.html Alejandro Gómez-Londoño 18 Jan 2021 00:00:00 +0000 This is a verified implementation of a constant time queue. The original design is due to <a href="https://doi.org/10.1016/0020-0190(81)90030-2">Hood and Melville</a>. This formalization follows the presentation in <em>Purely Functional Data Structures</em>by Okasaki. + JinjaDCI: a Java semantics with dynamic class initialization + https://www.isa-afp.org/entries/JinjaDCI.html + https://www.isa-afp.org/entries/JinjaDCI.html + Susannah Mansky + 11 Jan 2021 00:00:00 +0000 + +We extend Jinja to include static fields, methods, and instructions, +and dynamic class initialization, based on the Java SE 8 +specification. This includes extension of definitions and proofs. This +work is partially described in Mansky and Gunter's paper at CPP +2019 and Mansky's doctoral thesis (UIUC, 2020). + + Cofinality and the Delta System Lemma https://www.isa-afp.org/entries/Delta_System_Lemma.html https://www.isa-afp.org/entries/Delta_System_Lemma.html Pedro Sánchez Terraf 27 Dec 2020 00:00:00 +0000 We formalize the basic results on cofinality of linearly ordered sets and ordinals and Šanin’s Lemma for uncountable families of finite sets. This last result is used to prove the countable chain condition for Cohen posets. We work in the set theory framework of Isabelle/ZF, using the Axiom of Choice as needed. Topological semantics for paraconsistent and paracomplete logics https://www.isa-afp.org/entries/Topological_Semantics.html https://www.isa-afp.org/entries/Topological_Semantics.html David Fuenmayor 17 Dec 2020 00:00:00 +0000 We introduce a generalized topological semantics for paraconsistent and paracomplete logics by drawing upon early works on topological Boolean algebras (cf. works by Kuratowski, Zarycki, McKinsey & Tarski, etc.). In particular, this work exemplarily illustrates the shallow semantical embeddings approach (<a href="http://dx.doi.org/10.1007/s11787-012-0052-y">SSE</a>) employing the proof assistant Isabelle/HOL. By means of the SSE technique we can effectively harness theorem provers, model finders and 'hammers' for reasoning with quantified non-classical logics. Relational Minimum Spanning Tree Algorithms https://www.isa-afp.org/entries/Relational_Minimum_Spanning_Trees.html https://www.isa-afp.org/entries/Relational_Minimum_Spanning_Trees.html Walter Guttmann, Nicolas Robinson-O'Brien 08 Dec 2020 00:00:00 +0000 We verify the correctness of Prim's, Kruskal's and Borůvka's minimum spanning tree algorithms based on algebras for aggregation and minimisation. Inline Caching and Unboxing Optimization for Interpreters https://www.isa-afp.org/entries/Interpreter_Optimizations.html https://www.isa-afp.org/entries/Interpreter_Optimizations.html Martin Desharnais 07 Dec 2020 00:00:00 +0000 This Isabelle/HOL formalization builds on the <em>VeriComp</em> entry of the <em>Archive of Formal Proofs</em> to provide the following contributions: <ul> <li>an operational semantics for a realistic virtual machine (Std) for dynamically typed programming languages;</li> <li>the formalization of an inline caching optimization (Inca), a proof of bisimulation with (Std), and a compilation function;</li> <li>the formalization of an unboxing optimization (Ubx), a proof of bisimulation with (Inca), and a simple compilation function.</li> </ul> This formalization was described in the CPP 2021 paper <em>Towards Efficient and Verified Virtual Machines for Dynamic Languages</em> The Relational Method with Message Anonymity for the Verification of Cryptographic Protocols https://www.isa-afp.org/entries/Relational_Method.html https://www.isa-afp.org/entries/Relational_Method.html Pasquale Noce 05 Dec 2020 00:00:00 +0000 This paper introduces a new method for the formal verification of cryptographic protocols, the relational method, derived from Paulson's inductive method by means of some enhancements aimed at streamlining formal definitions and proofs, specially for protocols using public key cryptography. Moreover, this paper proposes a method to formalize a further security property, message anonymity, in addition to message confidentiality and authenticity. The relational method, including message anonymity, is then applied to the verification of a sample authentication protocol, comprising Password Authenticated Connection Establishment (PACE) with Chip Authentication Mapping followed by the explicit verification of an additional password over the PACE secure channel. Isabelle Marries Dirac: a Library for Quantum Computation and Quantum Information https://www.isa-afp.org/entries/Isabelle_Marries_Dirac.html https://www.isa-afp.org/entries/Isabelle_Marries_Dirac.html Anthony Bordg, Hanna Lachnitt, Yijun He 22 Nov 2020 00:00:00 +0000 This work is an effort to formalise some quantum algorithms and results in quantum information theory. Formal methods being critical for the safety and security of algorithms and protocols, we foresee their widespread use for quantum computing in the future. We have developed a large library for quantum computing in Isabelle based on a matrix representation for quantum circuits, successfully formalising the no-cloning theorem, quantum teleportation, Deutsch's algorithm, the Deutsch-Jozsa algorithm and the quantum Prisoner's Dilemma. The HOL-CSP Refinement Toolkit https://www.isa-afp.org/entries/CSP_RefTK.html https://www.isa-afp.org/entries/CSP_RefTK.html Safouan Taha, Burkhart Wolff, Lina Ye 19 Nov 2020 00:00:00 +0000 We use a formal development for CSP, called HOL-CSP2.0, to analyse a family of refinement notions, comprising classic and new ones. This analysis enables to derive a number of properties that allow to deepen the understanding of these notions, in particular with respect to specification decomposition principles for the case of infinite sets of events. The established relations between the refinement relations help to clarify some obscure points in the CSP literature, but also provide a weapon for shorter refinement proofs. Furthermore, we provide a framework for state-normalisation allowing to formally reason on parameterised process architectures. As a result, we have a modern environment for formal proofs of concurrent systems that allow for the combination of general infinite processes with locally finite ones in a logically safe way. We demonstrate these verification-techniques for classical, generalised examples: The CopyBuffer for arbitrary data and the Dijkstra's Dining Philosopher Problem of arbitrary size. Verified SAT-Based AI Planning https://www.isa-afp.org/entries/Verified_SAT_Based_AI_Planning.html https://www.isa-afp.org/entries/Verified_SAT_Based_AI_Planning.html Mohammad Abdulaziz, Friedrich Kurz 29 Oct 2020 00:00:00 +0000 We present an executable formally verified SAT encoding of classical AI planning that is based on the encodings by Kautz and Selman and the one by Rintanen et al. The encoding was experimentally tested and shown to be usable for reasonably sized standard AI planning benchmarks. We also use it as a reference to test a state-of-the-art SAT-based planner, showing that it sometimes falsely claims that problems have no solutions of certain lengths. The formalisation in this submission was described in an independent publication. AI Planning Languages Semantics https://www.isa-afp.org/entries/AI_Planning_Languages_Semantics.html https://www.isa-afp.org/entries/AI_Planning_Languages_Semantics.html Mohammad Abdulaziz, Peter Lammich 29 Oct 2020 00:00:00 +0000 This is an Isabelle/HOL formalisation of the semantics of the multi-valued planning tasks language that is used by the planning system Fast-Downward, the STRIPS fragment of the Planning Domain Definition Language (PDDL), and the STRIPS soundness meta-theory developed by Vladimir Lifschitz. It also contains formally verified checkers for checking the well-formedness of problems specified in either language as well the correctness of potential solutions. The formalisation in this entry was described in an earlier publication. A Sound Type System for Physical Quantities, Units, and Measurements https://www.isa-afp.org/entries/Physical_Quantities.html https://www.isa-afp.org/entries/Physical_Quantities.html Simon Foster, Burkhart Wolff 20 Oct 2020 00:00:00 +0000 The present Isabelle theory builds a formal model for both the International System of Quantities (ISQ) and the International System of Units (SI), which are both fundamental for physics and engineering. Both the ISQ and the SI are deeply integrated into Isabelle's type system. Quantities are parameterised by dimension types, which correspond to base vectors, and thus only quantities of the same dimension can be equated. Since the underlying "algebra of quantities" induces congruences on quantity and SI types, specific tactic support is developed to capture these. Our construction is validated by a test-set of known equivalences between both quantities and SI units. Moreover, the presented theory can be used for type-safe conversions between the SI system and others, like the British Imperial System (BIS). Finite Map Extras https://www.isa-afp.org/entries/Finite-Map-Extras.html https://www.isa-afp.org/entries/Finite-Map-Extras.html Javier Díaz 12 Oct 2020 00:00:00 +0000 This entry includes useful syntactic sugar, new operators and functions, and their associated lemmas for finite maps which currently are not present in the standard Finite_Map theory. A Formal Model of the Safely Composable Document Object Model with Shadow Roots https://www.isa-afp.org/entries/Shadow_SC_DOM.html https://www.isa-afp.org/entries/Shadow_SC_DOM.html Achim D. Brucker, Michael Herzberg 28 Sep 2020 00:00:00 +0000 In this AFP entry, we extend our formalization of the safely composable DOM with Shadow Roots. This is a proposal for Shadow Roots with stricter safety guarantess than the standard compliant formalization (see "Shadow DOM"). Shadow Roots are a recent proposal of the web community to support a component-based development approach for client-side web applications. Shadow roots are a significant extension to the DOM standard and, as web standards are condemned to be backward compatible, such extensions often result in complex specification that may contain unwanted subtleties that can be detected by a formalization. Our Isabelle/HOL formalization is, in the sense of object-orientation, an extension of our formalization of the core DOM and enjoys the same basic properties, i.e., it is extensible, i.e., can be extended without the need of re-proving already proven properties and executable, i.e., we can generate executable code from our specification. We exploit the executability to show that our formalization complies to the official standard of the W3C, respectively, the WHATWG. A Formal Model of the Document Object Model with Shadow Roots https://www.isa-afp.org/entries/Shadow_DOM.html https://www.isa-afp.org/entries/Shadow_DOM.html Achim D. Brucker, Michael Herzberg 28 Sep 2020 00:00:00 +0000 In this AFP entry, we extend our formalization of the core DOM with Shadow Roots. Shadow roots are a recent proposal of the web community to support a component-based development approach for client-side web applications. Shadow roots are a significant extension to the DOM standard and, as web standards are condemned to be backward compatible, such extensions often result in complex specification that may contain unwanted subtleties that can be detected by a formalization. Our Isabelle/HOL formalization is, in the sense of object-orientation, an extension of our formalization of the core DOM and enjoys the same basic properties, i.e., it is extensible, i.e., can be extended without the need of re-proving already proven properties and executable, i.e., we can generate executable code from our specification. We exploit the executability to show that our formalization complies to the official standard of the W3C, respectively, the WHATWG. A Formalization of Safely Composable Web Components https://www.isa-afp.org/entries/SC_DOM_Components.html https://www.isa-afp.org/entries/SC_DOM_Components.html Achim D. Brucker, Michael Herzberg 28 Sep 2020 00:00:00 +0000 While the (safely composable) DOM with shadow trees provide the technical basis for defining web components, it does neither defines the concept of web components nor specifies the safety properties that web components should guarantee. Consequently, the standard also does not discuss how or even if the methods for modifying the DOM respect component boundaries. In AFP entry, we present a formally verified model of safely composable web components and define safety properties which ensure that different web components can only interact with each other using well-defined interfaces. Moreover, our verification of the application programming interface (API) of the DOM revealed numerous invariants that implementations of the DOM API need to preserve to ensure the integrity of components. In comparison to the strict standard compliance formalization of Web Components in the AFP entry "DOM_Components", the notion of components in this entry (based on "SC_DOM" and "Shadow_SC_DOM") provides much stronger safety guarantees. A Formalization of Web Components https://www.isa-afp.org/entries/DOM_Components.html https://www.isa-afp.org/entries/DOM_Components.html Achim D. Brucker, Michael Herzberg 28 Sep 2020 00:00:00 +0000 While the DOM with shadow trees provide the technical basis for defining web components, the DOM standard neither defines the concept of web components nor specifies the safety properties that web components should guarantee. Consequently, the standard also does not discuss how or even if the methods for modifying the DOM respect component boundaries. In AFP entry, we present a formally verified model of web components and define safety properties which ensure that different web components can only interact with each other using well-defined interfaces. Moreover, our verification of the application programming interface (API) of the DOM revealed numerous invariants that implementations of the DOM API need to preserve to ensure the integrity of components. The Safely Composable DOM https://www.isa-afp.org/entries/Core_SC_DOM.html https://www.isa-afp.org/entries/Core_SC_DOM.html Achim D. Brucker, Michael Herzberg 28 Sep 2020 00:00:00 +0000 In this AFP entry, we formalize the core of the Safely Composable Document Object Model (SC DOM). The SC DOM improve the standard DOM (as formalized in the AFP entry "Core DOM") by strengthening the tree boundaries set by shadow roots: in the SC DOM, the shadow root is a sub-class of the document class (instead of a base class). This modifications also results in changes to some API methods (e.g., getOwnerDocument) to return the nearest shadow root rather than the document root. As a result, many API methods that, when called on a node inside a shadow tree, would previously ``break out'' and return or modify nodes that are possibly outside the shadow tree, now stay within its boundaries. This change in behavior makes programs that operate on shadow trees more predictable for the developer and allows them to make more assumptions about other code accessing the DOM. Syntax-Independent Logic Infrastructure https://www.isa-afp.org/entries/Syntax_Independent_Logic.html https://www.isa-afp.org/entries/Syntax_Independent_Logic.html Andrei Popescu, Dmitriy Traytel 16 Sep 2020 00:00:00 +0000 We formalize a notion of logic whose terms and formulas are kept abstract. In particular, logical connectives, substitution, free variables, and provability are not defined, but characterized by their general properties as locale assumptions. Based on this abstract characterization, we develop further reusable reasoning infrastructure. For example, we define parallel substitution (along with proving its characterizing theorems) from single-point substitution. Similarly, we develop a natural deduction style proof system starting from the abstract Hilbert-style one. These one-time efforts benefit different concrete logics satisfying our locales' assumptions. We instantiate the syntax-independent logic infrastructure to Robinson arithmetic (also known as Q) in the AFP entry <a href="https://www.isa-afp.org/entries/Robinson_Arithmetic.html">Robinson_Arithmetic</a> and to hereditarily finite set theory in the AFP entries <a href="https://www.isa-afp.org/entries/Goedel_HFSet_Semantic.html">Goedel_HFSet_Semantic</a> and <a href="https://www.isa-afp.org/entries/Goedel_HFSet_Semanticless.html">Goedel_HFSet_Semanticless</a>, which are part of our formalization of G&ouml;del's Incompleteness Theorems described in our CADE-27 paper <a href="https://dx.doi.org/10.1007/978-3-030-29436-6_26">A Formally Verified Abstract Account of Gödel's Incompleteness Theorems</a>. Robinson Arithmetic https://www.isa-afp.org/entries/Robinson_Arithmetic.html https://www.isa-afp.org/entries/Robinson_Arithmetic.html Andrei Popescu, Dmitriy Traytel 16 Sep 2020 00:00:00 +0000 We instantiate our syntax-independent logic infrastructure developed in <a href="https://www.isa-afp.org/entries/Syntax_Independent_Logic.html">a separate AFP entry</a> to the FOL theory of Robinson arithmetic (also known as Q). The latter was formalised using Nominal Isabelle by adapting <a href="https://www.isa-afp.org/entries/Incompleteness.html">Larry Paulson’s formalization of the Hereditarily Finite Set theory</a>. An Abstract Formalization of Gödel's Incompleteness Theorems https://www.isa-afp.org/entries/Goedel_Incompleteness.html https://www.isa-afp.org/entries/Goedel_Incompleteness.html Andrei Popescu, Dmitriy Traytel 16 Sep 2020 00:00:00 +0000 We present an abstract formalization of G&ouml;del's incompleteness theorems. We analyze sufficient conditions for the theorems' applicability to a partially specified logic. Our abstract perspective enables a comparison between alternative approaches from the literature. These include Rosser's variation of the first theorem, Jeroslow's variation of the second theorem, and the Swierczkowski&ndash;Paulson semantics-based approach. This AFP entry is the main entry point to the results described in our CADE-27 paper <a href="https://dx.doi.org/10.1007/978-3-030-29436-6_26">A Formally Verified Abstract Account of Gödel's Incompleteness Theorems</a>. As part of our abstract formalization's validation, we instantiate our locales twice in the separate AFP entries <a href="https://www.isa-afp.org/entries/Goedel_HFSet_Semantic.html">Goedel_HFSet_Semantic</a> and <a href="https://www.isa-afp.org/entries/Goedel_HFSet_Semanticless.html">Goedel_HFSet_Semanticless</a>. From Abstract to Concrete Gödel's Incompleteness Theorems—Part II https://www.isa-afp.org/entries/Goedel_HFSet_Semanticless.html https://www.isa-afp.org/entries/Goedel_HFSet_Semanticless.html Andrei Popescu, Dmitriy Traytel 16 Sep 2020 00:00:00 +0000 We validate an abstract formulation of G&ouml;del's Second Incompleteness Theorem from a <a href="https://www.isa-afp.org/entries/Goedel_Incompleteness.html">separate AFP entry</a> by instantiating it to the case of <i>finite consistent extensions of the Hereditarily Finite (HF) Set theory</i>, i.e., consistent FOL theories extending the HF Set theory with a finite set of axioms. The instantiation draws heavily on infrastructure previously developed by Larry Paulson in his <a href="https://www.isa-afp.org/entries/Incompleteness.html">direct formalisation of the concrete result</a>. It strengthens Paulson's formalization of G&ouml;del's Second from that entry by <i>not</i> assuming soundness, and in fact not relying on any notion of model or semantic interpretation. The strengthening was obtained by first replacing some of Paulson’s semantic arguments with proofs within his HF calculus, and then plugging in some of Paulson's (modified) lemmas to instantiate our soundness-free G&ouml;del's Second locale. From Abstract to Concrete Gödel's Incompleteness Theorems—Part I https://www.isa-afp.org/entries/Goedel_HFSet_Semantic.html https://www.isa-afp.org/entries/Goedel_HFSet_Semantic.html Andrei Popescu, Dmitriy Traytel 16 Sep 2020 00:00:00 +0000 We validate an abstract formulation of G&ouml;del's First and Second Incompleteness Theorems from a <a href="https://www.isa-afp.org/entries/Goedel_Incompleteness.html">separate AFP entry</a> by instantiating them to the case of <i>finite sound extensions of the Hereditarily Finite (HF) Set theory</i>, i.e., FOL theories extending the HF Set theory with a finite set of axioms that are sound in the standard model. The concrete results had been previously formalised in an <a href="https://www.isa-afp.org/entries/Incompleteness.html">AFP entry by Larry Paulson</a>; our instantiation reuses the infrastructure developed in that entry. A Formal Model of Extended Finite State Machines https://www.isa-afp.org/entries/Extended_Finite_State_Machines.html https://www.isa-afp.org/entries/Extended_Finite_State_Machines.html Michael Foster, Achim D. Brucker, Ramsay G. Taylor, John Derrick 07 Sep 2020 00:00:00 +0000 In this AFP entry, we provide a formalisation of extended finite state machines (EFSMs) where models are represented as finite sets of transitions between states. EFSMs execute traces to produce observable outputs. We also define various simulation and equality metrics for EFSMs in terms of traces and prove their strengths in relation to each other. Another key contribution is a framework of function definitions such that LTL properties can be phrased over EFSMs. Finally, we provide a simple example case study in the form of a drinks machine. Inference of Extended Finite State Machines https://www.isa-afp.org/entries/Extended_Finite_State_Machine_Inference.html https://www.isa-afp.org/entries/Extended_Finite_State_Machine_Inference.html Michael Foster, Achim D. Brucker, Ramsay G. Taylor, John Derrick 07 Sep 2020 00:00:00 +0000 In this AFP entry, we provide a formal implementation of a state-merging technique to infer extended finite state machines (EFSMs), complete with output and update functions, from black-box traces. In particular, we define the subsumption in context relation as a means of determining whether one transition is able to account for the behaviour of another. Building on this, we define the direct subsumption relation, which lifts the subsumption in context relation to EFSM level such that we can use it to determine whether it is safe to merge a given pair of transitions. Key proofs include the conditions necessary for subsumption to occur and that subsumption and direct subsumption are preorder relations. We also provide a number of different heuristics which can be used to abstract away concrete values into registers so that more states and transitions can be merged and provide proofs of the various conditions which must hold for these abstractions to subsume their ungeneralised counterparts. A Code Generator setup to create executable Scala code is also defined. Practical Algebraic Calculus Checker https://www.isa-afp.org/entries/PAC_Checker.html https://www.isa-afp.org/entries/PAC_Checker.html Mathias Fleury, Daniela Kaufmann 31 Aug 2020 00:00:00 +0000 Generating and checking proof certificates is important to increase the trust in automated reasoning tools. In recent years formal verification using computer algebra became more important and is heavily used in automated circuit verification. An existing proof format which covers algebraic reasoning and allows efficient proof checking is the practical algebraic calculus (PAC). In this development, we present the verified checker Pastèque that is obtained by synthesis via the Refinement Framework. This is the formalization going with our FMCAD'20 tool presentation. Some classical results in inductive inference of recursive functions https://www.isa-afp.org/entries/Inductive_Inference.html https://www.isa-afp.org/entries/Inductive_Inference.html Frank J. Balbach 31 Aug 2020 00:00:00 +0000 <p> This entry formalizes some classical concepts and results from inductive inference of recursive functions. In the basic setting a partial recursive function ("strategy") must identify ("learn") all functions from a set ("class") of recursive functions. To that end the strategy receives more and more values $f(0), f(1), f(2), \ldots$ of some function $f$ from the given class and in turn outputs descriptions of partial recursive functions, for example, Gödel numbers. The strategy is considered successful if the sequence of outputs ("hypotheses") converges to a description of $f$. A class of functions learnable in this sense is called "learnable in the limit". The set of all these classes is denoted by LIM. </p> <p> Other types of inference considered are finite learning (FIN), behaviorally correct learning in the limit (BC), and some variants of LIM with restrictions on the hypotheses: total learning (TOTAL), consistent learning (CONS), and class-preserving learning (CP). The main results formalized are the proper inclusions $\mathrm{FIN} \subset \mathrm{CP} \subset \mathrm{TOTAL} \subset \mathrm{CONS} \subset \mathrm{LIM} \subset \mathrm{BC} \subset 2^{\mathcal{R}}$, where $\mathcal{R}$ is the set of all total recursive functions. Further results show that for all these inference types except CONS, strategies can be assumed to be total recursive functions; that all inference types but CP are closed under the subset relation between classes; and that no inference type is closed under the union of classes. </p> <p> The above is based on a formalization of recursive functions heavily inspired by the <a href="https://www.isa-afp.org/entries/Universal_Turing_Machine.html">Universal Turing Machine</a> entry by Xu et al., but different in that it models partial functions with codomain <em>nat option</em>. The formalization contains a construction of a universal partial recursive function, without resorting to Turing machines, introduces decidability and recursive enumerability, and proves some standard results: existence of a Kleene normal form, the <em>s-m-n</em> theorem, Rice's theorem, and assorted fixed-point theorems (recursion theorems) by Kleene, Rogers, and Smullyan. </p> Relational Disjoint-Set Forests https://www.isa-afp.org/entries/Relational_Disjoint_Set_Forests.html https://www.isa-afp.org/entries/Relational_Disjoint_Set_Forests.html Walter Guttmann 26 Aug 2020 00:00:00 +0000 We give a simple relation-algebraic semantics of read and write operations on associative arrays. The array operations seamlessly integrate with assignments in the Hoare-logic library. Using relation algebras and Kleene algebras we verify the correctness of an array-based implementation of disjoint-set forests with a naive union operation and a find operation with path compression. Extensions to the Comprehensive Framework for Saturation Theorem Proving https://www.isa-afp.org/entries/Saturation_Framework_Extensions.html https://www.isa-afp.org/entries/Saturation_Framework_Extensions.html Jasmin Blanchette, Sophie Tourret 25 Aug 2020 00:00:00 +0000 This Isabelle/HOL formalization extends the AFP entry <em>Saturation_Framework</em> with the following contributions: <ul> <li>an application of the framework to prove Bachmair and Ganzinger's resolution prover RP refutationally complete, which was formalized in a more ad hoc fashion by Schlichtkrull et al. in the AFP entry <em>Ordered_Resultion_Prover</em>;</li> <li>generalizations of various basic concepts formalized by Schlichtkrull et al., which were needed to verify RP and could be useful to formalize other calculi, such as superposition;</li> <li>alternative proofs of fairness (and hence saturation and ultimately refutational completeness) for the given clause procedures GC and LGC, based on invariance.</li> </ul> Putting the `K' into Bird's derivation of Knuth-Morris-Pratt string matching https://www.isa-afp.org/entries/BirdKMP.html https://www.isa-afp.org/entries/BirdKMP.html Peter Gammie 25 Aug 2020 00:00:00 +0000 Richard Bird and collaborators have proposed a derivation of an intricate cyclic program that implements the Morris-Pratt string matching algorithm. Here we provide a proof of total correctness for Bird's derivation and complete it by adding Knuth's optimisation. - - Amicable Numbers - https://www.isa-afp.org/entries/Amicable_Numbers.html - https://www.isa-afp.org/entries/Amicable_Numbers.html - Angeliki Koutsoukou-Argyraki - 04 Aug 2020 00:00:00 +0000 - -This is a formalisation of Amicable Numbers, involving some relevant -material including Euler's sigma function, some relevant -definitions, results and examples as well as rules such as -Th&#257;bit ibn Qurra's Rule, Euler's Rule, te -Riele's Rule and Borho's Rule with breeders. - diff --git a/web/statistics.html b/web/statistics.html --- a/web/statistics.html +++ b/web/statistics.html @@ -1,302 +1,302 @@ Archive of Formal Proofs

 

 

 

 

 

 

Statistics

 

Statistics

- - - - + + + +
Number of Articles:578
Number of Authors:371
Number of lemmas:~161,500
Lines of Code:~2,826,100
Number of Articles:579
Number of Authors:372
Number of lemmas:~162,200
Lines of Code:~2,826,300

Most used AFP articles:

- +
NameUsed by ? articles
1. List-Index1617
2. Coinductive 12
Collections 12
Regular-Sets 12
3. Landau_Symbols 11
Show 11
4. Polynomial_Factorization 10
5. Abstract-Rewriting 9
Automatic_Refinement 9
Deriving 9
Jordan_Normal_Form 9

Growth in number of articles:

Growth in lines of code:

Growth in number of authors:

Size of articles:

\ No newline at end of file diff --git a/web/topics.html b/web/topics.html --- a/web/topics.html +++ b/web/topics.html @@ -1,936 +1,937 @@ Archive of Formal Proofs

 

 

 

 

 

 

Index by Topic

 

Computer science

Artificial intelligence

Automata and formal languages

Algorithms

Knuth_Morris_Pratt   Probabilistic_While   Comparison_Sort_Lower_Bound   Quick_Sort_Cost   TortoiseHare   Selection_Heap_Sort   VerifyThis2018   CYK   Boolean_Expression_Checkers   Efficient-Mergesort   SATSolverVerification   MuchAdoAboutTwo   First_Order_Terms   Monad_Memo_DP   Hidden_Markov_Models   Imperative_Insertion_Sort   Formal_SSA   ROBDD   Median_Of_Medians_Selection   Fisher_Yates   Optimal_BST   IMP2   Auto2_Imperative_HOL   List_Inversions   IMP2_Binary_Heap   MFOTL_Monitor   Adaptive_State_Counting   Generic_Join   VerifyThis2019   Generalized_Counting_Sort   MFODL_Monitor_Optimized   Sliding_Window_Algorithm   PAC_Checker   Graph: DFS_Framework   Prpu_Maxflow   Floyd_Warshall   Roy_Floyd_Warshall   Dijkstra_Shortest_Path   EdmondsKarp_Maxflow   Depth-First-Search   GraphMarkingIBP   Transitive-Closure   Transitive-Closure-II   Gabow_SCC   Kruskal   Prim_Dijkstra_Simple   Relational_Minimum_Spanning_Trees   Distributed: DiskPaxos   GenClock   ClockSynchInst   Heard_Of   Consensus_Refined   Abortable_Linearizable_Modules   IMAP-CRDT   CRDT   Chandy_Lamport   OpSets   Stellar_Quorums   WOOT_Strong_Eventual_Consistency   Concurrent: ConcurrentGC   Online: List_Update   Geometry: Closest_Pair_Points   Approximation: Approximation_Algorithms   Mathematical: FFT   Gauss-Jordan-Elim-Fun   UpDown_Scheme   Polynomials   Gauss_Jordan   Echelon_Form   QR_Decomposition   Hermite   Groebner_Bases   Diophantine_Eqns_Lin_Hom   Taylor_Models   LLL_Basis_Reduction   Signature_Groebner   Smith_Normal_Form   Safe_Distance   Optimization: Simplex   Quantum computing: Isabelle_Marries_Dirac  

Concurrency

Data structures

Functional programming

Hardware

SPARCv8  

Machine learning

Networks

Programming languages

Clean   Decl_Sem_Fun_PL   Language definitions: CakeML   WebAssembly   pGCL   GPU_Kernel_PL   LightweightJava   CoreC++   FeatherweightJava   Jinja   JinjaThreads   Locally-Nameless-Sigma   AutoFocus-Stream   FocusStreamsCaseStudies   Isabelle_Meta_Model   Simpl   Complx   Safe_OCL   Isabelle_C   + JinjaDCI   Lambda calculi: Higher_Order_Terms   Launchbury   PCF   POPLmark-deBruijn   Lam-ml-Normalization   LambdaMu   Binding_Syntax_Theory   LambdaAuth   Type systems: Name_Carrying_Type_Inference   MiniML   Possibilistic_Noninterference   SIFUM_Type_Systems   Dependent_SIFUM_Type_Systems   Strong_Security   WHATandWHERE_Security   VolpanoSmith   Physical_Quantities   Logics: ConcurrentIMP   Refine_Monadic   Automatic_Refinement   MonoBoolTranAlgebra   Simpl   Separation_Algebra   Separation_Logic_Imperative_HOL   Relational-Incorrectness-Logic   Abstract-Hoare-Logics   Kleene_Algebra   KAT_and_DRA   KAD   BytecodeLogicJmlTypes   DataRefinementIBP   RefinementReactive   SIFPL   TLA   Ribbon_Proofs   Separata   Complx   Differential_Dynamic_Logic   Hoare_Time   IMP2   UTP   QHLProver   Differential_Game_Logic   Compiling: CakeML_Codegen   Compiling-Exceptions-Correctly   NormByEval   Density_Compiler   VeriComp   Static analysis: RIPEMD-160-SPARK   Program-Conflict-Analysis   Shivers-CFA   Slicing   HRB-Slicing   InfPathElimination   Abs_Int_ITP2012   Transformations: Call_Arity   Refine_Imperative_HOL   WorkerWrapper   Monad_Memo_DP   Formal_SSA   Minimal_SSA   Misc: JiveDataStoreModel   Pop_Refinement   Case_Labeling   Interpreter_Optimizations  

Security

Semantics

System description languages

Logic

Philosophical aspects

General logic

Computability

Set theory

Proof theory

Rewriting

Mathematics

Order

Algebra

Analysis

Probability theory

Number theory

Games and economics

Geometry

Topology

Graph theory

Combinatorics

Category theory

Physics

Misc

Tools

\ No newline at end of file