diff --git a/metadata/metadata b/metadata/metadata --- a/metadata/metadata +++ b/metadata/metadata @@ -1,9029 +1,9096 @@ [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? [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 +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) + (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. 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)
[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. 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)
[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)
[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 = [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 +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 +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, Computer Science/Automata and Formal Languages +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 +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 +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. 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 [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 = grewe@cs.tu-darmstadt.de [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 = grewe@cs.tu-darmstadt.de [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 = grewe@cs.tu-darmstadt.de [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 +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 +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 +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 +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 +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 +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 +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 +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 +topic = Logic/General logic/Decidability of theories 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 +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 +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 +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, Computer Science/Automata and Formal Languages +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 +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 +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/Philosophy +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/Philosophy +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/Philosophy +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/Philosophy +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/Philosophy +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 +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 +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.

[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 [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 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 +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 +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 +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 +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 +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! ∼ √2πn (n/e)n on natural numbers and the real Gamma function Γ(x) ∼ √2π/x (x/e)x. The proof is based on work by Graham Jameson. [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, Mathematics/Order +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 +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 +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 +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 +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, Computer Science/Programming Languages/Logics +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. [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. 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 +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/Philosophy +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. [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. [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 +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. [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 +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. [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 +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 +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. [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 +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, Computer Science/Automata and Formal Languages +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 forthcoming 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. [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 +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. [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/Philosophy +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 = Mathematics/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 +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 the cited 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 the general ones admissible. Finally, the GoTo rule is restricted using a notion of coins such that each application consumes a coin and coins are 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 coin. These restrictions are imposed to rule out some means of nontermination. [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. 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)
[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 = +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. + +[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. + + diff --git a/metadata/topics b/metadata/topics --- a/metadata/topics +++ b/metadata/topics @@ -1,50 +1,63 @@ Computer Science Automata and Formal Languages Algorithms Graph Distributed Concurrent Online Geometry Approximation Mathematical Optimization Concurrency Process Calculi Data Structures Functional Programming Hardware Machine Learning Networks Programming Languages Language Definitions Lambda Calculi Type Systems Logics Compiling Static Analysis Transformations Misc Security Cryptography Semantics System Description Languages Logic - Philosophy + Philosophical aspects + General logic + Classical propositional logic + Classical first-order logic + Decidability of theories + Mechanization of proofs + Lambda calculus + Logics of knowledge and belief + Temporal logic + Modal logic + Paraconsistent logics + 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 Set Theory Misc Tools diff --git a/thys/MFODL_Monitor_Optimized/Abstract_Monitor.thy b/thys/MFODL_Monitor_Optimized/Abstract_Monitor.thy new file mode 100644 --- /dev/null +++ b/thys/MFODL_Monitor_Optimized/Abstract_Monitor.thy @@ -0,0 +1,227 @@ +(*<*) +theory Abstract_Monitor + imports Formula +begin +(*>*) + +section \Abstract monitor specification\ + +locale monitorable = + fixes monitorable :: "Formula.formula \ bool" + +text \The following locale specifies the desired behavior ouf a monitor abstractly.\ + +locale monitor = monitorable + + fixes + M :: "Formula.formula \ Formula.prefix \ (nat \ event_data tuple) set" + assumes + mono_monitor: "monitorable \ \ \ \ \' \ M \ \ \ M \ \'" + and sound_monitor: "monitorable \ \ (i, v) \ M \ \ \ + i < plen \ \ wf_tuple (Formula.nfv \) (Formula.fv \) v \ (\\. prefix_of \ \ \ Formula.sat \ Map.empty (map the v) i \)" + and complete_monitor: "monitorable \ \ prefix_of \ \ \ + i < plen \ \ wf_tuple (Formula.nfv \) (Formula.fv \) v \ + (\\. prefix_of \ \ \ Formula.sat \ Map.empty (map the v) i \) \ \\'. prefix_of \' \ \ (i, v) \ M \ \'" + +locale slicable_monitor = monitor + + assumes monitor_slice: "mem_restr S v \ (i, v) \ M \ (Formula.pslice \ S \) \ (i, v) \ M \ \" + +locale monitor_pre_progress = monitorable + + fixes progress :: "Formula.trace \ Formula.formula \ nat \ nat" + assumes + progress_mono: "j \ j' \ progress \ \ j \ progress \ \ j'" + and progress_le: "progress \ \ j \ j" + and progress_ge: "monitorable \ \ \j. i \ progress \ \ j" + +locale monitor_progress = monitor_pre_progress + + assumes progress_prefix_conv: "prefix_of \ \ \ prefix_of \ \' \ + progress \ \ (plen \) = progress \' \ (plen \)" +begin + +definition verdicts :: "Formula.formula \ Formula.prefix \ (nat \ event_data tuple) set" where + "verdicts \ \ = {(i, v). wf_tuple (Formula.nfv \) (Formula.fv \) v \ + (\\. prefix_of \ \ \ i < progress \ \ (plen \) \ Formula.sat \ Map.empty (map the v) i \)}" + +lemma verdicts_mono: "\ \ \' \ verdicts \ \ \ verdicts \ \'" + unfolding verdicts_def + by (auto dest: prefix_of_antimono elim!: order.strict_trans2 intro!: progress_mono plen_mono) + +end + +lemma stake_eq_mono: "stake b x = stake b y \ a \ b \ stake a x = stake a y" +proof (induction a arbitrary: b x y) + case 0 + then show ?case by simp +next + case Suca: (Suc a) + show ?case proof (cases b) + case 0 + with Suca show ?thesis by (simp del: stake.simps) + next + case (Suc b') + with Suca show ?thesis by (auto simp only: stake.simps list.inject) + qed +qed + +sublocale monitor_progress \ monitor monitorable verdicts +proof (standard, goal_cases) + case (1 \ \ \') + from 1(2) show ?case by (rule verdicts_mono) +next + case (2 \ i v \) + from \(i, v) \ verdicts \ \\ show ?case + unfolding verdicts_def + using ex_prefix_of[of \] + by (auto elim!: order.strict_trans2 intro!: progress_le) +next + case complete: (3 \ \ \ i v) + from \monitorable \\ obtain j where eval: "i < progress \ \ j" + unfolding less_eq_Suc_le + using progress_ge by blast + define j' where "j' = max (plen \) j" + then have "plen \ \ j'" by simp + from eval have eval': "i < progress \ \ j'" + unfolding j'_def + by (auto elim: order.strict_trans2 intro!: progress_mono) + from complete(2) \plen \ \ j'\ have "\ \ take_prefix j' \" + proof (transfer fixing: j', goal_cases prefix) + case (prefix \ \) + then have "stake j' \ = stake (length \) \ @ stake (j' - length \) (sdrop (length \) \)" + by (unfold stake_add) auto + with \stake (length \) \ = \\ show ?case + by auto + qed + with complete(4) eval' show ?case using progress_prefix_conv[of "take_prefix j' \" \ \' \ for \'] + unfolding verdicts_def + by (auto intro!: exI[where x="take_prefix j' \"] complete(5)[rule_format] elim: prefix_of_antimono) +qed + +locale monitor_timed_progress = monitor_pre_progress + + assumes progress_time_conv: "\i \ i = \ \' i \ progress \ \ j = progress \' \ j" + and progress_sat_cong: "prefix_of \ \ \ prefix_of \ \' \ i < progress \ \ (plen \) \ + Formula.sat \ Map.empty v i \ \ Formula.sat \' Map.empty v i \" +begin + +lemma progress_map_conv: "progress (map_\ f \) \ j = progress (map_\ g \) \ j" + by (auto intro: progress_time_conv) + +lemma progress_slice_conv: "progress (Formula.slice \' R \) \ j = progress (Formula.slice \' R' \) \ j" + unfolding Formula.slice_def using progress_map_conv . + +lemma progress_slice: "progress (Formula.slice \ R \) \ j = progress \ \ j" + using progress_map_conv[where g=id] by (simp add: Formula.slice_def) + +end + +sublocale monitor_timed_progress \ monitor_progress + by (unfold_locales, auto intro: progress_time_conv \_prefix_conv) + +lemma (in monitor_timed_progress) verdicts_alt: + "verdicts \ \ = {(i, v). wf_tuple (Formula.nfv \) (Formula.fv \) v \ + (\\. prefix_of \ \ \ i < progress \ \ (plen \) \ Formula.sat \ Map.empty (map the v) i \)}" + unfolding verdicts_def + using ex_prefix_of[of \] + by (auto dest: progress_prefix_conv[of \ _ _ \] elim!: progress_sat_cong[THEN iffD1, rotated -1]) + +sublocale monitor_timed_progress \ slicable_monitor monitorable verdicts +proof + fix S :: "event_data list set" and v i \ \ + assume *: "mem_restr S v" + show "((i, v) \ verdicts \ (Formula.pslice \ S \)) = ((i, v) \ verdicts \ \)" (is "?L = ?R") + proof + assume ?L + with * show ?R unfolding verdicts_def + by (auto simp: progress_slice fvi_less_nfv wf_tuple_def elim!: mem_restrE + box_equals[OF sat_slice_iff sat_fv_cong sat_fv_cong, symmetric, THEN iffD1, rotated -1] + dest: spec[of _ "Formula.slice \ S _"] prefix_of_pslice_slice) + next + assume ?R + with * show ?L unfolding verdicts_alt + by (auto simp: progress_slice fvi_less_nfv wf_tuple_def elim!: mem_restrE + box_equals[OF sat_slice_iff sat_fv_cong sat_fv_cong, symmetric, THEN iffD2, rotated -1] + intro: exI[of _ "Formula.slice \ S _"] prefix_of_pslice_slice) + qed +qed + +text \Past-only Formulas.\ + +fun past_only :: "Formula.formula \ bool" where + "past_only (Formula.Pred _ _) = True" +| "past_only (Formula.Eq _ _) = True" +| "past_only (Formula.Less _ _) = True" +| "past_only (Formula.LessEq _ _) = True" +| "past_only (Formula.Let _ _ \ \) = (past_only \ \ past_only \)" +| "past_only (Formula.Neg \) = past_only \" +| "past_only (Formula.Or \ \) = (past_only \ \ past_only \)" +| "past_only (Formula.And \ \) = (past_only \ \ past_only \)" +| "past_only (Formula.Ands l) = (\\\set l. past_only \)" +| "past_only (Formula.Exists \) = past_only \" +| "past_only (Formula.Agg _ _ _ _ \) = past_only \" +| "past_only (Formula.Prev _ \) = past_only \" +| "past_only (Formula.Next _ _) = False" +| "past_only (Formula.Since \ _ \) = (past_only \ \ past_only \)" +| "past_only (Formula.Until \ _ \) = False" +| "past_only (Formula.MatchP _ r) = Regex.pred_regex past_only r" +| "past_only (Formula.MatchF _ _) = False" + +lemma past_only_sat: + assumes "prefix_of \ \" "prefix_of \ \'" + shows "i < plen \ \ dom V = dom V' \ + (\p i. p \ dom V \ i < plen \ \ the (V p) i = the (V' p) i) \ + past_only \ \ Formula.sat \ V v i \ = Formula.sat \' V' v i \" +proof (induction \ arbitrary: V V' v i) + case (Pred e ts) + show ?case proof (cases "V e") + case None + then have "V' e = None" using \dom V = dom V'\ by auto + with None \_prefix_conv[OF assms(1,2) Pred(1)] show ?thesis by simp + next + case (Some a) + moreover obtain a' where "V' e = Some a'" using Some \dom V = dom V'\ by auto + moreover have "the (V e) i = the (V' e) i" + using Some Pred(1,3) by (fastforce intro: domI) + ultimately show ?thesis by simp + qed +next + case (Let p b \ \) + let ?V = "\V \. (V(p \ + \i. {v. length v = Formula.nfv \ - b \ + (\zs. length zs = b \ + Formula.sat \ V (zs @ v) i \)}))" + show ?case unfolding sat.simps proof (rule Let.IH(2)) + show "i < plen \" by fact + from Let.prems show "past_only \" by simp + from Let.prems show "dom (?V V \) = dom (?V V' \')" + by (simp del: fun_upd_apply) + next + fix p' i + assume *: "p' \ dom (?V V \)" "i < plen \" + show "the (?V V \ p') i = the (?V V' \' p') i" proof (cases "p' = p") + case True + with Let \i < plen \\ show ?thesis by auto + next + case False + with * show ?thesis by (auto intro!: Let.prems(3)) + qed + qed +next + case (Ands l) + with \_prefix_conv[OF assms] show ?case by simp +next + case (Prev I \) + with \_prefix_conv[OF assms] show ?case by (simp split: nat.split) +next + case (Since \1 I \2) + with \_prefix_conv[OF assms] show ?case by auto +next + case (MatchP I r) + then have "Regex.match (Formula.sat \ V v) r a b = Regex.match (Formula.sat \' V' v) r a b" if "b < plen \" for a b + using that by (intro Regex.match_cong_strong) (auto simp: regex.pred_set) + with \_prefix_conv[OF assms] MatchP(2) show ?case by auto +qed auto + +interpretation past_only_monitor: monitor_timed_progress past_only "\\ \ j. if past_only \ then j else 0" + by unfold_locales (auto dest: past_only_sat(1) split: if_splits) + +(*<*) +end +(*>*) diff --git a/thys/MFODL_Monitor_Optimized/Code_Double.thy b/thys/MFODL_Monitor_Optimized/Code_Double.thy new file mode 100644 --- /dev/null +++ b/thys/MFODL_Monitor_Optimized/Code_Double.thy @@ -0,0 +1,521 @@ +(*<*) +theory Code_Double + imports IEEE_Floating_Point.IEEE_Properties + "HOL-Library.Code_Target_Int" + Containers.Collection_Eq + Containers.Collection_Order +begin +(*>*) + +section \Code adaptation for IEEE double-precision floats\ + +subsection \copysign\ + +lift_definition copysign :: "('e, 'f) float \ ('e, 'f) float \ ('e, 'f) float" is + "\(_, e::'e word, f::'f word) (s::1 word, _, _). (s, e, f)" . + +lemma is_nan_copysign[simp]: "is_nan (copysign x y) \ is_nan x" + unfolding is_nan_def by transfer auto + + +subsection \Additional lemmas about generic floats\ + +lemma is_nan_some_nan[simp]: "is_nan (some_nan :: ('e, 'f) float)" + unfolding some_nan_def + by (rule someI[where x="Abs_float (0, max_word :: 'e word, 1)"]) + (auto simp add: is_nan_def exponent_def fraction_def emax_def Abs_float_inverse[simplified]) + +lemma not_is_nan_0[simp]: "\ is_nan 0" + unfolding is_nan_def by (simp add: zero_simps) + +lemma not_is_nan_1[simp]: "\ is_nan 1" + unfolding is_nan_def by transfer simp + +lemma is_nan_plus: "is_nan x \ is_nan y \ is_nan (x + y)" + unfolding plus_float_def fadd_def by auto + +lemma is_nan_minus: "is_nan x \ is_nan y \ is_nan (x - y)" + unfolding minus_float_def fsub_def by auto + +lemma is_nan_times: "is_nan x \ is_nan y \ is_nan (x * y)" + unfolding times_float_def fmul_def by auto + +lemma is_nan_divide: "is_nan x \ is_nan y \ is_nan (x / y)" + unfolding divide_float_def fdiv_def by auto + +lemma is_nan_float_sqrt: "is_nan x \ is_nan (float_sqrt x)" + unfolding float_sqrt_def fsqrt_def by simp + +lemma nan_fcompare: "is_nan x \ is_nan y \ fcompare x y = Und" + unfolding fcompare_def by simp + +lemma nan_not_le: "is_nan x \ is_nan y \ \ x \ y" + unfolding less_eq_float_def fle_def fcompare_def by simp + +lemma nan_not_less: "is_nan x \ is_nan y \ \ x < y" + unfolding less_float_def flt_def fcompare_def by simp + +lemma nan_not_zero: "is_nan x \ \ is_zero x" + unfolding is_nan_def is_zero_def by simp + +lemma nan_not_infinity: "is_nan x \ \ is_infinity x" + unfolding is_nan_def is_infinity_def by simp + +lemma zero_not_infinity: "is_zero x \ \ is_infinity x" + unfolding is_zero_def is_infinity_def by simp + +lemma zero_not_nan: "is_zero x \ \ is_nan x" + unfolding is_zero_def is_nan_def by simp + + +lemma minus_one_power_one_word: "(-1 :: real) ^ unat (x :: 1 word) = (if unat x = 0 then 1 else -1)" +proof - + have "unat x = 0 \ unat x = 1" + using le_SucE[OF unat_one_word_le] by auto + then show ?thesis by auto +qed + +definition valofn :: "('e, 'f) float \ real" where + "valofn x = (2^exponent x / 2^bias TYPE(('e, 'f) float)) * + (1 + real (fraction x) / 2^LENGTH('f))" + +definition valofd :: "('e, 'f) float \ real" where + "valofd x = (2 / 2^bias TYPE(('e, 'f) float)) * (real (fraction x) / 2^LENGTH('f))" + +lemma valof_alt: "valof x = (if exponent x = 0 then + if sign x = 0 then valofd x else - valofd x + else if sign x = 0 then valofn x else - valofn x)" + unfolding valofn_def valofd_def + by transfer (auto simp: minus_one_power_one_word unat_eq_0 field_simps) + +lemma fraction_less_2p: "fraction (x :: ('e, 'f) float) < 2^LENGTH('f)" + by transfer auto + +lemma valofn_ge_0: "0 \ valofn x" + unfolding valofn_def by simp + +lemma valofn_ge_2p: "2^exponent (x :: ('e, 'f) float) / 2^bias TYPE(('e, 'f) float) \ valofn x" + unfolding valofn_def by (simp add: field_simps) + +lemma valofn_less_2p: + fixes x :: "('e, 'f) float" + assumes "exponent x < e" + shows "valofn x < 2^e / 2^bias TYPE(('e, 'f) float)" +proof - + have "1 + real (fraction x) / 2^LENGTH('f) < 2" + by (simp add: fraction_less_2p) + then have "valofn x < (2^exponent x / 2^bias TYPE(('e, 'f) float)) * 2" + unfolding valofn_def by (simp add: field_simps) + also have "... \ 2^e / 2^bias TYPE(('e, 'f) float)" + using assms by (auto simp: less_eq_Suc_le field_simps elim: order_trans[rotated, OF exp_less]) + finally show ?thesis . +qed + +lemma valofd_ge_0: "0 \ valofd x" + unfolding valofd_def by simp + +lemma valofd_less_2p: "valofd (x :: ('e, 'f) float) < 2 / 2^bias TYPE(('e, 'f) float)" + unfolding valofd_def + by (simp add: fraction_less_2p field_simps) + +lemma valofn_le_imp_exponent_le: + fixes x y :: "('e, 'f) float" + assumes "valofn x \ valofn y" + shows "exponent x \ exponent y" +proof (rule ccontr) + assume "\ exponent x \ exponent y" + then have "valofn y < 2^exponent x / 2^bias TYPE(('e, 'f) float)" + using valofn_less_2p[of y] by auto + also have "... \ valofn x" by (rule valofn_ge_2p) + finally show False using assms by simp +qed + +lemma valofn_eq: + fixes x y :: "('e, 'f) float" + assumes "valofn x = valofn y" + shows "exponent x = exponent y" "fraction x = fraction y" +proof - + from assms show "exponent x = exponent y" + by (auto intro!: antisym valofn_le_imp_exponent_le) + with assms show "fraction x = fraction y" + unfolding valofn_def by (simp add: field_simps) +qed + +lemma valofd_eq: + fixes x y :: "('e, 'f) float" + assumes "valofd x = valofd y" + shows "fraction x = fraction y" + using assms unfolding valofd_def by (simp add: field_simps) + +lemma is_zero_valof_conv: "is_zero x \ valof x = 0" + unfolding is_zero_def valof_alt + using valofn_ge_2p[of x] by (auto simp: valofd_def field_simps dest: order.antisym) + +lemma valofd_neq_valofn: + fixes x y :: "('e, 'f) float" + assumes "exponent y \ 0" + shows "valofd x \ valofn y" "valofn y \ valofd x" +proof - + have "valofd x < 2 / 2^bias TYPE(('e, 'f) float)" by (rule valofd_less_2p) + also have "... \ 2 ^ IEEE.exponent y / 2 ^ bias TYPE(('e, 'f) IEEE.float)" + using assms by (simp add: self_le_power field_simps) + also have "... \ valofn y" by (rule valofn_ge_2p) + finally show "valofd x \ valofn y" "valofn y \ valofd x" by simp_all +qed + +lemma sign_gt_0_conv: "0 < sign x \ sign x = 1" + by (cases x rule: sign_cases) simp_all + +lemma valof_eq: + assumes "\ is_zero x \ \ is_zero y" + shows "valof x = valof y \ x = y" +proof + assume *: "valof x = valof y" + with assms have "valof y \ 0" by (simp add: is_zero_valof_conv) + with * show "x = y" + unfolding valof_alt + using valofd_ge_0[of x] valofd_ge_0[of y] valofn_ge_0[of x] valofn_ge_0[of y] + by (auto simp: valofd_neq_valofn sign_gt_0_conv split: if_splits + intro!: float_eqI elim: valofn_eq valofd_eq) +qed simp + +lemma zero_fcompare: "is_zero x \ is_zero y \ fcompare x y = ccode.Eq" + unfolding fcompare_def by (simp add: zero_not_infinity zero_not_nan is_zero_valof_conv) + + +subsection \Doubles with a unified NaN value\ + +quotient_type double = "(11, 52) float" / "\x y. is_nan x \ is_nan y \ x = y" + by (auto intro!: equivpI reflpI sympI transpI) + +instantiation double :: "{zero, one, plus, minus, uminus, times, ord}" +begin + +lift_definition zero_double :: "double" is "0" . +lift_definition one_double :: "double" is "1" . + +lift_definition plus_double :: "double \ double \ double" is plus + by (auto simp: is_nan_plus) + +lift_definition minus_double :: "double \ double \ double" is minus + by (auto simp: is_nan_minus) + +lift_definition uminus_double :: "double \ double" is uminus + by auto + +lift_definition times_double :: "double \ double \ double" is times + by (auto simp: is_nan_times) + +lift_definition less_eq_double :: "double \ double \ bool" is "(\)" + by (auto simp: nan_not_le) + +lift_definition less_double :: "double \ double \ bool" is "(<)" + by (auto simp: nan_not_less) + +instance .. + +end + +instantiation double :: inverse +begin + +lift_definition divide_double :: "double \ double \ double" is divide + by (auto simp: is_nan_divide) + +definition inverse_double :: "double \ double" where + "inverse_double x = 1 div x" + +instance .. + +end + +lift_definition sqrt_double :: "double \ double" is float_sqrt + by (auto simp: is_nan_float_sqrt) + +no_notation plus_infinity ("\") + +lift_definition infinity :: "double" is plus_infinity . + +lift_definition nan :: "double" is some_nan . + +lift_definition is_zero :: "double \ bool" is IEEE.is_zero + by (auto simp: nan_not_zero) + +lift_definition is_infinite :: "double \ bool" is IEEE.is_infinity + by (auto simp: nan_not_infinity) + +lift_definition is_nan :: "double \ bool" is IEEE.is_nan + by auto + +lemma is_nan_conv: "is_nan x \ x = nan" + by transfer auto + +lift_definition copysign_double :: "double \ double \ double" is + "\x y. if IEEE.is_nan y then some_nan else copysign x y" + by auto + +text \Note: @{const copysign_double} deviates from the IEEE standard in cases where + the second argument is a NaN.\ + +lift_definition fcompare_double :: "double \ double \ ccode" is fcompare + by (auto simp: nan_fcompare) + +lemma nan_fcompare_double: "is_nan x \ is_nan y \ fcompare_double x y = Und" + by transfer (rule nan_fcompare) + +consts compare_double :: "double \ double \ integer" + +specification (compare_double) + compare_double_less: "compare_double x y < 0 \ is_nan x \ \ is_nan y \ fcompare_double x y = ccode.Lt" + compare_double_eq: "compare_double x y = 0 \ is_nan x \ is_nan y \ fcompare_double x y = ccode.Eq" + compare_double_greater: "compare_double x y > 0 \ \ is_nan x \ is_nan y \ fcompare_double x y = ccode.Gt" + by (rule exI[where x="\x y. if is_nan x then if is_nan y then 0 else -1 + else if is_nan y then 1 else (case fcompare_double x y of ccode.Eq \ 0 | ccode.Lt \ -1 | ccode.Gt \ 1)"], + transfer, auto simp: fcompare_def) + +lemmas compare_double_simps = compare_double_less compare_double_eq compare_double_greater + +lemma compare_double_le_0: "compare_double x y \ 0 \ + is_nan x \ fcompare_double x y \ {ccode.Eq, ccode.Lt}" + by (rule linorder_cases[of "compare_double x y" 0]; simp) + (auto simp: compare_double_simps nan_fcompare_double) + +lift_definition double_of_integer :: "integer \ double" is + "\x. zerosign 0 (intround To_nearest (int_of_integer x))" . + +definition double_of_int where [code del]: "double_of_int x = double_of_integer (integer_of_int x)" + +lemma [code]: "double_of_int (int_of_integer x) = double_of_integer x" + unfolding double_of_int_def by simp + +lift_definition integer_of_double :: "double \ integer" is + "\x. if IEEE.is_nan x \ IEEE.is_infinity x then undefined + else integer_of_int \valof (intround float_To_zero (valof x) :: (11, 52) float)\" + by auto + +definition int_of_double: "int_of_double x = int_of_integer (integer_of_double x)" + + +subsection \Linear ordering\ + +definition lcompare_double :: "double \ double \ integer" where + "lcompare_double x y = (if is_zero x \ is_zero y then + compare_double (copysign_double 1 x) (copysign_double 1 y) + else compare_double x y)" + +lemma fcompare_double_swap: "fcompare_double x y = ccode.Gt \ fcompare_double y x = ccode.Lt" + by transfer (auto simp: fcompare_def) + +lemma fcompare_double_refl: "\ is_nan x \ fcompare_double x x = ccode.Eq" + by transfer (auto simp: fcompare_def) + +lemma fcompare_double_Eq1: "fcompare_double x y = ccode.Eq \ fcompare_double y z = c \ fcompare_double x z = c" + by transfer (auto simp: fcompare_def split: if_splits) + +lemma fcompare_double_Eq2: "fcompare_double y z = ccode.Eq \ fcompare_double x y = c \ fcompare_double x z = c" + by transfer (auto simp: fcompare_def split: if_splits) + +lemma fcompare_double_Lt_trans: "fcompare_double x y = ccode.Lt \ fcompare_double y z = ccode.Lt \ fcompare_double x z = ccode.Lt" + by transfer (auto simp: fcompare_def split: if_splits) + +lemma fcompare_double_eq: "\ is_zero x \ \ is_zero y \ fcompare_double x y = ccode.Eq \ x = y" + by transfer (auto simp: fcompare_def valof_eq IEEE.is_infinity_def split: if_splits intro!: float_eqI) + +lemma fcompare_double_Lt_asym: "fcompare_double x y = ccode.Lt \ fcompare_double y x = ccode.Lt \ False" + by transfer (auto simp: fcompare_def split: if_splits) + +lemma compare_double_swap: "0 < compare_double x y \ compare_double y x < 0" + by (auto simp: compare_double_simps fcompare_double_swap) + +lemma compare_double_refl: "compare_double x x = 0" + by (auto simp: compare_double_eq intro!: fcompare_double_refl) + +lemma compare_double_trans: "compare_double x y \ 0 \ compare_double y z \ 0 \ compare_double x z \ 0" + by (fastforce simp: compare_double_le_0 nan_fcompare_double + dest: fcompare_double_Eq1 fcompare_double_Eq2 fcompare_double_Lt_trans) + +lemma compare_double_antisym: "compare_double x y \ 0 \ compare_double y x \ 0 \ + \ is_zero x \ \ is_zero y \ x = y" + unfolding compare_double_le_0 + by (auto simp: nan_fcompare_double is_nan_conv + intro: fcompare_double_eq fcompare_double_eq[symmetric] + dest: fcompare_double_Lt_asym) + +lemma zero_compare_double_copysign: "compare_double (copysign_double 1 x) (copysign_double 1 y) \ 0 \ + is_zero x \ is_zero y \ compare_double x y \ 0" + unfolding compare_double_le_0 + by transfer (auto simp: nan_not_zero zero_fcompare split: if_splits) + +lemma is_zero_double_cases: "is_zero x \ (x = 0 \ P) \ (x = -0 \ P) \ P" + by transfer (auto elim!: is_zero_cases) + +lemma copysign_1_0[simp]: "copysign_double 1 0 = 1" "copysign_double 1 (-0) = -1" + by (transfer, simp, transfer, auto)+ + +lemma is_zero_uminus_double[simp]: "is_zero (- x) \ is_zero x" + by transfer simp + +lemma not_is_zero_one_double[simp]: "\ is_zero 1" + by (transfer, unfold IEEE.is_zero_def, transfer, simp) + +lemma uminus_one_neq_one_double[simp]: "- 1 \ (1 :: double)" + by (transfer, transfer, simp) + +definition lle_double :: "double \ double \ bool" where + "lle_double x y \ lcompare_double x y \ 0" + +definition lless_double :: "double \ double \ bool" where + "lless_double x y \ lcompare_double x y < 0" + +lemma lcompare_double_ge_0: "lcompare_double x y \ 0 \ lle_double y x" + unfolding lle_double_def lcompare_double_def + using compare_double_swap not_less by auto + +lemma lcompare_double_gt_0: "lcompare_double x y > 0 \ lless_double y x" + unfolding lless_double_def lcompare_double_def + using compare_double_swap by auto + +lemma lcompare_double_eq_0: "lcompare_double x y = 0 \ x = y" +proof + assume *: "lcompare_double x y = 0" + show "x = y" proof (cases "is_zero x \ is_zero y") + case True + with * show ?thesis + by (fastforce simp: lcompare_double_def compare_double_simps is_nan_conv + elim: is_zero_double_cases dest!: fcompare_double_eq[rotated]) + next + case False + with * show ?thesis + by (auto simp: lcompare_double_def linorder_not_less[symmetric] compare_double_swap + intro!: compare_double_antisym) + qed +next + assume "x = y" + then show "lcompare_double x y = 0" + by (simp add: lcompare_double_def compare_double_refl) +qed + +lemmas lcompare_double_0_folds = lle_double_def[symmetric] lless_double_def[symmetric] + lcompare_double_ge_0 lcompare_double_gt_0 lcompare_double_eq_0 + +interpretation double_linorder: linorder lle_double lless_double +proof + fix x y z :: double + show "lless_double x y \ lle_double x y \ \ lle_double y x" + unfolding lless_double_def lle_double_def lcompare_double_def + by (auto simp: compare_double_swap not_le) + show "lle_double x x" + unfolding lle_double_def lcompare_double_def + by (auto simp: compare_double_refl) + show "lle_double x z" if "lle_double x y" and "lle_double y z" + using that + by (auto 0 3 simp: lle_double_def lcompare_double_def not_le compare_double_swap + split: if_splits dest: compare_double_trans zero_compare_double_copysign + zero_compare_double_copysign[OF less_imp_le] compare_double_antisym) + show "x = y" if "lle_double x y" and "lle_double y x" + proof (cases "is_zero x \ is_zero y") + case True + with that show ?thesis + by (auto 0 3 simp: lle_double_def lcompare_double_def elim: is_zero_double_cases + dest!: compare_double_antisym) + next + case False + with that show ?thesis + by (auto simp: lle_double_def lcompare_double_def elim!: compare_double_antisym) + qed + show "lle_double x y \ lle_double y x" + unfolding lle_double_def lcompare_double_def + by (auto simp: compare_double_swap not_le) +qed + +instantiation double :: equal +begin + +definition equal_double :: "double \ double \ bool" where + "equal_double x y \ lcompare_double x y = 0" + +instance by intro_classes (simp add: equal_double_def lcompare_double_eq_0) + +end + +derive (eq) ceq double + +definition comparator_double :: "double comparator" where + "comparator_double x y = (let c = lcompare_double x y in + if c = 0 then order.Eq else if c < 0 then order.Lt else order.Gt)" + +lemma comparator_double: "comparator comparator_double" + unfolding comparator_double_def + by (auto simp: lcompare_double_0_folds split: if_splits intro!: comparator.intro) + +local_setup \ + Comparator_Generator.register_foreign_comparator @{typ double} + @{term comparator_double} + @{thm comparator_double} +\ + +derive ccompare double + + +subsubsection \Code setup\ + +declare [[code drop: + "0 :: double" + "1 :: double" + "plus :: double \ _" + "minus :: double \ _" + "uminus :: double \ _" + "times :: double \ _" + "less_eq :: double \ _" + "less :: double \ _" + "divide :: double \ _" + sqrt_double infinity nan is_zero is_infinite is_nan copysign_double fcompare_double + double_of_integer integer_of_double + ]] + +code_printing + code_module FloatUtil \ (OCaml) +\module FloatUtil : sig + val iszero : float -> bool + val isinfinite : float -> bool + val isnan : float -> bool + val copysign : float -> float -> float + val compare : float -> float -> Z.t +end = struct + let iszero x = (Pervasives.classify_float x = Pervasives.FP_zero);; + let isinfinite x = (Pervasives.classify_float x = Pervasives.FP_infinite);; + let isnan x = (Pervasives.classify_float x = Pervasives.FP_nan);; + let copysign x y = if isnan y then Pervasives.nan else Pervasives.copysign x y;; + let compare x y = Z.of_int (Pervasives.compare x y);; +end;;\ + +code_reserved OCaml Pervasives FloatUtil + +code_printing + type_constructor double \ (OCaml) "float" + | constant "uminus :: double \ double" \ (OCaml) "Pervasives.(~-.)" + | constant "(+) :: double \ double \ double" \ (OCaml) "Pervasives.(+.)" + | constant "(*) :: double \ double \ double" \ (OCaml) "Pervasives.( *. )" + | constant "(/) :: double \ double \ double" \ (OCaml) "Pervasives.('/.)" + | constant "(-) :: double \ double \ double" \ (OCaml) "Pervasives.(-.)" + | constant "0 :: double" \ (OCaml) "0.0" + | constant "1 :: double" \ (OCaml) "1.0" + | constant "(\) :: double \ double \ bool" \ (OCaml) "Pervasives.(<=)" + | constant "(<) :: double \ double \ bool" \ (OCaml) "Pervasives.(<)" + | constant "sqrt_double :: double \ double" \ (OCaml) "Pervasives.sqrt" + | constant "infinity :: double" \ (OCaml) "Pervasives.infinity" + | constant "nan :: double" \ (OCaml) "Pervasives.nan" + | constant "is_zero :: double \ bool" \ (OCaml) "FloatUtil.iszero" + | constant "is_infinite :: double \ bool" \ (OCaml) "FloatUtil.isinfinite" + | constant "is_nan :: double \ bool" \ (OCaml) "FloatUtil.isnan" + | constant "copysign_double :: double \ double \ double" \ (OCaml) "FloatUtil.copysign" + | constant "compare_double :: double \ double \ integer" \ (OCaml) "FloatUtil.compare" + | constant "double_of_integer :: integer \ double" \ (OCaml) "Z.to'_float" + | constant "integer_of_double :: double \ integer" \ (OCaml) "Z.of'_float" + +hide_const (open) fcompare_double + +(*<*) +end +(*>*) + diff --git a/thys/MFODL_Monitor_Optimized/Event_Data.thy b/thys/MFODL_Monitor_Optimized/Event_Data.thy new file mode 100644 --- /dev/null +++ b/thys/MFODL_Monitor_Optimized/Event_Data.thy @@ -0,0 +1,99 @@ +(*<*) +theory Event_Data + imports + "HOL-Library.Char_ord" + Code_Double + Deriving.Derive +begin +(*>*) + +section \Event parameters\ + +definition div_to_zero :: "integer \ integer \ integer" where + "div_to_zero x y = (let z = fst (Code_Numeral.divmod_abs x y) in + if (x < 0) \ (y < 0) then - z else z)" + +definition mod_to_zero :: "integer \ integer \ integer" where + "mod_to_zero x y = (let z = snd (Code_Numeral.divmod_abs x y) in + if x < 0 then - z else z)" + +lemma "b \ 0 \ div_to_zero a b * b + mod_to_zero a b = a" + unfolding div_to_zero_def mod_to_zero_def Let_def + by (auto simp: minus_mod_eq_mult_div[symmetric] div_minus_right mod_minus_right ac_simps) + + +datatype event_data = EInt integer | EFloat double | EString string + +derive (eq) ceq event_data +derive ccompare event_data + +instantiation event_data :: "{ord, plus, minus, uminus, times, divide, modulo}" +begin + +fun less_eq_event_data where + "EInt x \ EInt y \ x \ y" +| "EInt x \ EFloat y \ double_of_integer x \ y" +| "EInt _ \ EString _ \ False" +| "EFloat x \ EInt y \ x \ double_of_integer y" +| "EFloat x \ EFloat y \ x \ y" +| "EFloat _ \ EString _ \ False" +| "EString x \ EString y \ lexordp_eq x y" +| "EString _ \ _ \ False" + +definition less_event_data :: "event_data \ event_data \ bool" where + "less_event_data x y \ x \ y \ \ y \ x" + +fun plus_event_data where + "EInt x + EInt y = EInt (x + y)" +| "EInt x + EFloat y = EFloat (double_of_integer x + y)" +| "EFloat x + EInt y = EFloat (x + double_of_integer y)" +| "EFloat x + EFloat y = EFloat (x + y)" +| "(_::event_data) + _ = EFloat nan" + +fun minus_event_data where + "EInt x - EInt y = EInt (x - y)" +| "EInt x - EFloat y = EFloat (double_of_integer x - y)" +| "EFloat x - EInt y = EFloat (x - double_of_integer y)" +| "EFloat x - EFloat y = EFloat (x - y)" +| "(_::event_data) - _ = EFloat nan" + +fun uminus_event_data where + "- EInt x = EInt (- x)" +| "- EFloat x = EFloat (- x)" +| "- (_::event_data) = EFloat nan" + +fun times_event_data where + "EInt x * EInt y = EInt (x * y)" +| "EInt x * EFloat y = EFloat (double_of_integer x * y)" +| "EFloat x * EInt y = EFloat (x * double_of_integer y)" +| "EFloat x * EFloat y = EFloat (x * y)" +| "(_::event_data) * _ = EFloat nan" + +fun divide_event_data where + "EInt x div EInt y = EInt (div_to_zero x y)" +| "EInt x div EFloat y = EFloat (double_of_integer x div y)" +| "EFloat x div EInt y = EFloat (x div double_of_integer y)" +| "EFloat x div EFloat y = EFloat (x div y)" +| "(_::event_data) div _ = EFloat nan" + +fun modulo_event_data where + "EInt x mod EInt y = EInt (mod_to_zero x y)" +| "(_::event_data) mod _ = EFloat nan" + +instance .. + +end + +primrec integer_of_event_data :: "event_data \ integer" where + "integer_of_event_data (EInt x) = x" +| "integer_of_event_data (EFloat x) = integer_of_double x" +| "integer_of_event_data (EString _) = 0" + +primrec double_of_event_data :: "event_data \ double" where + "double_of_event_data (EInt x) = double_of_integer x" +| "double_of_event_data (EFloat x) = x" +| "double_of_event_data (EString _) = nan" + +(*<*) +end +(*>*) diff --git a/thys/MFODL_Monitor_Optimized/Formula.thy b/thys/MFODL_Monitor_Optimized/Formula.thy new file mode 100644 --- /dev/null +++ b/thys/MFODL_Monitor_Optimized/Formula.thy @@ -0,0 +1,1291 @@ +(*<*) +theory Formula + imports Interval Trace Regex Event_Data + "MFOTL_Monitor.Table" + "HOL-Library.Mapping" + Containers.Set_Impl +begin +(*>*) + +section \Metric first-order temporal logic\ + +derive (eq) ceq enat + +instantiation enat :: ccompare begin +definition ccompare_enat :: "enat comparator option" where + "ccompare_enat = Some (\x y. if x = y then order.Eq else if x < y then order.Lt else order.Gt)" + +instance by intro_classes + (auto simp: ccompare_enat_def split: if_splits intro!: comparator.intro) +end + +context begin + +subsection \Formulas and satisfiability\ + +qualified type_synonym name = string +qualified type_synonym event = "(name \ event_data list)" +qualified type_synonym database = "(name, event_data list set list) mapping" +qualified type_synonym prefix = "(name \ event_data list) prefix" +qualified type_synonym trace = "(name \ event_data list) trace" + +qualified type_synonym env = "event_data list" + +subsubsection \Syntax\ + +qualified datatype trm = is_Var: Var nat | is_Const: Const event_data + | Plus trm trm | Minus trm trm | UMinus trm | Mult trm trm | Div trm trm | Mod trm trm + | F2i trm | I2f trm + +qualified primrec fvi_trm :: "nat \ trm \ nat set" where + "fvi_trm b (Var x) = (if b \ x then {x - b} else {})" +| "fvi_trm b (Const _) = {}" +| "fvi_trm b (Plus x y) = fvi_trm b x \ fvi_trm b y" +| "fvi_trm b (Minus x y) = fvi_trm b x \ fvi_trm b y" +| "fvi_trm b (UMinus x) = fvi_trm b x" +| "fvi_trm b (Mult x y) = fvi_trm b x \ fvi_trm b y" +| "fvi_trm b (Div x y) = fvi_trm b x \ fvi_trm b y" +| "fvi_trm b (Mod x y) = fvi_trm b x \ fvi_trm b y" +| "fvi_trm b (F2i x) = fvi_trm b x" +| "fvi_trm b (I2f x) = fvi_trm b x" + +abbreviation "fv_trm \ fvi_trm 0" + +qualified primrec eval_trm :: "env \ trm \ event_data" where + "eval_trm v (Var x) = v ! x" +| "eval_trm v (Const x) = x" +| "eval_trm v (Plus x y) = eval_trm v x + eval_trm v y" +| "eval_trm v (Minus x y) = eval_trm v x - eval_trm v y" +| "eval_trm v (UMinus x) = - eval_trm v x" +| "eval_trm v (Mult x y) = eval_trm v x * eval_trm v y" +| "eval_trm v (Div x y) = eval_trm v x div eval_trm v y" +| "eval_trm v (Mod x y) = eval_trm v x mod eval_trm v y" +| "eval_trm v (F2i x) = EInt (integer_of_event_data (eval_trm v x))" +| "eval_trm v (I2f x) = EFloat (double_of_event_data (eval_trm v x))" + +lemma eval_trm_fv_cong: "\x\fv_trm t. v ! x = v' ! x \ eval_trm v t = eval_trm v' t" + by (induction t) simp_all + + +qualified datatype agg_type = Agg_Cnt | Agg_Min | Agg_Max | Agg_Sum | Agg_Avg | Agg_Med +qualified type_synonym agg_op = "agg_type \ event_data" + +definition flatten_multiset :: "(event_data \ enat) set \ event_data list" where + "flatten_multiset M = concat (map (\(x, c). replicate (the_enat c) x) (csorted_list_of_set M))" + +fun eval_agg_op :: "agg_op \ (event_data \ enat) set \ event_data" where + "eval_agg_op (Agg_Cnt, y0) M = EInt (integer_of_int (length (flatten_multiset M)))" +| "eval_agg_op (Agg_Min, y0) M = (case flatten_multiset M of + [] \ y0 + | x # xs \ foldl min x xs)" +| "eval_agg_op (Agg_Max, y0) M = (case flatten_multiset M of + [] \ y0 + | x # xs \ foldl max x xs)" +| "eval_agg_op (Agg_Sum, y0) M = foldl plus y0 (flatten_multiset M)" +| "eval_agg_op (Agg_Avg, y0) M = EFloat (let xs = flatten_multiset M in case xs of + [] \ 0 + | _ \ double_of_event_data (foldl plus (EInt 0) xs) / double_of_int (length xs))" +| "eval_agg_op (Agg_Med, y0) M = EFloat (let xs = flatten_multiset M; u = length xs in + if u = 0 then 0 else + let u' = u div 2 in + if even u then + (double_of_event_data (xs ! (u'-1)) + double_of_event_data (xs ! u') / double_of_int 2) + else double_of_event_data (xs ! u'))" + +qualified datatype (discs_sels) formula = Pred name "trm list" + | Let name nat formula formula + | Eq trm trm | Less trm trm | LessEq trm trm + | Neg formula | Or formula formula | And formula formula | Ands "formula list" | Exists formula + | Agg nat agg_op nat trm formula + | Prev \ formula | Next \ formula + | Since formula \ formula | Until formula \ formula + | MatchF \ "formula Regex.regex" | MatchP \ "formula Regex.regex" + +qualified definition "FF = Exists (Neg (Eq (Var 0) (Var 0)))" +qualified definition "TT \ Neg FF" + +qualified fun fvi :: "nat \ formula \ nat set" where + "fvi b (Pred r ts) = (\t\set ts. fvi_trm b t)" +| "fvi b (Let p _ \ \) = fvi b \" +| "fvi b (Eq t1 t2) = fvi_trm b t1 \ fvi_trm b t2" +| "fvi b (Less t1 t2) = fvi_trm b t1 \ fvi_trm b t2" +| "fvi b (LessEq t1 t2) = fvi_trm b t1 \ fvi_trm b t2" +| "fvi b (Neg \) = fvi b \" +| "fvi b (Or \ \) = fvi b \ \ fvi b \" +| "fvi b (And \ \) = fvi b \ \ fvi b \" +| "fvi b (Ands \s) = (let xs = map (fvi b) \s in \x\set xs. x)" +| "fvi b (Exists \) = fvi (Suc b) \" +| "fvi b (Agg y \ b' f \) = fvi (b + b') \ \ fvi_trm (b + b') f \ (if b \ y then {y - b} else {})" +| "fvi b (Prev I \) = fvi b \" +| "fvi b (Next I \) = fvi b \" +| "fvi b (Since \ I \) = fvi b \ \ fvi b \" +| "fvi b (Until \ I \) = fvi b \ \ fvi b \" +| "fvi b (MatchF I r) = Regex.fv_regex (fvi b) r" +| "fvi b (MatchP I r) = Regex.fv_regex (fvi b) r" + +abbreviation "fv \ fvi 0" +abbreviation "fv_regex \ Regex.fv_regex fv" + +lemma fv_abbrevs[simp]: "fv TT = {}" "fv FF = {}" + unfolding TT_def FF_def by auto + +lemma fv_subset_Ands: "\ \ set \s \ fv \ \ fv (Ands \s)" + by auto + +lemma finite_fvi_trm[simp]: "finite (fvi_trm b t)" + by (induction t) simp_all + +lemma finite_fvi[simp]: "finite (fvi b \)" + by (induction \ arbitrary: b) simp_all + +lemma fvi_trm_plus: "x \ fvi_trm (b + c) t \ x + c \ fvi_trm b t" + by (induction t) auto + +lemma fvi_trm_iff_fv_trm: "x \ fvi_trm b t \ x + b \ fv_trm t" + using fvi_trm_plus[where b=0 and c=b] by simp_all + +lemma fvi_plus: "x \ fvi (b + c) \ \ x + c \ fvi b \" +proof (induction \ arbitrary: b rule: formula.induct) + case (Exists \) + then show ?case by force +next + case (Agg y \ b' f \) + have *: "b + c + b' = b + b' + c" by simp + from Agg show ?case by (force simp: * fvi_trm_plus) +qed (auto simp add: fvi_trm_plus fv_regex_commute[where g = "\x. x + c"]) + +lemma fvi_Suc: "x \ fvi (Suc b) \ \ Suc x \ fvi b \" + using fvi_plus[where c=1] by simp + +lemma fvi_plus_bound: + assumes "\i\fvi (b + c) \. i < n" + shows "\i\fvi b \. i < c + n" +proof + fix i + assume "i \ fvi b \" + show "i < c + n" + proof (cases "i < c") + case True + then show ?thesis by simp + next + case False + then obtain i' where "i = i' + c" + using nat_le_iff_add by (auto simp: not_less) + with assms \i \ fvi b \\ show ?thesis by (simp add: fvi_plus) + qed +qed + +lemma fvi_Suc_bound: + assumes "\i\fvi (Suc b) \. i < n" + shows "\i\fvi b \. i < Suc n" + using assms fvi_plus_bound[where c=1] by simp + +lemma fvi_iff_fv: "x \ fvi b \ \ x + b \ fv \" + using fvi_plus[where b=0 and c=b] by simp_all + +qualified definition nfv :: "formula \ nat" where + "nfv \ = Max (insert 0 (Suc ` fv \))" + +qualified abbreviation nfv_regex where + "nfv_regex \ Regex.nfv_regex fv" + +qualified definition envs :: "formula \ env set" where + "envs \ = {v. length v = nfv \}" + +lemma nfv_simps[simp]: + "nfv (Let p b \ \) = nfv \" + "nfv (Neg \) = nfv \" + "nfv (Or \ \) = max (nfv \) (nfv \)" + "nfv (And \ \) = max (nfv \) (nfv \)" + "nfv (Prev I \) = nfv \" + "nfv (Next I \) = nfv \" + "nfv (Since \ I \) = max (nfv \) (nfv \)" + "nfv (Until \ I \) = max (nfv \) (nfv \)" + "nfv (MatchP I r) = Regex.nfv_regex fv r" + "nfv (MatchF I r) = Regex.nfv_regex fv r" + "nfv_regex (Regex.Skip n) = 0" + "nfv_regex (Regex.Test \) = Max (insert 0 (Suc ` fv \))" + "nfv_regex (Regex.Plus r s) = max (nfv_regex r) (nfv_regex s)" + "nfv_regex (Regex.Times r s) = max (nfv_regex r) (nfv_regex s)" + "nfv_regex (Regex.Star r) = nfv_regex r" + unfolding nfv_def Regex.nfv_regex_def by (simp_all add: image_Un Max_Un[symmetric]) + +lemma nfv_Ands[simp]: "nfv (Ands l) = Max (insert 0 (nfv ` set l))" +proof (induction l) + case Nil + then show ?case unfolding nfv_def by simp +next + case (Cons a l) + have "fv (Ands (a # l)) = fv a \ fv (Ands l)" by simp + then have "nfv (Ands (a # l)) = max (nfv a) (nfv (Ands l))" + unfolding nfv_def + by (auto simp: image_Un Max.union[symmetric]) + with Cons.IH show ?case + by (cases l) auto +qed + +lemma fvi_less_nfv: "\i\fv \. i < nfv \" + unfolding nfv_def + by (auto simp add: Max_gr_iff intro: max.strict_coboundedI2) + +lemma fvi_less_nfv_regex: "\i\fv_regex \. i < nfv_regex \" + unfolding Regex.nfv_regex_def + by (auto simp add: Max_gr_iff intro: max.strict_coboundedI2) + +subsubsection \Future reach\ + +qualified fun future_bounded :: "formula \ bool" where + "future_bounded (Pred _ _) = True" +| "future_bounded (Let p b \ \) = (future_bounded \ \ future_bounded \)" +| "future_bounded (Eq _ _) = True" +| "future_bounded (Less _ _) = True" +| "future_bounded (LessEq _ _) = True" +| "future_bounded (Neg \) = future_bounded \" +| "future_bounded (Or \ \) = (future_bounded \ \ future_bounded \)" +| "future_bounded (And \ \) = (future_bounded \ \ future_bounded \)" +| "future_bounded (Ands l) = list_all future_bounded l" +| "future_bounded (Exists \) = future_bounded \" +| "future_bounded (Agg y \ b f \) = future_bounded \" +| "future_bounded (Prev I \) = future_bounded \" +| "future_bounded (Next I \) = future_bounded \" +| "future_bounded (Since \ I \) = (future_bounded \ \ future_bounded \)" +| "future_bounded (Until \ I \) = (future_bounded \ \ future_bounded \ \ right I \ \)" +| "future_bounded (MatchP I r) = Regex.pred_regex future_bounded r" +| "future_bounded (MatchF I r) = (Regex.pred_regex future_bounded r \ right I \ \)" + + +subsubsection \Semantics\ + +definition "ecard A = (if finite A then card A else \)" + +qualified fun sat :: "trace \ (name \ nat \ event_data list set) \ env \ nat \ formula \ bool" where + "sat \ V v i (Pred r ts) = (case V r of + None \ (r, map (eval_trm v) ts) \ \ \ i + | Some X \ map (eval_trm v) ts \ X i)" +| "sat \ V v i (Let p b \ \) = + sat \ (V(p \ \i. {v. length v = nfv \ - b \ (\zs. length zs = b \ sat \ V (zs @ v) i \)})) v i \" +| "sat \ V v i (Eq t1 t2) = (eval_trm v t1 = eval_trm v t2)" +| "sat \ V v i (Less t1 t2) = (eval_trm v t1 < eval_trm v t2)" +| "sat \ V v i (LessEq t1 t2) = (eval_trm v t1 \ eval_trm v t2)" +| "sat \ V v i (Neg \) = (\ sat \ V v i \)" +| "sat \ V v i (Or \ \) = (sat \ V v i \ \ sat \ V v i \)" +| "sat \ V v i (And \ \) = (sat \ V v i \ \ sat \ V v i \)" +| "sat \ V v i (Ands l) = (\\ \ set l. sat \ V v i \)" +| "sat \ V v i (Exists \) = (\z. sat \ V (z # v) i \)" +| "sat \ V v i (Agg y \ b f \) = + (let M = {(x, ecard Zs) | x Zs. Zs = {zs. length zs = b \ sat \ V (zs @ v) i \ \ eval_trm (zs @ v) f = x} \ Zs \ {}} + in (M = {} \ fv \ \ {0.. v ! y = eval_agg_op \ M)" +| "sat \ V v i (Prev I \) = (case i of 0 \ False | Suc j \ mem (\ \ i - \ \ j) I \ sat \ V v j \)" +| "sat \ V v i (Next I \) = (mem (\ \ (Suc i) - \ \ i) I \ sat \ V v (Suc i) \)" +| "sat \ V v i (Since \ I \) = (\j\i. mem (\ \ i - \ \ j) I \ sat \ V v j \ \ (\k \ {j <.. i}. sat \ V v k \))" +| "sat \ V v i (Until \ I \) = (\j\i. mem (\ \ j - \ \ i) I \ sat \ V v j \ \ (\k \ {i ..< j}. sat \ V v k \))" +| "sat \ V v i (MatchP I r) = (\j\i. mem (\ \ i - \ \ j) I \ Regex.match (sat \ V v) r j i)" +| "sat \ V v i (MatchF I r) = (\j\i. mem (\ \ j - \ \ i) I \ Regex.match (sat \ V v) r i j)" + +lemma sat_abbrevs[simp]: + "sat \ V v i TT" "\ sat \ V v i FF" + unfolding TT_def FF_def by auto + +lemma sat_Ands: "sat \ V v i (Ands l) \ (\\\set l. sat \ V v i \)" + by (simp add: list_all_iff) + +lemma sat_Until_rec: "sat \ V v i (Until \ I \) \ + mem 0 I \ sat \ V v i \ \ + (\ \ (i + 1) \ right I \ sat \ V v i \ \ sat \ V v (i + 1) (Until \ (subtract (\ \ (i + 1)) I) \))" + (is "?L \ ?R") +proof (rule iffI; (elim disjE conjE)?) + assume ?L + then obtain j where j: "i \ j" "mem (\ \ j - \ \ i) I" "sat \ V v j \" "\k \ {i ..< j}. sat \ V v k \" + by auto + then show ?R + proof (cases "i = j") + case False + with j(1,2) have "\ \ (i + 1) \ right I" + by (auto elim: order_trans[rotated] simp: diff_le_mono) + moreover from False j(1,4) have "sat \ V v i \" by auto + moreover from False j have "sat \ V v (i + 1) (Until \ (subtract (\ \ (i + 1)) I) \)" + by (cases "right I") (auto simp: le_diff_conv le_diff_conv2 intro!: exI[of _ j]) + ultimately show ?thesis by blast + qed simp +next + assume \: "\ \ (i + 1) \ right I" and now: "sat \ V v i \" and + "next": "sat \ V v (i + 1) (Until \ (subtract (\ \ (i + 1)) I) \)" + from "next" obtain j where j: "i + 1 \ j" "mem (\ \ j - \ \ (i + 1)) ((subtract (\ \ (i + 1)) I))" + "sat \ V v j \" "\k \ {i + 1 ..< j}. sat \ V v k \" + by auto + from \ j(1,2) have "mem (\ \ j - \ \ i) I" + by (cases "right I") (auto simp: le_diff_conv2) + with now j(1,3,4) show ?L by (auto simp: le_eq_less_or_eq[of i] intro!: exI[of _ j]) +qed auto + +lemma sat_Since_rec: "sat \ V v i (Since \ I \) \ + mem 0 I \ sat \ V v i \ \ + (i > 0 \ \ \ i \ right I \ sat \ V v i \ \ sat \ V v (i - 1) (Since \ (subtract (\ \ i) I) \))" + (is "?L \ ?R") +proof (rule iffI; (elim disjE conjE)?) + assume ?L + then obtain j where j: "j \ i" "mem (\ \ i - \ \ j) I" "sat \ V v j \" "\k \ {j <.. i}. sat \ V v k \" + by auto + then show ?R + proof (cases "i = j") + case False + with j(1) obtain k where [simp]: "i = k + 1" + by (cases i) auto + with j(1,2) False have "\ \ i \ right I" + by (auto elim: order_trans[rotated] simp: diff_le_mono2 le_Suc_eq) + moreover from False j(1,4) have "sat \ V v i \" by auto + moreover from False j have "sat \ V v (i - 1) (Since \ (subtract (\ \ i) I) \)" + by (cases "right I") (auto simp: le_diff_conv le_diff_conv2 intro!: exI[of _ j]) + ultimately show ?thesis by auto + qed simp +next + assume i: "0 < i" and \: "\ \ i \ right I" and now: "sat \ V v i \" and + "prev": "sat \ V v (i - 1) (Since \ (subtract (\ \ i) I) \)" + from "prev" obtain j where j: "j \ i - 1" "mem (\ \ (i - 1) - \ \ j) ((subtract (\ \ i) I))" + "sat \ V v j \" "\k \ {j <.. i - 1}. sat \ V v k \" + by auto + from \ i j(1,2) have "mem (\ \ i - \ \ j) I" + by (cases "right I") (auto simp: le_diff_conv2) + with now i j(1,3,4) show ?L by (auto simp: le_Suc_eq gr0_conv_Suc intro!: exI[of _ j]) +qed auto + +lemma sat_MatchF_rec: "sat \ V v i (MatchF I r) \ mem 0 I \ Regex.eps (sat \ V v) i r \ + \ \ (i + 1) \ right I \ (\s \ Regex.lpd (sat \ V v) i r. sat \ V v (i + 1) (MatchF (subtract (\ \ (i + 1)) I) s))" + (is "?L \ ?R1 \ ?R2") +proof (rule iffI; (elim disjE conjE bexE)?) + assume ?L + then obtain j where j: "j \ i" "mem (\ \ j - \ \ i) I" and "Regex.match (sat \ V v) r i j" by auto + then show "?R1 \ ?R2" + proof (cases "i < j") + case True + with \Regex.match (sat \ V v) r i j\ lpd_match[of i j "sat \ V v" r] + obtain s where "s \ Regex.lpd (sat \ V v) i r" "Regex.match (sat \ V v) s (i + 1) j" by auto + with True j have ?R2 + by (cases "right I") + (auto simp: le_diff_conv le_diff_conv2 intro!: exI[of _ j] elim: le_trans[rotated]) + then show ?thesis by blast + qed (auto simp: eps_match) +next + assume "enat (\ \ (i + 1)) \ right I" + moreover + fix s + assume [simp]: "s \ Regex.lpd (sat \ V v) i r" and "sat \ V v (i + 1) (MatchF (subtract (\ \ (i + 1)) I) s)" + then obtain j where "j > i" "Regex.match (sat \ V v) s (i + 1) j" + "mem (\ \ j - \ \ (Suc i)) (subtract (\ \ (i + 1)) I)" by (auto simp: Suc_le_eq) + ultimately show ?L + by (cases "right I") + (auto simp: le_diff_conv lpd_match intro!: exI[of _ j] bexI[of _ s]) +qed (auto simp: eps_match intro!: exI[of _ i]) + +lemma sat_MatchP_rec: "sat \ V v i (MatchP I r) \ mem 0 I \ Regex.eps (sat \ V v) i r \ + i > 0 \ \ \ i \ right I \ (\s \ Regex.rpd (sat \ V v) i r. sat \ V v (i - 1) (MatchP (subtract (\ \ i) I) s))" + (is "?L \ ?R1 \ ?R2") +proof (rule iffI; (elim disjE conjE bexE)?) + assume ?L + then obtain j where j: "j \ i" "mem (\ \ i - \ \ j) I" and "Regex.match (sat \ V v) r j i" by auto + then show "?R1 \ ?R2" + proof (cases "j < i") + case True + with \Regex.match (sat \ V v) r j i\ rpd_match[of j i "sat \ V v" r] + obtain s where "s \ Regex.rpd (sat \ V v) i r" "Regex.match (sat \ V v) s j (i - 1)" by auto + with True j have ?R2 + by (cases "right I") + (auto simp: le_diff_conv le_diff_conv2 intro!: exI[of _ j] elim: le_trans) + then show ?thesis by blast + qed (auto simp: eps_match) +next + assume "enat (\ \ i) \ right I" + moreover + fix s + assume [simp]: "s \ Regex.rpd (sat \ V v) i r" and "sat \ V v (i - 1) (MatchP (subtract (\ \ i) I) s)" "i > 0" + then obtain j where "j < i" "Regex.match (sat \ V v) s j (i - 1)" + "mem (\ \ (i - 1) - \ \ j) (subtract (\ \ i) I)" by (auto simp: gr0_conv_Suc less_Suc_eq_le) + ultimately show ?L + by (cases "right I") + (auto simp: le_diff_conv rpd_match intro!: exI[of _ j] bexI[of _ s]) +qed (auto simp: eps_match intro!: exI[of _ i]) + +lemma sat_Since_0: "sat \ V v 0 (Since \ I \) \ mem 0 I \ sat \ V v 0 \" + by auto + +lemma sat_MatchP_0: "sat \ V v 0 (MatchP I r) \ mem 0 I \ Regex.eps (sat \ V v) 0 r" + by (auto simp: eps_match) + +lemma sat_Since_point: "sat \ V v i (Since \ I \) \ + (\j. j \ i \ mem (\ \ i - \ \ j) I \ sat \ V v i (Since \ (point (\ \ i - \ \ j)) \) \ P) \ P" + by (auto intro: diff_le_self) + +lemma sat_MatchP_point: "sat \ V v i (MatchP I r) \ + (\j. j \ i \ mem (\ \ i - \ \ j) I \ sat \ V v i (MatchP (point (\ \ i - \ \ j)) r) \ P) \ P" + by (auto intro: diff_le_self) + +lemma sat_Since_pointD: "sat \ V v i (Since \ (point t) \) \ mem t I \ sat \ V v i (Since \ I \)" + by auto + +lemma sat_MatchP_pointD: "sat \ V v i (MatchP (point t) r) \ mem t I \ sat \ V v i (MatchP I r)" + by auto + +lemma sat_fv_cong: "\x\fv \. v!x = v'!x \ sat \ V v i \ = sat \ V v' i \" +proof (induct \ arbitrary: V v v' i rule: formula.induct) + case (Pred n ts) + show ?case by (simp cong: map_cong eval_trm_fv_cong[OF Pred[simplified, THEN bspec]] split: option.splits) +next + case (Let p b \ \) + then show ?case + by auto +next + case (Eq x1 x2) + then show ?case unfolding fvi.simps sat.simps by (metis UnCI eval_trm_fv_cong) +next + case (Less x1 x2) + then show ?case unfolding fvi.simps sat.simps by (metis UnCI eval_trm_fv_cong) +next + case (LessEq x1 x2) + then show ?case unfolding fvi.simps sat.simps by (metis UnCI eval_trm_fv_cong) +next + case (Ands l) + have "\\. \ \ set l \ sat \ V v i \ = sat \ V v' i \" + proof - + fix \ assume "\ \ set l" + then have "fv \ \ fv (Ands l)" using fv_subset_Ands by blast + then have "\x\fv \. v!x = v'!x" using Ands.prems by blast + then show "sat \ V v i \ = sat \ V v' i \" using Ands.hyps \\ \ set l\ by blast + qed + then show ?case using sat_Ands by blast +next + case (Exists \) + then show ?case unfolding sat.simps by (intro iff_exI) (simp add: fvi_Suc nth_Cons') +next + case (Agg y \ b f \) + have "v ! y = v' ! y" + using Agg.prems by simp + moreover have "sat \ V (zs @ v) i \ = sat \ V (zs @ v') i \" if "length zs = b" for zs + using that Agg.prems by (simp add: Agg.hyps[where v="zs @ v" and v'="zs @ v'"] + nth_append fvi_iff_fv(1)[where b=b]) + moreover have "eval_trm (zs @ v) f = eval_trm (zs @ v') f" if "length zs = b" for zs + using that Agg.prems by (auto intro!: eval_trm_fv_cong[where v="zs @ v" and v'="zs @ v'"] + simp: nth_append fvi_iff_fv(1)[where b=b] fvi_trm_iff_fv_trm[where b="length zs"]) + ultimately show ?case + by (simp cong: conj_cong) +next + case (MatchF I r) + then have "Regex.match (sat \ V v) r = Regex.match (sat \ V v') r" + by (intro match_fv_cong) (auto simp: fv_regex_alt) + then show ?case + by auto +next + case (MatchP I r) + then have "Regex.match (sat \ V v) r = Regex.match (sat \ V v') r" + by (intro match_fv_cong) (auto simp: fv_regex_alt) + then show ?case + by auto +qed (auto 10 0 split: nat.splits intro!: iff_exI) + +lemma match_fv_cong: + "\x\fv_regex r. v!x = v'!x \ Regex.match (sat \ V v) r = Regex.match (sat \ V v') r" + by (rule match_fv_cong, rule sat_fv_cong) (auto simp: fv_regex_alt) + +lemma eps_fv_cong: + "\x\fv_regex r. v!x = v'!x \ Regex.eps (sat \ V v) i r = Regex.eps (sat \ V v') i r" + unfolding eps_match by (erule match_fv_cong[THEN fun_cong, THEN fun_cong]) + + +subsection \Safe formulas\ + +fun remove_neg :: "formula \ formula" where + "remove_neg (Neg \) = \" +| "remove_neg \ = \" + +lemma fvi_remove_neg[simp]: "fvi b (remove_neg \) = fvi b \" + by (cases \) simp_all + +lemma partition_cong[fundef_cong]: + "xs = ys \ (\x. x\set xs \ f x = g x) \ partition f xs = partition g ys" + by (induction xs arbitrary: ys) auto + +lemma size_remove_neg[termination_simp]: "size (remove_neg \) \ size \" + by (cases \) simp_all + +fun is_constraint :: "formula \ bool" where + "is_constraint (Eq t1 t2) = True" +| "is_constraint (Less t1 t2) = True" +| "is_constraint (LessEq t1 t2) = True" +| "is_constraint (Neg (Eq t1 t2)) = True" +| "is_constraint (Neg (Less t1 t2)) = True" +| "is_constraint (Neg (LessEq t1 t2)) = True" +| "is_constraint _ = False" + +definition safe_assignment :: "nat set \ formula \ bool" where + "safe_assignment X \ = (case \ of + Eq (Var x) (Var y) \ (x \ X \ y \ X) + | Eq (Var x) t \ (x \ X \ fv_trm t \ X) + | Eq t (Var x) \ (x \ X \ fv_trm t \ X) + | _ \ False)" + +fun safe_formula :: "formula \ bool" where + "safe_formula (Eq t1 t2) = (is_Const t1 \ (is_Const t2 \ is_Var t2) \ is_Var t1 \ is_Const t2)" +| "safe_formula (Neg (Eq (Var x) (Var y))) = (x = y)" +| "safe_formula (Less t1 t2) = False" +| "safe_formula (LessEq t1 t2) = False" +| "safe_formula (Pred e ts) = (\t\set ts. is_Var t \ is_Const t)" +| "safe_formula (Let p b \ \) = ({0..} \ fv \ \ b \ nfv \ \ safe_formula \ \ safe_formula \)" +| "safe_formula (Neg \) = (fv \ = {} \ safe_formula \)" +| "safe_formula (Or \ \) = (fv \ = fv \ \ safe_formula \ \ safe_formula \)" +| "safe_formula (And \ \) = (safe_formula \ \ + (safe_assignment (fv \) \ \ safe_formula \ \ + fv \ \ fv \ \ (is_constraint \ \ (case \ of Neg \' \ safe_formula \' | _ \ False))))" +| "safe_formula (Ands l) = (let (pos, neg) = partition safe_formula l in pos \ [] \ + list_all safe_formula (map remove_neg neg) \ \(set (map fv neg)) \ \(set (map fv pos)))" +| "safe_formula (Exists \) = (safe_formula \)" +| "safe_formula (Agg y \ b f \) = (safe_formula \ \ y + b \ fv \ \ {0.. fv \ \ fv_trm f \ fv \)" +| "safe_formula (Prev I \) = (safe_formula \)" +| "safe_formula (Next I \) = (safe_formula \)" +| "safe_formula (Since \ I \) = (fv \ \ fv \ \ + (safe_formula \ \ (case \ of Neg \' \ safe_formula \' | _ \ False)) \ safe_formula \)" +| "safe_formula (Until \ I \) = (fv \ \ fv \ \ + (safe_formula \ \ (case \ of Neg \' \ safe_formula \' | _ \ False)) \ safe_formula \)" +| "safe_formula (MatchP I r) = Regex.safe_regex fv (\g \. safe_formula \ \ + (g = Lax \ (case \ of Neg \' \ safe_formula \' | _ \ False))) Past Strict r" +| "safe_formula (MatchF I r) = Regex.safe_regex fv (\g \. safe_formula \ \ + (g = Lax \ (case \ of Neg \' \ safe_formula \' | _ \ False))) Futu Strict r" + +abbreviation "safe_regex \ Regex.safe_regex fv (\g \. safe_formula \ \ + (g = Lax \ (case \ of Neg \' \ safe_formula \' | _ \ False)))" + +lemma safe_regex_safe_formula: + "safe_regex m g r \ \ \ Regex.atms r \ safe_formula \ \ + (\\. \ = Neg \ \ safe_formula \)" + by (cases g) (auto dest!: safe_regex_safe[rotated] split: formula.splits[where formula=\]) + +lemma safe_abbrevs[simp]: "safe_formula TT" "safe_formula FF" + unfolding TT_def FF_def by auto + +definition safe_neg :: "formula \ bool" where + "safe_neg \ \ (\ safe_formula \ \ safe_formula (remove_neg \))" + +definition atms :: "formula Regex.regex \ formula set" where + "atms r = (\\ \ Regex.atms r. + if safe_formula \ then {\} else case \ of Neg \' \ {\'} | _ \ {})" + +lemma atms_simps[simp]: + "atms (Regex.Skip n) = {}" + "atms (Regex.Test \) = (if safe_formula \ then {\} else case \ of Neg \' \ {\'} | _ \ {})" + "atms (Regex.Plus r s) = atms r \ atms s" + "atms (Regex.Times r s) = atms r \ atms s" + "atms (Regex.Star r) = atms r" + unfolding atms_def by auto + +lemma finite_atms[simp]: "finite (atms r)" + by (induct r) (auto split: formula.splits) + +lemma disjE_Not2: "P \ Q \ (P \ R) \ (\P \ Q \ R) \ R" + by blast + +lemma safe_formula_induct[consumes 1, case_names Eq_Const Eq_Var1 Eq_Var2 neq_Var Pred Let + And_assign And_safe And_constraint And_Not Ands Neg Or Exists Agg + Prev Next Since Not_Since Until Not_Until MatchP MatchF]: + assumes "safe_formula \" + and Eq_Const: "\c d. P (Eq (Const c) (Const d))" + and Eq_Var1: "\c x. P (Eq (Const c) (Var x))" + and Eq_Var2: "\c x. P (Eq (Var x) (Const c))" + and neq_Var: "\x. P (Neg (Eq (Var x) (Var x)))" + and Pred: "\e ts. \t\set ts. is_Var t \ is_Const t \ P (Pred e ts)" + and Let: "\p b \ \. {0..} \ fv \ \ b \ nfv \ \ safe_formula \ \ safe_formula \ \ P \ \ P \ \ P (Let p b \ \)" + and And_assign: "\\ \. safe_formula \ \ safe_assignment (fv \) \ \ P \ \ P (And \ \)" + and And_safe: "\\ \. safe_formula \ \ \ safe_assignment (fv \) \ \ safe_formula \ \ + P \ \ P \ \ P (And \ \)" + and And_constraint: "\\ \. safe_formula \ \ \ safe_assignment (fv \) \ \ \ safe_formula \ \ + fv \ \ fv \ \ is_constraint \ \ P \ \ P (And \ \)" + and And_Not: "\\ \. safe_formula \ \ \ safe_assignment (fv \) (Neg \) \ \ safe_formula (Neg \) \ + fv (Neg \) \ fv \ \ \ is_constraint (Neg \) \ safe_formula \ \ P \ \ P \ \ P (And \ (Neg \))" + and Ands: "\l pos neg. (pos, neg) = partition safe_formula l \ pos \ [] \ + list_all safe_formula pos \ list_all safe_formula (map remove_neg neg) \ + (\\\set neg. fv \) \ (\\\set pos. fv \) \ + list_all P pos \ list_all P (map remove_neg neg) \ P (Ands l)" + and Neg: "\\. fv \ = {} \ safe_formula \ \ P \ \ P (Neg \)" + and Or: "\\ \. fv \ = fv \ \ safe_formula \ \ safe_formula \ \ P \ \ P \ \ P (Or \ \)" + and Exists: "\\. safe_formula \ \ P \ \ P (Exists \)" + and Agg: "\y \ b f \. y + b \ fv \ \ {0.. fv \ \ fv_trm f \ fv \ \ + safe_formula \ \ P \ \ P (Agg y \ b f \)" + and Prev: "\I \. safe_formula \ \ P \ \ P (Prev I \)" + and Next: "\I \. safe_formula \ \ P \ \ P (Next I \)" + and Since: "\\ I \. fv \ \ fv \ \ safe_formula \ \ safe_formula \ \ P \ \ P \ \ P (Since \ I \)" + and Not_Since: "\\ I \. fv (Neg \) \ fv \ \ safe_formula \ \ + \ safe_formula (Neg \) \ safe_formula \ \ P \ \ P \ \ P (Since (Neg \) I \ )" + and Until: "\\ I \. fv \ \ fv \ \ safe_formula \ \ safe_formula \ \ P \ \ P \ \ P (Until \ I \)" + and Not_Until: "\\ I \. fv (Neg \) \ fv \ \ safe_formula \ \ + \ safe_formula (Neg \) \ safe_formula \ \ P \ \ P \ \ P (Until (Neg \) I \)" + and MatchP: "\I r. safe_regex Past Strict r \ \\ \ atms r. P \ \ P (MatchP I r)" + and MatchF: "\I r. safe_regex Futu Strict r \ \\ \ atms r. P \ \ P (MatchF I r)" + shows "P \" +using assms(1) proof (induction \ rule: safe_formula.induct) + case (1 t1 t2) + then show ?case using Eq_Const Eq_Var1 Eq_Var2 by (auto simp: trm.is_Const_def trm.is_Var_def) +next + case (9 \ \) + from \safe_formula (And \ \)\ have "safe_formula \" by simp + from \safe_formula (And \ \)\ consider + (a) "safe_assignment (fv \) \" + | (b) "\ safe_assignment (fv \) \" "safe_formula \" + | (c) "fv \ \ fv \" "\ safe_assignment (fv \) \" "\ safe_formula \" "is_constraint \" + | (d) \' where "fv \ \ fv \" "\ safe_assignment (fv \) \" "\ safe_formula \" "\ is_constraint \" + "\ = Neg \'" "safe_formula \'" + by (cases \) auto + then show ?case proof cases + case a + then show ?thesis using "9.IH" \safe_formula \\ by (intro And_assign) + next + case b + then show ?thesis using "9.IH" \safe_formula \\ by (intro And_safe) + next + case c + then show ?thesis using "9.IH" \safe_formula \\ by (intro And_constraint) + next + case d + then show ?thesis using "9.IH" \safe_formula \\ by (blast intro!: And_Not) + qed +next + case (10 l) + obtain pos neg where posneg: "(pos, neg) = partition safe_formula l" by simp + have "pos \ []" using "10.prems" posneg by simp + moreover have "list_all safe_formula pos" using posneg by (simp add: list.pred_set) + moreover have safe_remove_neg: "list_all safe_formula (map remove_neg neg)" using "10.prems" posneg by auto + moreover have "list_all P pos" + using posneg "10.IH"(1) by (simp add: list_all_iff) + moreover have "list_all P (map remove_neg neg)" + using "10.IH"(2)[OF posneg] safe_remove_neg by (simp add: list_all_iff) + ultimately show ?case using "10.IH"(1) "10.prems" Ands posneg by simp +next + case (15 \ I \) + then show ?case + proof (cases \) + case (Ands l) + then show ?thesis using "15.IH"(1) "15.IH"(3) "15.prems" Since by auto + qed (auto 0 3 elim!: disjE_Not2 intro: Since Not_Since) (*SLOW*) +next + case (16 \ I \) + then show ?case + proof (cases \) + case (Ands l) + then show ?thesis using "16.IH"(1) "16.IH"(3) "16.prems" Until by auto + qed (auto 0 3 elim!: disjE_Not2 intro: Until Not_Until) (*SLOW*) +next + case (17 I r) + then show ?case + by (intro MatchP) (auto simp: atms_def dest: safe_regex_safe_formula split: if_splits) +next + case (18 I r) + then show ?case + by (intro MatchF) (auto simp: atms_def dest: safe_regex_safe_formula split: if_splits) +qed (auto simp: assms) + +lemma safe_formula_NegD: + "safe_formula (Formula.Neg \) \ fv \ = {} \ (\x. \ = Formula.Eq (Formula.Var x) (Formula.Var x))" + by (induct "Formula.Neg \" rule: safe_formula_induct) auto + + +subsection \Slicing traces\ + +qualified fun matches :: + "env \ formula \ name \ event_data list \ bool" where + "matches v (Pred r ts) e = (fst e = r \ map (eval_trm v) ts = snd e)" +| "matches v (Let p b \ \) e = + ((\zs v'. length zs = b \ matches (zs @ v') \ e \ matches v \ (p, v')) \ + fst e \ p \ matches v \ e)" +| "matches v (Eq _ _) e = False" +| "matches v (Less _ _) e = False" +| "matches v (LessEq _ _) e = False" +| "matches v (Neg \) e = matches v \ e" +| "matches v (Or \ \) e = (matches v \ e \ matches v \ e)" +| "matches v (And \ \) e = (matches v \ e \ matches v \ e)" +| "matches v (Ands l) e = (\\\set l. matches v \ e)" +| "matches v (Exists \) e = (\z. matches (z # v) \ e)" +| "matches v (Agg y \ b f \) e = (\zs. length zs = b \ matches (zs @ v) \ e)" +| "matches v (Prev I \) e = matches v \ e" +| "matches v (Next I \) e = matches v \ e" +| "matches v (Since \ I \) e = (matches v \ e \ matches v \ e)" +| "matches v (Until \ I \) e = (matches v \ e \ matches v \ e)" +| "matches v (MatchP I r) e = (\\ \ Regex.atms r. matches v \ e)" +| "matches v (MatchF I r) e = (\\ \ Regex.atms r. matches v \ e)" + +lemma matches_cong: + "\x\fv \. v!x = v'!x \ matches v \ e = matches v' \ e" +proof (induct \ arbitrary: v v' e) + case (Pred n ts) + show ?case + by (simp cong: map_cong eval_trm_fv_cong[OF Pred(1)[simplified, THEN bspec]]) +next + case (Let p b \ \) + then show ?case + by (cases e) (auto 11 0) +next + case (Ands l) + have "\\. \ \ (set l) \ matches v \ e = matches v' \ e" + proof - + fix \ assume "\ \ (set l)" + then have "fv \ \ fv (Ands l)" using fv_subset_Ands by blast + then have "\x\fv \. v!x = v'!x" using Ands.prems by blast + then show "matches v \ e = matches v' \ e" using Ands.hyps \\ \ set l\ by blast + qed + then show ?case by simp +next + case (Exists \) + then show ?case unfolding matches.simps by (intro iff_exI) (simp add: fvi_Suc nth_Cons') +next + case (Agg y \ b f \) + have "matches (zs @ v) \ e = matches (zs @ v') \ e" if "length zs = b" for zs + using that Agg.prems by (simp add: Agg.hyps[where v="zs @ v" and v'="zs @ v'"] + nth_append fvi_iff_fv(1)[where b=b]) + then show ?case by auto +qed (auto 9 0 simp add: nth_Cons' fv_regex_alt) + +abbreviation relevant_events where + "relevant_events \ S \ {e. S \ {v. matches v \ e} \ {}}" + +qualified definition slice :: "formula \ env set \ trace \ trace" where + "slice \ S \ = map_\ (\D. D \ relevant_events \ S) \" + +lemma \_slice[simp]: "\ (slice \ S \) = \ \" + unfolding slice_def by (simp add: fun_eq_iff) + +lemma sat_slice_strong: + assumes "v \ S" "dom V = dom V'" + "\p v i. p \ dom V \ (p, v) \ relevant_events \ S \ v \ the (V p) i \ v \ the (V' p) i" + shows "relevant_events \ S - {e. fst e \ dom V} \ E \ + sat \ V v i \ \ sat (map_\ (\D. D \ E) \) V' v i \" + using assms +proof (induction \ arbitrary: V V' v S i) + case (Pred r ts) + show ?case proof (cases "V r") + case None + then have "V' r = None" using \dom V = dom V'\ by auto + with None Pred(1,2) show ?thesis by (auto simp: domIff dest!: subsetD) + next + case (Some a) + moreover obtain a' where "V' r = Some a'" using Some \dom V = dom V'\ by auto + moreover have "(map (eval_trm v) ts \ the (V r) i) = (map (eval_trm v) ts \ the (V' r) i)" + using Some Pred(2,4) by (fastforce intro: domI) + ultimately show ?thesis by simp + qed +next + case (Let p b \ \) + from Let.prems show ?case unfolding sat.simps + proof (intro Let(2)[of S], goal_cases relevant v dom V) + case (V p' v' i) + then show ?case + proof (cases "p' = p") + case [simp]: True + with V show ?thesis + unfolding fun_upd_apply eqTrueI[OF True] if_True option.sel mem_Collect_eq + proof (intro ex_cong conj_cong refl Let(1)[where + S="{zs @ v' | zs v'. length zs = b \ (\v \ S. matches v \ (p, v'))}" and V=V], + goal_cases relevant' v' dom' V') + case (relevant' zs) + then show ?case + by (elim subset_trans[rotated]) (auto simp: set_eq_iff) + next + case (V' zs p' v' i) + then show ?case + by (intro V(4)) (auto simp: set_eq_iff) + qed auto + next + case False + with V(2,3,5,6) show ?thesis + unfolding fun_upd_apply eq_False[THEN iffD2, OF False] if_False + by (intro V(4)) (auto simp: False) + qed + qed (auto simp: dom_def) +next + case (Or \ \) + show ?case using Or.IH[of S V v V'] Or.prems + by (auto simp: Collect_disj_eq Int_Un_distrib subset_iff) +next + case (And \ \) + show ?case using And.IH[of S V v V'] And.prems + by (auto simp: Collect_disj_eq Int_Un_distrib subset_iff) +next + case (Ands l) + obtain "relevant_events (Ands l) S - {e. fst e \ dom V} \ E" "v \ S" using Ands.prems(1) Ands.prems(2) by blast + then have "{e. S \ {v. matches v (Ands l) e} \ {}} - {e. fst e \ dom V} \ E" by simp + have "\\. \ \ set l \ sat \ V v i \ \ sat (map_\ (\D. D \ E) \) V' v i \" + proof - + fix \ assume "\ \ set l" + have "relevant_events \ S = {e. S \ {v. matches v \ e} \ {}}" by simp + have "{e. S \ {v. matches v \ e} \ {}} \ {e. S \ {v. matches v (Ands l) e} \ {}}" (is "?A \ ?B") + proof (rule subsetI) + fix e assume "e \ ?A" + then have "S \ {v. matches v \ e} \ {}" by blast + moreover have "S \ {v. matches v (Ands l) e} \ {}" + proof - + obtain v where "v \ S" "matches v \ e" using calculation by blast + then show ?thesis using \\ \ set l\ by auto + qed + then show "e \ ?B" by blast + qed + then have "relevant_events \ S - {e. fst e \ dom V} \ E" using Ands.prems(1) by auto + then show "sat \ V v i \ \ sat (map_\ (\D. D \ E) \) V' v i \" + using Ands.prems(2,3) \\ \ set l\ + by (intro Ands.IH[of \ S V v V' i] Ands.prems(4)) auto + qed + show ?case using \\\. \ \ set l \ sat \ V v i \ = sat (map_\ (\D. D \ E) \) V' v i \\ sat_Ands by blast +next + case (Exists \) + have "sat \ V (z # v) i \ = sat (map_\ (\D. D \ E) \) V' (z # v) i \" for z + using Exists.prems(1-3) by (intro Exists.IH[where S="{z # v | v. v \ S}"] Exists.prems(4)) auto + then show ?case by simp +next + case (Agg y \ b f \) + have "sat \ V (zs @ v) i \ = sat (map_\ (\D. D \ E) \) V' (zs @ v) i \" if "length zs = b" for zs + using that Agg.prems(1-3) by (intro Agg.IH[where S="{zs @ v | v. v \ S}"] Agg.prems(4)) auto + then show ?case by (simp cong: conj_cong) +next + case (Prev I \) + then show ?case by (auto cong: nat.case_cong) +next + case (Next I \) + then show ?case by simp +next + case (Since \ I \) + show ?case using Since.IH[of S V] Since.prems + by (auto simp: Collect_disj_eq Int_Un_distrib subset_iff) +next + case (Until \ I \) + show ?case using Until.IH[of S V] Until.prems + by (auto simp: Collect_disj_eq Int_Un_distrib subset_iff) +next + case (MatchP I r) + from MatchP.prems(1-3) have "Regex.match (sat \ V v) r = Regex.match (sat (map_\ (\D. D \ E) \) V' v) r" + by (intro Regex.match_fv_cong MatchP(1)[of _ S V v] MatchP.prems(4)) auto + then show ?case + by auto +next + case (MatchF I r) + from MatchF.prems(1-3) have "Regex.match (sat \ V v) r = Regex.match (sat (map_\ (\D. D \ E) \) V' v) r" + by (intro Regex.match_fv_cong MatchF(1)[of _ S V v] MatchF.prems(4)) auto + then show ?case + by auto +qed simp_all + +lemma sat_slice_iff: + assumes "v \ S" + shows "sat \ V v i \ \ sat (slice \ S \) V v i \" + unfolding slice_def + by (rule sat_slice_strong[OF assms]) auto + +qualified lift_definition pslice :: "formula \ env set \ prefix \ prefix" is + "\\ S \. map (\(D, t). (D \ relevant_events \ S, t)) \" + by (auto simp: o_def split_beta) + +lemma prefix_of_pslice_slice: "prefix_of \ \ \ prefix_of (pslice \ R \) (slice \ R \)" + unfolding slice_def + by transfer simp + +lemma plen_pslice[simp]: "plen (pslice \ R \) = plen \" + by transfer simp + +lemma pslice_pnil[simp]: "pslice \ R pnil = pnil" + by transfer simp + +lemma last_ts_pslice[simp]: "last_ts (pslice \ R \) = last_ts \" + by transfer (simp add: last_map case_prod_beta split: list.split) + +lemma prefix_of_replace_prefix: + "prefix_of (pslice \ R \) \ \ prefix_of \ (replace_prefix \ \)" +proof (transfer; safe; goal_cases) + case (1 \ R \ \) + then show ?case + by (subst (asm) (2) stake_sdrop[symmetric, of _ "length \"]) + (auto 0 3 simp: ssorted_shift split_beta o_def stake_shift sdrop_smap[symmetric] + ssorted_sdrop not_le pslice_def simp del: sdrop_smap) +qed + +lemma slice_replace_prefix: + "prefix_of (pslice \ R \) \ \ slice \ R (replace_prefix \ \) = slice \ R \" +unfolding slice_def proof (transfer; safe; goal_cases) + case (1 \ R \ \) + then show ?case + by (subst (asm) (2) stake_sdrop[symmetric, of \ "length \"], + subst (3) stake_sdrop[symmetric, of \ "length \"]) + (auto simp: ssorted_shift split_beta o_def stake_shift sdrop_smap[symmetric] ssorted_sdrop + not_le pslice_def simp del: sdrop_smap cong: map_cong) +qed + +lemma prefix_of_psliceD: + assumes "prefix_of (pslice \ R \) \" + shows "\\'. prefix_of \ \' \ prefix_of (pslice \ R \) (slice \ R \')" +proof - + from assms(1) obtain \' where 1: "prefix_of \ \'" + using ex_prefix_of by blast + then have "prefix_of (pslice \ R \) (slice \ R \')" + unfolding slice_def + by transfer simp + with 1 show ?thesis by blast +qed + +lemma prefix_of_sliceD: + assumes "prefix_of \' (slice \ R \)" + shows "\\''. \' = pslice \ R \'' \ prefix_of \'' \" + using assms unfolding slice_def + by transfer (auto intro!: exI[of _ "stake (length _) _"] elim: sym dest: sorted_stake) + + +subsection \Translation to n-ary conjunction\ + +fun get_and_list :: "formula \ formula list" where + "get_and_list (Ands l) = l" +| "get_and_list \ = [\]" + +lemma fv_get_and: "(\x\(set (get_and_list \)). fvi b x) = fvi b \" + by (induction \ rule: get_and_list.induct) simp_all + +lemma safe_get_and: "safe_formula \ \ list_all safe_neg (get_and_list \)" + by (induction \ rule: get_and_list.induct) (simp_all add: safe_neg_def list_all_iff) + +lemma sat_get_and: "sat \ V v i \ \ list_all (sat \ V v i) (get_and_list \)" + by (induction \ rule: get_and_list.induct) (simp_all add: list_all_iff) + +fun convert_multiway :: "formula \ formula" where + "convert_multiway (Neg \) = Neg (convert_multiway \)" +| "convert_multiway (Or \ \) = Or (convert_multiway \) (convert_multiway \)" +| "convert_multiway (And \ \) = (if safe_assignment (fv \) \ then + And (convert_multiway \) \ + else if safe_formula \ then + Ands (get_and_list (convert_multiway \) @ get_and_list (convert_multiway \)) + else if is_constraint \ then + And (convert_multiway \) \ + else Ands (convert_multiway \ # get_and_list (convert_multiway \)))" +| "convert_multiway (Exists \) = Exists (convert_multiway \)" +| "convert_multiway (Agg y \ b f \) = Agg y \ b f (convert_multiway \)" +| "convert_multiway (Prev I \) = Prev I (convert_multiway \)" +| "convert_multiway (Next I \) = Next I (convert_multiway \)" +| "convert_multiway (Since \ I \) = Since (convert_multiway \) I (convert_multiway \)" +| "convert_multiway (Until \ I \) = Until (convert_multiway \) I (convert_multiway \)" +| "convert_multiway (MatchP I r) = MatchP I (Regex.map_regex convert_multiway r)" +| "convert_multiway (MatchF I r) = MatchF I (Regex.map_regex convert_multiway r)" +| "convert_multiway \ = \" + +abbreviation "convert_multiway_regex \ Regex.map_regex convert_multiway" + +lemma fv_safe_get_and: + "safe_formula \ \ fv \ \ (\x\(set (filter safe_formula (get_and_list \))). fv x)" +proof (induction \ rule: get_and_list.induct) + case (1 l) + obtain pos neg where posneg: "(pos, neg) = partition safe_formula l" by simp + have "get_and_list (Ands l) = l" by simp + have sub: "(\x\set neg. fv x) \ (\x\set pos. fv x)" using "1.prems" posneg by simp + then have "fv (Ands l) \ (\x\set pos. fv x)" + proof - + have "fv (Ands l) = (\x\set pos. fv x) \ (\x\set neg. fv x)" using posneg by auto + then show ?thesis using sub by simp + qed + then show ?case using posneg by auto +qed auto + +lemma ex_safe_get_and: + "safe_formula \ \ list_ex safe_formula (get_and_list \)" +proof (induction \ rule: get_and_list.induct) + case (1 l) + have "get_and_list (Ands l) = l" by simp + obtain pos neg where posneg: "(pos, neg) = partition safe_formula l" by simp + then have "pos \ []" using "1.prems" by simp + then obtain x where "x \ set pos" by fastforce + then show ?case using posneg using Bex_set_list_ex by fastforce +qed simp_all + +lemma case_NegE: "(case \ of Neg \' \ P \' | _ \ False) \ (\\'. \ = Neg \' \ P \' \ Q) \ Q" + by (cases \) simp_all + +lemma convert_multiway_remove_neg: "safe_formula (remove_neg \) \ convert_multiway (remove_neg \) = remove_neg (convert_multiway \)" + by (cases \) (auto elim: case_NegE) + +lemma fv_convert_multiway: "safe_formula \ \ fvi b (convert_multiway \) = fvi b \" +proof (induction \ arbitrary: b rule: safe_formula.induct) + case (9 \ \) + then show ?case by (cases \) (auto simp: fv_get_and Un_commute) +next + case (15 \ I \) + show ?case proof (cases "safe_formula \") + case True + with 15 show ?thesis by simp + next + case False + with "15.prems" obtain \' where "\ = Neg \'" by (simp split: formula.splits) + with False 15 show ?thesis by simp + qed +next + case (16 \ I \) + show ?case proof (cases "safe_formula \") + case True + with 16 show ?thesis by simp + next + case False + with "16.prems" obtain \' where "\ = Neg \'" by (simp split: formula.splits) + with False 16 show ?thesis by simp + qed +next + case (17 I r) + then show ?case + unfolding convert_multiway.simps fvi.simps fv_regex_alt regex.set_map image_image + by (intro arg_cong[where f=Union, OF image_cong[OF refl]]) + (auto dest!: safe_regex_safe_formula) +next + case (18 I r) + then show ?case + unfolding convert_multiway.simps fvi.simps fv_regex_alt regex.set_map image_image + by (intro arg_cong[where f=Union, OF image_cong[OF refl]]) + (auto dest!: safe_regex_safe_formula) +qed (auto simp del: convert_multiway.simps(3)) + +lemma get_and_nonempty: + assumes "safe_formula \" + shows "get_and_list \ \ []" + using assms by (induction \) auto + +lemma future_bounded_get_and: + "list_all future_bounded (get_and_list \) = future_bounded \" + by (induction \) simp_all + +lemma safe_convert_multiway: "safe_formula \ \ safe_formula (convert_multiway \)" +proof (induction \ rule: safe_formula_induct) + case (And_safe \ \) + let ?a = "And \ \" + let ?b = "convert_multiway ?a" + let ?c\ = "convert_multiway \" + let ?c\ = "convert_multiway \" + have b_def: "?b = Ands (get_and_list ?c\ @ get_and_list ?c\)" + using And_safe by simp + show ?case proof - + let ?l = "get_and_list ?c\ @ get_and_list ?c\" + obtain pos neg where posneg: "(pos, neg) = partition safe_formula ?l" by simp + then have "list_all safe_formula pos" by (auto simp: list_all_iff) + have lsafe_neg: "list_all safe_neg ?l" + using And_safe \safe_formula \\ \safe_formula \\ + by (simp add: safe_get_and) + then have "list_all safe_formula (map remove_neg neg)" + proof - + have "\x. x \ set neg \ safe_formula (remove_neg x)" + proof - + fix x assume "x \ set neg" + then have "\ safe_formula x" using posneg by auto + moreover have "safe_neg x" using lsafe_neg \x \ set neg\ + unfolding safe_neg_def list_all_iff partition_set[OF posneg[symmetric], symmetric] + by simp + ultimately show "safe_formula (remove_neg x)" using safe_neg_def by blast + qed + then show ?thesis by (auto simp: list_all_iff) + qed + + have pos_filter: "pos = filter safe_formula (get_and_list ?c\ @ get_and_list ?c\)" + using posneg by simp + have "(\x\set neg. fv x) \ (\x\set pos. fv x)" + proof - + have 1: "fv ?c\ \ (\x\(set (filter safe_formula (get_and_list ?c\))). fv x)" (is "_ \ ?fv\") + using And_safe \safe_formula \\ by (blast intro!: fv_safe_get_and) + have 2: "fv ?c\ \ (\x\(set (filter safe_formula (get_and_list ?c\))). fv x)" (is "_ \ ?fv\") + using And_safe \safe_formula \\ by (blast intro!: fv_safe_get_and) + have "(\x\set neg. fv x) \ fv ?c\ \ fv ?c\" proof - + have "\ (fv ` set neg) \ \ (fv ` (set pos \ set neg))" + by simp + also have "... \ fv (convert_multiway \) \ fv (convert_multiway \)" + unfolding partition_set[OF posneg[symmetric], simplified] + by (simp add: fv_get_and) + finally show ?thesis . + qed + then have "(\x\set neg. fv x) \ ?fv\ \ ?fv\" using 1 2 by blast + then show ?thesis unfolding pos_filter by simp + qed + have "pos \ []" + proof - + obtain x where "x \ set (get_and_list ?c\)" "safe_formula x" + using And_safe \safe_formula \\ ex_safe_get_and by (auto simp: list_ex_iff) + then show ?thesis + unfolding pos_filter by (auto simp: filter_empty_conv) + qed + then show ?thesis unfolding b_def + using \\ (fv ` set neg) \ \ (fv ` set pos)\ \list_all safe_formula (map remove_neg neg)\ + \list_all safe_formula pos\ posneg + by simp + qed +next + case (And_Not \ \) + let ?a = "And \ (Neg \)" + let ?b = "convert_multiway ?a" + let ?c\ = "convert_multiway \" + let ?c\ = "convert_multiway \" + have b_def: "?b = Ands (Neg ?c\ # get_and_list ?c\)" + using And_Not by simp + show ?case proof - + let ?l = "Neg ?c\ # get_and_list ?c\" + note \safe_formula ?c\\ + then have "list_all safe_neg (get_and_list ?c\)" by (simp add: safe_get_and) + moreover have "safe_neg (Neg ?c\)" + using \safe_formula ?c\\ by (simp add: safe_neg_def) + then have lsafe_neg: "list_all safe_neg ?l" using calculation by simp + obtain pos neg where posneg: "(pos, neg) = partition safe_formula ?l" by simp + then have "list_all safe_formula pos" by (auto simp: list_all_iff) + then have "list_all safe_formula (map remove_neg neg)" + proof - + have "\x. x \ (set neg) \ safe_formula (remove_neg x)" + proof - + fix x assume "x \ set neg" + then have "\ safe_formula x" using posneg by (auto simp del: filter.simps) + moreover have "safe_neg x" using lsafe_neg \x \ set neg\ + unfolding safe_neg_def list_all_iff partition_set[OF posneg[symmetric], symmetric] + by simp + ultimately show "safe_formula (remove_neg x)" using safe_neg_def by blast + qed + then show ?thesis using Ball_set_list_all by force + qed + + have pos_filter: "pos = filter safe_formula ?l" + using posneg by simp + have neg_filter: "neg = filter (Not \ safe_formula) ?l" + using posneg by simp + have "(\x\(set neg). fv x) \ (\x\(set pos). fv x)" + proof - + have fv_neg: "(\x\(set neg). fv x) \ (\x\(set ?l). fv x)" using posneg by auto + have "(\x\(set ?l). fv x) \ fv ?c\ \ fv ?c\" + using \safe_formula \\ \safe_formula \\ + by (simp add: fv_get_and fv_convert_multiway) + also have "fv ?c\ \ fv ?c\ \ fv ?c\" + using \safe_formula \\ \safe_formula \\ \fv (Neg \) \ fv \\ + by (simp add: fv_convert_multiway[symmetric]) + finally have "(\x\(set neg). fv x) \ fv ?c\" + using fv_neg unfolding neg_filter by blast + then show ?thesis + unfolding pos_filter + using fv_safe_get_and[OF And_Not.IH(1)] + by auto + qed + have "pos \ []" + proof - + obtain x where "x \ set (get_and_list ?c\)" "safe_formula x" + using And_Not.IH \safe_formula \\ ex_safe_get_and by (auto simp: list_ex_iff) + then show ?thesis + unfolding pos_filter by (auto simp: filter_empty_conv) + qed + then show ?thesis unfolding b_def + using \\ (fv ` set neg) \ \ (fv ` set pos)\ \list_all safe_formula (map remove_neg neg)\ + \list_all safe_formula pos\ posneg + by simp + qed +next + case (Neg \) + have "safe_formula (Neg \') \ safe_formula \'" if "fv \' = {}" for \' + using that by (cases "Neg \'" rule: safe_formula.cases) simp_all + with Neg show ?case by (simp add: fv_convert_multiway) +next + case (MatchP I r) + then show ?case + by (auto 0 3 simp: atms_def fv_convert_multiway intro!: safe_regex_map_regex + elim!: disjE_Not2 case_NegE + dest: safe_regex_safe_formula split: if_splits) +next + case (MatchF I r) + then show ?case + by (auto 0 3 simp: atms_def fv_convert_multiway intro!: safe_regex_map_regex + elim!: disjE_Not2 case_NegE + dest: safe_regex_safe_formula split: if_splits) +qed (auto simp: fv_convert_multiway) + +lemma future_bounded_convert_multiway: "safe_formula \ \ future_bounded (convert_multiway \) = future_bounded \" +proof (induction \ rule: safe_formula_induct) + case (And_safe \ \) + let ?a = "And \ \" + let ?b = "convert_multiway ?a" + let ?c\ = "convert_multiway \" + let ?c\ = "convert_multiway \" + have b_def: "?b = Ands (get_and_list ?c\ @ get_and_list ?c\)" + using And_safe by simp + have "future_bounded ?a = (future_bounded ?c\ \ future_bounded ?c\)" + using And_safe by simp + moreover have "future_bounded ?c\ = list_all future_bounded (get_and_list ?c\)" + using \safe_formula \\ by (simp add: future_bounded_get_and safe_convert_multiway) + moreover have "future_bounded ?c\ = list_all future_bounded (get_and_list ?c\)" + using \safe_formula \\ by (simp add: future_bounded_get_and safe_convert_multiway) + moreover have "future_bounded ?b = list_all future_bounded (get_and_list ?c\ @ get_and_list ?c\)" + unfolding b_def by simp + ultimately show ?case by simp +next + case (And_Not \ \) + let ?a = "And \ (Neg \)" + let ?b = "convert_multiway ?a" + let ?c\ = "convert_multiway \" + let ?c\ = "convert_multiway \" + have b_def: "?b = Ands (Neg ?c\ # get_and_list ?c\)" + using And_Not by simp + have "future_bounded ?a = (future_bounded ?c\ \ future_bounded ?c\)" + using And_Not by simp + moreover have "future_bounded ?c\ = list_all future_bounded (get_and_list ?c\)" + using \safe_formula \\ by (simp add: future_bounded_get_and safe_convert_multiway) + moreover have "future_bounded ?b = list_all future_bounded (Neg ?c\ # get_and_list ?c\)" + unfolding b_def by (simp add: list.pred_map o_def) + ultimately show ?case by auto +next + case (MatchP I r) + then show ?case + by (fastforce simp: atms_def regex.pred_set regex.set_map ball_Un + elim: safe_regex_safe_formula[THEN disjE_Not2]) +next + case (MatchF I r) + then show ?case + by (fastforce simp: atms_def regex.pred_set regex.set_map ball_Un + elim: safe_regex_safe_formula[THEN disjE_Not2]) +qed auto + +lemma sat_convert_multiway: "safe_formula \ \ sat \ V v i (convert_multiway \) \ sat \ V v i \" +proof (induction \ arbitrary: v i rule: safe_formula_induct) + case (And_safe \ \) + let ?a = "And \ \" + let ?b = "convert_multiway ?a" + let ?la = "get_and_list (convert_multiway \)" + let ?lb = "get_and_list (convert_multiway \)" + let ?sat = "sat \ V v i" + have b_def: "?b = Ands (?la @ ?lb)" using And_safe by simp + have "list_all ?sat ?la \ ?sat \" using And_safe sat_get_and by blast + moreover have "list_all ?sat ?lb \ ?sat \" using And_safe sat_get_and by blast + ultimately show ?case using And_safe by (auto simp: list.pred_set) +next + case (And_Not \ \) + let ?a = "And \ (Neg \)" + let ?b = "convert_multiway ?a" + let ?la = "get_and_list (convert_multiway \)" + let ?lb = "convert_multiway \" + let ?sat = "sat \ V v i" + have b_def: "?b = Ands (Neg ?lb # ?la)" using And_Not by simp + have "list_all ?sat ?la \ ?sat \" using And_Not sat_get_and by blast + then show ?case using And_Not by (auto simp: list.pred_set) +next + case (Agg y \ b f \) + then show ?case + by (simp add: nfv_def fv_convert_multiway cong: conj_cong) +next + case (MatchP I r) + then have "Regex.match (sat \ V v) (convert_multiway_regex r) = Regex.match (sat \ V v) r" + unfolding match_map_regex + by (intro Regex.match_fv_cong) + (auto 0 4 simp: atms_def elim!: disjE_Not2 dest!: safe_regex_safe_formula) + then show ?case + by auto +next + case (MatchF I r) + then have "Regex.match (sat \ V v) (convert_multiway_regex r) = Regex.match (sat \ V v) r" + unfolding match_map_regex + by (intro Regex.match_fv_cong) + (auto 0 4 simp: atms_def elim!: disjE_Not2 dest!: safe_regex_safe_formula) + then show ?case + by auto +qed (auto cong: nat.case_cong) + +end (*context*) + +lemma Neg_splits: + "P (case \ of formula.Neg \ \ f \ | \ \ g \) = + ((\\. \ = formula.Neg \ \ P (f \)) \ ((\ Formula.is_Neg \) \ P (g \)))" + "P (case \ of formula.Neg \ \ f \ | _ \ g \) = + (\ ((\\. \ = formula.Neg \ \ \ P (f \)) \ ((\ Formula.is_Neg \) \ \ P (g \))))" + by (cases \; auto simp: Formula.is_Neg_def)+ + +(*<*) +end +(*>*) diff --git a/thys/MFODL_Monitor_Optimized/Interval.thy b/thys/MFODL_Monitor_Optimized/Interval.thy new file mode 100644 --- /dev/null +++ b/thys/MFODL_Monitor_Optimized/Interval.thy @@ -0,0 +1,79 @@ +(*<*) +theory Interval + imports "HOL-Library.Extended_Nat" "HOL-Library.Product_Lexorder" +begin +(*>*) + +section \Intervals\ + +typedef \ = "{(i :: nat, j :: enat). i \ j}" + by (intro exI[of _ "(0, \)"]) auto + +setup_lifting type_definition_\ + +instantiation \ :: equal begin +lift_definition equal_\ :: "\ \ \ \ bool" is "(=)" . +instance by standard (transfer, auto) +end + +instantiation \ :: linorder begin +lift_definition less_eq_\ :: "\ \ \ \ bool" is "(\)" . +lift_definition less_\ :: "\ \ \ \ bool" is "(<)" . +instance by standard (transfer, auto)+ +end + + +lift_definition all :: \ is "(0, \)" by simp +lift_definition left :: "\ \ nat" is fst . +lift_definition right :: "\ \ enat" is snd . +lift_definition point :: "nat \ \" is "\n. (n, enat n)" by simp +lift_definition init :: "nat \ \" is "\n. (0, enat n)" by auto +abbreviation mem where "mem n I \ (left I \ n \ n \ right I)" +lift_definition subtract :: "nat \ \ \ \" is + "\n (i, j). (i - n, j - enat n)" by (auto simp: diff_enat_def split: enat.splits) +lift_definition add :: "nat \ \ \ \" is + "\n (a, b). (a, b + enat n)" by (auto simp add: add_increasing2) + +lemma left_right: "left I \ right I" + by transfer auto + +lemma point_simps[simp]: + "left (point n) = n" + "right (point n) = n" + by (transfer; auto)+ + +lemma init_simps[simp]: + "left (init n) = 0" + "right (init n) = n" + by (transfer; auto)+ + +lemma subtract_simps[simp]: + "left (subtract n I) = left I - n" + "right (subtract n I) = right I - n" + "subtract 0 I = I" + "subtract x (point y) = point (y - x)" + by (transfer; auto)+ + +definition shifted :: "\ \ \ set" where + "shifted I = (\n. subtract n I) ` {0 .. (case right I of \ \ left I | enat n \ n)}" + +lemma subtract_too_much: "i > (case right I of \ \ left I | enat n \ n) \ + subtract i I = subtract (case right I of \ \ left I | enat n \ n) I" + by transfer (auto split: enat.splits) + +lemma subtract_shifted: "subtract n I \ shifted I" + by (cases "n \ (case right I of \ \ left I | enat n \ n)") + (auto simp: shifted_def subtract_too_much) + +lemma finite_shifted: "finite (shifted I)" + unfolding shifted_def by auto + +definition interval :: "nat \ enat \ \" where + "interval l r = (if l \ r then Abs_\ (l, r) else undefined)" + +lemma [code abstract]: "Rep_\ (interval l r) = (if l \ r then (l, r) else Rep_\ undefined)" + unfolding interval_def using Abs_\_inverse by simp + +(*<*) +end +(*>*) \ No newline at end of file diff --git a/thys/MFODL_Monitor_Optimized/Monitor.thy b/thys/MFODL_Monitor_Optimized/Monitor.thy new file mode 100644 --- /dev/null +++ b/thys/MFODL_Monitor_Optimized/Monitor.thy @@ -0,0 +1,5549 @@ +(*<*) +theory Monitor + imports Abstract_Monitor + Optimized_Join + "HOL-Library.While_Combinator" + "HOL-Library.Mapping" + "Deriving.Derive" + "Generic_Join.Generic_Join_Correctness" +begin +(*>*) + +section \Generic monitoring algorithm\ + +text \The algorithm defined here abstracts over the implementation of the temporal operators.\ + +subsection \Monitorable formulas\ + +definition "mmonitorable \ \ safe_formula \ \ Formula.future_bounded \" +definition "mmonitorable_regex b g r \ safe_regex b g r \ Regex.pred_regex Formula.future_bounded r" + +definition is_simple_eq :: "Formula.trm \ Formula.trm \ bool" where + "is_simple_eq t1 t2 = (Formula.is_Const t1 \ (Formula.is_Const t2 \ Formula.is_Var t2) \ + Formula.is_Var t1 \ Formula.is_Const t2)" + +fun mmonitorable_exec :: "Formula.formula \ bool" where + "mmonitorable_exec (Formula.Eq t1 t2) = is_simple_eq t1 t2" +| "mmonitorable_exec (Formula.Neg (Formula.Eq (Formula.Var x) (Formula.Var y))) = (x = y)" +| "mmonitorable_exec (Formula.Pred e ts) = list_all (\t. Formula.is_Var t \ Formula.is_Const t) ts" +| "mmonitorable_exec (Formula.Let p b \ \) = ({0..} \ Formula.fv \ \ b \ Formula.nfv \ \ mmonitorable_exec \ \ mmonitorable_exec \)" +| "mmonitorable_exec (Formula.Neg \) = (fv \ = {} \ mmonitorable_exec \)" +| "mmonitorable_exec (Formula.Or \ \) = (fv \ = fv \ \ mmonitorable_exec \ \ mmonitorable_exec \)" +| "mmonitorable_exec (Formula.And \ \) = (mmonitorable_exec \ \ + (safe_assignment (fv \) \ \ mmonitorable_exec \ \ + fv \ \ fv \ \ (is_constraint \ \ (case \ of Formula.Neg \' \ mmonitorable_exec \' | _ \ False))))" +| "mmonitorable_exec (Formula.Ands l) = (let (pos, neg) = partition mmonitorable_exec l in + pos \ [] \ list_all mmonitorable_exec (map remove_neg neg) \ + \(set (map fv neg)) \ \(set (map fv pos)))" +| "mmonitorable_exec (Formula.Exists \) = (mmonitorable_exec \)" +| "mmonitorable_exec (Formula.Agg y \ b f \) = (mmonitorable_exec \ \ + y + b \ Formula.fv \ \ {0.. Formula.fv \ \ Formula.fv_trm f \ Formula.fv \)" +| "mmonitorable_exec (Formula.Prev I \) = (mmonitorable_exec \)" +| "mmonitorable_exec (Formula.Next I \) = (mmonitorable_exec \)" +| "mmonitorable_exec (Formula.Since \ I \) = (Formula.fv \ \ Formula.fv \ \ + (mmonitorable_exec \ \ (case \ of Formula.Neg \' \ mmonitorable_exec \' | _ \ False)) \ mmonitorable_exec \)" +| "mmonitorable_exec (Formula.Until \ I \) = (Formula.fv \ \ Formula.fv \ \ right I \ \ \ + (mmonitorable_exec \ \ (case \ of Formula.Neg \' \ mmonitorable_exec \' | _ \ False)) \ mmonitorable_exec \)" +| "mmonitorable_exec (Formula.MatchP I r) = Regex.safe_regex Formula.fv (\g \. mmonitorable_exec \ \ (g = Lax \ (case \ of Formula.Neg \' \ mmonitorable_exec \' | _ \ False))) Past Strict r" +| "mmonitorable_exec (Formula.MatchF I r) = (Regex.safe_regex Formula.fv (\g \. mmonitorable_exec \ \ (g = Lax \ (case \ of Formula.Neg \' \ mmonitorable_exec \' | _ \ False))) Futu Strict r \ right I \ \)" +| "mmonitorable_exec _ = False" + +lemma cases_Neg_iff: + "(case \ of formula.Neg \ \ P \ | _ \ False) \ (\\. \ = formula.Neg \ \ P \)" + by (cases \) auto + +lemma safe_formula_mmonitorable_exec: "safe_formula \ \ Formula.future_bounded \ \ mmonitorable_exec \" +proof (induct \ rule: safe_formula.induct) + case (8 \ \) + then show ?case + unfolding safe_formula.simps future_bounded.simps mmonitorable_exec.simps + by (auto simp: cases_Neg_iff) +next + case (9 \ \) + then show ?case + unfolding safe_formula.simps future_bounded.simps mmonitorable_exec.simps + by (auto simp: cases_Neg_iff) +next + case (10 l) + from "10.prems"(2) have bounded: "Formula.future_bounded \" if "\ \ set l" for \ + using that by (auto simp: list.pred_set) + obtain poss negs where posnegs: "(poss, negs) = partition safe_formula l" by simp + obtain posm negm where posnegm: "(posm, negm) = partition mmonitorable_exec l" by simp + have "set poss \ set posm" + proof (rule subsetI) + fix x assume "x \ set poss" + then have "x \ set l" "safe_formula x" using posnegs by simp_all + then have "mmonitorable_exec x" using "10.hyps"(1) bounded by blast + then show "x \ set posm" using \x \ set poss\ posnegm posnegs by simp + qed + then have "set negm \ set negs" using posnegm posnegs by auto + obtain "poss \ []" "list_all safe_formula (map remove_neg negs)" + "(\x\set negs. fv x) \ (\x\set poss. fv x)" + using "10.prems"(1) posnegs by simp + then have "posm \ []" using \set poss \ set posm\ by auto + moreover have "list_all mmonitorable_exec (map remove_neg negm)" + proof - + let ?l = "map remove_neg negm" + have "\x. x \ set ?l \ mmonitorable_exec x" + proof - + fix x assume "x \ set ?l" + then obtain y where "y \ set negm" "x = remove_neg y" by auto + then have "y \ set negs" using \set negm \ set negs\ by blast + then have "safe_formula x" + unfolding \x = remove_neg y\ using \list_all safe_formula (map remove_neg negs)\ + by (simp add: list_all_def) + show "mmonitorable_exec x" + proof (cases "\z. y = Formula.Neg z") + case True + then obtain z where "y = Formula.Neg z" by blast + then show ?thesis + using "10.hyps"(2)[OF posnegs refl] \x = remove_neg y\ \y \ set negs\ posnegs bounded + \safe_formula x\ by fastforce + next + case False + then have "remove_neg y = y" by (cases y) simp_all + then have "y = x" unfolding \x = remove_neg y\ by simp + show ?thesis + using "10.hyps"(1) \y \ set negs\ posnegs \safe_formula x\ unfolding \y = x\ + by auto + qed + qed + then show ?thesis by (simp add: list_all_iff) + qed + moreover have "(\x\set negm. fv x) \ (\x\set posm. fv x)" + using \\ (fv ` set negs) \ \ (fv ` set poss)\ \set poss \ set posm\ \set negm \ set negs\ + by fastforce + ultimately show ?case using posnegm by simp +next + case (15 \ I \) + then show ?case + unfolding safe_formula.simps future_bounded.simps mmonitorable_exec.simps + by (auto simp: cases_Neg_iff) +next + case (16 \ I \) + then show ?case + unfolding safe_formula.simps future_bounded.simps mmonitorable_exec.simps + by (auto simp: cases_Neg_iff) +next + case (17 I r) + then show ?case + by (auto elim!: safe_regex_mono[rotated] simp: cases_Neg_iff regex.pred_set) +next + case (18 I r) + then show ?case + by (auto elim!: safe_regex_mono[rotated] simp: cases_Neg_iff regex.pred_set) +qed (auto simp add: is_simple_eq_def list.pred_set) + +lemma safe_assignment_future_bounded: "safe_assignment X \ \ Formula.future_bounded \" + unfolding safe_assignment_def by (auto split: formula.splits) + +lemma is_constraint_future_bounded: "is_constraint \ \ Formula.future_bounded \" + by (induction rule: is_constraint.induct) simp_all + +lemma mmonitorable_exec_mmonitorable: "mmonitorable_exec \ \ mmonitorable \" +proof (induct \ rule: mmonitorable_exec.induct) + case (7 \ \) + then show ?case + unfolding mmonitorable_def mmonitorable_exec.simps safe_formula.simps + by (auto simp: cases_Neg_iff intro: safe_assignment_future_bounded is_constraint_future_bounded) +next + case (8 l) + obtain poss negs where posnegs: "(poss, negs) = partition safe_formula l" by simp + obtain posm negm where posnegm: "(posm, negm) = partition mmonitorable_exec l" by simp + have pos_monitorable: "list_all mmonitorable_exec posm" using posnegm by (simp add: list_all_iff) + have neg_monitorable: "list_all mmonitorable_exec (map remove_neg negm)" + using "8.prems" posnegm by (simp add: list_all_iff) + have "set posm \ set poss" + using "8.hyps"(1) posnegs posnegm unfolding mmonitorable_def by auto + then have "set negs \ set negm" + using posnegs posnegm by auto + + have "poss \ []" using "8.prems" posnegm \set posm \ set poss\ by auto + moreover have "list_all safe_formula (map remove_neg negs)" + using neg_monitorable "8.hyps"(2)[OF posnegm refl] \set negs \ set negm\ + unfolding mmonitorable_def by (auto simp: list_all_iff) + moreover have "\ (fv ` set negm) \ \ (fv ` set posm)" + using "8.prems" posnegm by simp + then have "\ (fv ` set negs) \ \ (fv ` set poss)" + using \set posm \ set poss\ \set negs \ set negm\ by fastforce + ultimately have "safe_formula (Formula.Ands l)" using posnegs by simp + moreover have "Formula.future_bounded (Formula.Ands l)" + proof - + have "list_all Formula.future_bounded posm" + using pos_monitorable "8.hyps"(1) posnegm unfolding mmonitorable_def + by (auto elim!: list.pred_mono_strong) + moreover have fnegm: "list_all Formula.future_bounded (map remove_neg negm)" + using neg_monitorable "8.hyps"(2) posnegm unfolding mmonitorable_def + by (auto elim!: list.pred_mono_strong) + then have "list_all Formula.future_bounded negm" + proof - + have "\x. x \ set negm \ Formula.future_bounded x" + proof - + fix x assume "x \ set negm" + have "Formula.future_bounded (remove_neg x)" using fnegm \x \ set negm\ by (simp add: list_all_iff) + then show "Formula.future_bounded x" by (cases x) auto + qed + then show ?thesis by (simp add: list_all_iff) + qed + ultimately have "list_all Formula.future_bounded l" using posnegm by (auto simp: list_all_iff) + then show ?thesis by (auto simp: list_all_iff) + qed + ultimately show ?case unfolding mmonitorable_def .. +next + case (13 \ I \) + then show ?case + unfolding mmonitorable_def mmonitorable_exec.simps safe_formula.simps + by (fastforce simp: cases_Neg_iff) +next + case (14 \ I \) + then show ?case + unfolding mmonitorable_def mmonitorable_exec.simps safe_formula.simps + by (fastforce simp: one_enat_def cases_Neg_iff) +next + case (15 I r) + then show ?case + by (auto elim!: safe_regex_mono[rotated] dest: safe_regex_safe[rotated] + simp: mmonitorable_regex_def mmonitorable_def cases_Neg_iff regex.pred_set) +next + case (16 I r) + then show ?case + by (auto 0 3 elim!: safe_regex_mono[rotated] dest: safe_regex_safe[rotated] + simp: mmonitorable_regex_def mmonitorable_def cases_Neg_iff regex.pred_set) +qed (auto simp add: mmonitorable_def mmonitorable_regex_def is_simple_eq_def one_enat_def list.pred_set) + +lemma monitorable_formula_code[code]: "mmonitorable \ = mmonitorable_exec \" + using mmonitorable_exec_mmonitorable safe_formula_mmonitorable_exec mmonitorable_def + by blast + +subsection \Handling regular expressions\ + +datatype mregex = + MSkip nat + | MTestPos nat + | MTestNeg nat + | MPlus mregex mregex + | MTimes mregex mregex + | MStar mregex + +primrec ok where + "ok _ (MSkip n) = True" +| "ok m (MTestPos n) = (n < m)" +| "ok m (MTestNeg n) = (n < m)" +| "ok m (MPlus r s) = (ok m r \ ok m s)" +| "ok m (MTimes r s) = (ok m r \ ok m s)" +| "ok m (MStar r) = ok m r" + +primrec from_mregex where + "from_mregex (MSkip n) _ = Regex.Skip n" +| "from_mregex (MTestPos n) \s = Regex.Test (\s ! n)" +| "from_mregex (MTestNeg n) \s = (if safe_formula (Formula.Neg (\s ! n)) + then Regex.Test (Formula.Neg (Formula.Neg (Formula.Neg (\s ! n)))) + else Regex.Test (Formula.Neg (\s ! n)))" +| "from_mregex (MPlus r s) \s = Regex.Plus (from_mregex r \s) (from_mregex s \s)" +| "from_mregex (MTimes r s) \s = Regex.Times (from_mregex r \s) (from_mregex s \s)" +| "from_mregex (MStar r) \s = Regex.Star (from_mregex r \s)" + +primrec to_mregex_exec where + "to_mregex_exec (Regex.Skip n) xs = (MSkip n, xs)" +| "to_mregex_exec (Regex.Test \) xs = (if safe_formula \ then (MTestPos (length xs), xs @ [\]) + else case \ of Formula.Neg \' \ (MTestNeg (length xs), xs @ [\']) | _ \ (MSkip 0, xs))" +| "to_mregex_exec (Regex.Plus r s) xs = + (let (mr, ys) = to_mregex_exec r xs; (ms, zs) = to_mregex_exec s ys + in (MPlus mr ms, zs))" +| "to_mregex_exec (Regex.Times r s) xs = + (let (mr, ys) = to_mregex_exec r xs; (ms, zs) = to_mregex_exec s ys + in (MTimes mr ms, zs))" +| "to_mregex_exec (Regex.Star r) xs = + (let (mr, ys) = to_mregex_exec r xs in (MStar mr, ys))" + +primrec shift where + "shift (MSkip n) k = MSkip n" +| "shift (MTestPos i) k = MTestPos (i + k)" +| "shift (MTestNeg i) k = MTestNeg (i + k)" +| "shift (MPlus r s) k = MPlus (shift r k) (shift s k)" +| "shift (MTimes r s) k = MTimes (shift r k) (shift s k)" +| "shift (MStar r) k = MStar (shift r k)" + +primrec to_mregex where + "to_mregex (Regex.Skip n) = (MSkip n, [])" +| "to_mregex (Regex.Test \) = (if safe_formula \ then (MTestPos 0, [\]) + else case \ of Formula.Neg \' \ (MTestNeg 0, [\']) | _ \ (MSkip 0, []))" +| "to_mregex (Regex.Plus r s) = + (let (mr, ys) = to_mregex r; (ms, zs) = to_mregex s + in (MPlus mr (shift ms (length ys)), ys @ zs))" +| "to_mregex (Regex.Times r s) = + (let (mr, ys) = to_mregex r; (ms, zs) = to_mregex s + in (MTimes mr (shift ms (length ys)), ys @ zs))" +| "to_mregex (Regex.Star r) = + (let (mr, ys) = to_mregex r in (MStar mr, ys))" + +lemma shift_0: "shift r 0 = r" + by (induct r) auto + +lemma shift_shift: "shift (shift r k) j = shift r (k + j)" + by (induct r) auto + +lemma to_mregex_to_mregex_exec: + "case to_mregex r of (mr, \s) \ to_mregex_exec r xs = (shift mr (length xs), xs @ \s)" + by (induct r arbitrary: xs) + (auto simp: shift_shift ac_simps split: formula.splits prod.splits) + +lemma to_mregex_to_mregex_exec_Nil[code]: "to_mregex r = to_mregex_exec r []" + using to_mregex_to_mregex_exec[where xs="[]" and r = r] by (auto simp: shift_0) + +lemma ok_mono: "ok m mr \ m \ n \ ok n mr" + by (induct mr) auto + +lemma from_mregex_cong: "ok m mr \ (\i < m. xs ! i = ys ! i) \ from_mregex mr xs = from_mregex mr ys" + by (induct mr) auto + +lemma not_Neg_cases: + "(\\. \ \ Formula.Neg \) \ (case \ of formula.Neg \ \ f \ | _ \ x) = x" + by (cases \) auto + +lemma to_mregex_exec_ok: + "to_mregex_exec r xs = (mr, ys) \ \zs. ys = xs @ zs \ set zs = atms r \ ok (length ys) mr" +proof (induct r arbitrary: xs mr ys) + case (Skip x) + then show ?case by (auto split: if_splits prod.splits simp: atms_def elim: ok_mono) +next + case (Test x) + show ?case proof (cases "\x'. x = Formula.Neg x'") + case True + with Test show ?thesis by (auto split: if_splits prod.splits simp: atms_def elim: ok_mono) + next + case False + with Test show ?thesis by (auto split: if_splits prod.splits simp: atms_def not_Neg_cases elim: ok_mono) + qed +next + case (Plus r1 r2) + then show ?case by (fastforce split: if_splits prod.splits formula.splits simp: atms_def elim: ok_mono) +next + case (Times r1 r2) + then show ?case by (fastforce split: if_splits prod.splits formula.splits simp: atms_def elim: ok_mono) +next + case (Star r) + then show ?case by (auto split: if_splits prod.splits simp: atms_def elim: ok_mono) +qed + +lemma ok_shift: "ok (i + m) (Monitor.shift r i) \ ok m r" + by (induct r) auto + +lemma to_mregex_ok: "to_mregex r = (mr, ys) \ set ys = atms r \ ok (length ys) mr" +proof (induct r arbitrary: mr ys) + case (Skip x) + then show ?case by (auto simp: atms_def elim: ok_mono split: if_splits prod.splits) +next + case (Test x) + show ?case proof (cases "\x'. x = Formula.Neg x'") + case True + with Test show ?thesis by (auto split: if_splits prod.splits simp: atms_def elim: ok_mono) + next + case False + with Test show ?thesis by (auto split: if_splits prod.splits simp: atms_def not_Neg_cases elim: ok_mono) + qed +next + case (Plus r1 r2) + then show ?case by (fastforce simp: ok_shift atms_def elim: ok_mono split: if_splits prod.splits) +next + case (Times r1 r2) + then show ?case by (fastforce simp: ok_shift atms_def elim: ok_mono split: if_splits prod.splits) +next + case (Star r) + then show ?case by (auto simp: atms_def elim: ok_mono split: if_splits prod.splits) +qed + +lemma from_mregex_shift: "from_mregex (shift r (length xs)) (xs @ ys) = from_mregex r ys" + by (induct r) (auto simp: nth_append) + +lemma from_mregex_to_mregex: "safe_regex m g r \ case_prod from_mregex (to_mregex r) = r" + by (induct r rule: safe_regex.induct) + (auto dest: to_mregex_ok intro!: from_mregex_cong simp: nth_append from_mregex_shift cases_Neg_iff + split: prod.splits modality.splits) + +lemma from_mregex_eq: "safe_regex m g r \ to_mregex r = (mr, \s) \ from_mregex mr \s = r" + using from_mregex_to_mregex[of m g r] by auto + +lemma from_mregex_to_mregex_exec: "safe_regex m g r \ case_prod from_mregex (to_mregex_exec r xs) = r" +proof (induct r arbitrary: xs rule: safe_regex_induct) + case (Plus b g r s) + from Plus(3) Plus(1)[of xs] Plus(2)[of "snd (to_mregex_exec r xs)"] show ?case + by (auto split: prod.splits simp: nth_append dest: to_mregex_exec_ok + intro!: from_mregex_cong[where m = "length (snd (to_mregex_exec r xs))"]) +next + case (TimesF g r s) + from TimesF(3) TimesF(2)[of xs] TimesF(1)[of "snd (to_mregex_exec r xs)"] show ?case + by (auto split: prod.splits simp: nth_append dest: to_mregex_exec_ok + intro!: from_mregex_cong[where m = "length (snd (to_mregex_exec r xs))"]) +next + case (TimesP g r s) + from TimesP(3) TimesP(1)[of xs] TimesP(2)[of "snd (to_mregex_exec r xs)"] show ?case + by (auto split: prod.splits simp: nth_append dest: to_mregex_exec_ok + intro!: from_mregex_cong[where m = "length (snd (to_mregex_exec r xs))"]) +next + case (Star b g r) + from Star(2) Star(1)[of xs] show ?case + by (auto split: prod.splits) +qed (auto split: prod.splits simp: cases_Neg_iff) + + +derive linorder mregex + +subsubsection \LPD\ + +definition saturate where + "saturate f = while (\S. f S \ S) f" + +lemma saturate_code[code]: + "saturate f S = (let S' = f S in if S' = S then S else saturate f S')" + unfolding saturate_def Let_def + by (subst while_unfold) auto + +definition "MTimesL r S = MTimes r ` S" +definition "MTimesR R s = (\r. MTimes r s) ` R" + +primrec LPD where + "LPD (MSkip n) = (case n of 0 \ {} | Suc m \ {MSkip m})" +| "LPD (MTestPos \) = {}" +| "LPD (MTestNeg \) = {}" +| "LPD (MPlus r s) = (LPD r \ LPD s)" +| "LPD (MTimes r s) = MTimesR (LPD r) s \ LPD s" +| "LPD (MStar r) = MTimesR (LPD r) (MStar r)" + +primrec LPDi where + "LPDi 0 r = {r}" +| "LPDi (Suc i) r = (\s \ LPD r. LPDi i s)" + +lemma LPDi_Suc_alt: "LPDi (Suc i) r = (\s \ LPDi i r. LPD s)" + by (induct i arbitrary: r) fastforce+ + +definition "LPDs r = (\i. LPDi i r)" + +lemma LPDs_refl: "r \ LPDs r" + by (auto simp: LPDs_def intro: exI[of _ 0]) +lemma LPDs_trans: "r \ LPD s \ s \ LPDs t \ r \ LPDs t" + by (force simp: LPDs_def LPDi_Suc_alt simp del: LPDi.simps intro: exI[of _ "Suc _"]) + +lemma LPDi_Test: + "LPDi i (MSkip 0) \ {MSkip 0}" + "LPDi i (MTestPos \) \ {MTestPos \}" + "LPDi i (MTestNeg \) \ {MTestNeg \}" + by (induct i) auto + +lemma LPDs_Test: + "LPDs (MSkip 0) \ {MSkip 0}" + "LPDs (MTestPos \) \ {MTestPos \}" + "LPDs (MTestNeg \) \ {MTestNeg \}" + unfolding LPDs_def using LPDi_Test by blast+ + +lemma LPDi_MSkip: "LPDi i (MSkip n) \ MSkip ` {i. i \ n}" + by (induct i arbitrary: n) (auto dest: set_mp[OF LPDi_Test(1)] simp: le_Suc_eq split: nat.splits) + +lemma LPDs_MSkip: "LPDs (MSkip n) \ MSkip ` {i. i \ n}" + unfolding LPDs_def using LPDi_MSkip by auto + +lemma LPDi_Plus: "LPDi i (MPlus r s) \ {MPlus r s} \ LPDi i r \ LPDi i s" + by (induct i arbitrary: r s) auto + +lemma LPDs_Plus: "LPDs (MPlus r s) \ {MPlus r s} \ LPDs r \ LPDs s" + unfolding LPDs_def using LPDi_Plus[of _ r s] by auto + +lemma LPDi_Times: + "LPDi i (MTimes r s) \ {MTimes r s} \ MTimesR (\j \ i. LPDi j r) s \ (\j \ i. LPDi j s)" +proof (induct i arbitrary: r s) + case (Suc i) + show ?case + by (fastforce simp: MTimesR_def dest: bspec[of _ _ "Suc _"] dest!: set_mp[OF Suc]) +qed simp + +lemma LPDs_Times: "LPDs (MTimes r s) \ {MTimes r s} \ MTimesR (LPDs r) s \ LPDs s" + unfolding LPDs_def using LPDi_Times[of _ r s] by (force simp: MTimesR_def) + +lemma LPDi_Star: "j \ i \ LPDi j (MStar r) \ {MStar r} \ MTimesR (\j \ i. LPDi j r) (MStar r)" +proof (induct i arbitrary: j r) + case (Suc i) + from Suc(2) show ?case + by (auto 0 5 simp: MTimesR_def image_iff le_Suc_eq + dest: bspec[of _ _ "Suc 0"] bspec[of _ _ "Suc _"] set_mp[OF Suc(1)] dest!: set_mp[OF LPDi_Times]) +qed simp + +lemma LPDs_Star: "LPDs (MStar r) \ {MStar r} \ MTimesR (LPDs r) (MStar r)" + unfolding LPDs_def using LPDi_Star[OF order_refl, of _ r] by (force simp: MTimesR_def) + +lemma finite_LPDs: "finite (LPDs r)" +proof (induct r) + case (MSkip n) + then show ?case by (intro finite_subset[OF LPDs_MSkip]) simp +next + case (MTestPos \) + then show ?case by (intro finite_subset[OF LPDs_Test(2)]) simp +next + case (MTestNeg \) + then show ?case by (intro finite_subset[OF LPDs_Test(3)]) simp +next + case (MPlus r s) + then show ?case by (intro finite_subset[OF LPDs_Plus]) simp +next + case (MTimes r s) + then show ?case by (intro finite_subset[OF LPDs_Times]) (simp add: MTimesR_def) +next + case (MStar r) + then show ?case by (intro finite_subset[OF LPDs_Star]) (simp add: MTimesR_def) +qed + +context begin + +private abbreviation (input) "addLPD r \ \S. insert r S \ Set.bind (insert r S) LPD" + +private lemma mono_addLPD: "mono (addLPD r)" + unfolding mono_def Set.bind_def by auto + +private lemma LPDs_aux1: "lfp (addLPD r) \ LPDs r" + by (rule lfp_induct[OF mono_addLPD], auto intro: LPDs_refl LPDs_trans simp: Set.bind_def) + +private lemma LPDs_aux2: "LPDi i r \ lfp (addLPD r)" +proof (induct i) + case 0 + then show ?case + by (subst lfp_unfold[OF mono_addLPD]) auto +next + case (Suc i) + then show ?case + by (subst lfp_unfold[OF mono_addLPD]) (auto simp: LPDi_Suc_alt simp del: LPDi.simps) +qed + +lemma LPDs_alt: "LPDs r = lfp (addLPD r)" + using LPDs_aux1 LPDs_aux2 by (force simp: LPDs_def) + +lemma LPDs_code[code]: + "LPDs r = saturate (addLPD r) {}" + unfolding LPDs_alt saturate_def + by (rule lfp_while[OF mono_addLPD _ finite_LPDs, of r]) (auto simp: LPDs_refl LPDs_trans Set.bind_def) + +end + +subsubsection \RPD\ + +primrec RPD where + "RPD (MSkip n) = (case n of 0 \ {} | Suc m \ {MSkip m})" +| "RPD (MTestPos \) = {}" +| "RPD (MTestNeg \) = {}" +| "RPD (MPlus r s) = (RPD r \ RPD s)" +| "RPD (MTimes r s) = MTimesL r (RPD s) \ RPD r" +| "RPD (MStar r) = MTimesL (MStar r) (RPD r)" + +primrec RPDi where + "RPDi 0 r = {r}" +| "RPDi (Suc i) r = (\s \ RPD r. RPDi i s)" + +lemma RPDi_Suc_alt: "RPDi (Suc i) r = (\s \ RPDi i r. RPD s)" + by (induct i arbitrary: r) fastforce+ + +definition "RPDs r = (\i. RPDi i r)" + +lemma RPDs_refl: "r \ RPDs r" + by (auto simp: RPDs_def intro: exI[of _ 0]) +lemma RPDs_trans: "r \ RPD s \ s \ RPDs t \ r \ RPDs t" + by (force simp: RPDs_def RPDi_Suc_alt simp del: RPDi.simps intro: exI[of _ "Suc _"]) + +lemma RPDi_Test: + "RPDi i (MSkip 0) \ {MSkip 0}" + "RPDi i (MTestPos \) \ {MTestPos \}" + "RPDi i (MTestNeg \) \ {MTestNeg \}" + by (induct i) auto + +lemma RPDs_Test: + "RPDs (MSkip 0) \ {MSkip 0}" + "RPDs (MTestPos \) \ {MTestPos \}" + "RPDs (MTestNeg \) \ {MTestNeg \}" + unfolding RPDs_def using RPDi_Test by blast+ + +lemma RPDi_MSkip: "RPDi i (MSkip n) \ MSkip ` {i. i \ n}" + by (induct i arbitrary: n) (auto dest: set_mp[OF RPDi_Test(1)] simp: le_Suc_eq split: nat.splits) + +lemma RPDs_MSkip: "RPDs (MSkip n) \ MSkip ` {i. i \ n}" + unfolding RPDs_def using RPDi_MSkip by auto + +lemma RPDi_Plus: "RPDi i (MPlus r s) \ {MPlus r s} \ RPDi i r \ RPDi i s" + by (induct i arbitrary: r s) auto + +lemma RPDi_Suc_RPD_Plus: + "RPDi (Suc i) r \ RPDs (MPlus r s)" + "RPDi (Suc i) s \ RPDs (MPlus r s)" + unfolding RPDs_def by (force intro!: exI[of _ "Suc i"])+ + +lemma RPDs_Plus: "RPDs (MPlus r s) \ {MPlus r s} \ RPDs r \ RPDs s" + unfolding RPDs_def using RPDi_Plus[of _ r s] by auto + +lemma RPDi_Times: + "RPDi i (MTimes r s) \ {MTimes r s} \ MTimesL r (\j \ i. RPDi j s) \ (\j \ i. RPDi j r)" +proof (induct i arbitrary: r s) + case (Suc i) + show ?case + by (fastforce simp: MTimesL_def dest: bspec[of _ _ "Suc _"] dest!: set_mp[OF Suc]) +qed simp + +lemma RPDs_Times: "RPDs (MTimes r s) \ {MTimes r s} \ MTimesL r (RPDs s) \ RPDs r" + unfolding RPDs_def using RPDi_Times[of _ r s] by (force simp: MTimesL_def) + +lemma RPDi_Star: "j \ i \ RPDi j (MStar r) \ {MStar r} \ MTimesL (MStar r) (\j \ i. RPDi j r)" +proof (induct i arbitrary: j r) + case (Suc i) + from Suc(2) show ?case + by (auto 0 5 simp: MTimesL_def image_iff le_Suc_eq + dest: bspec[of _ _ "Suc 0"] bspec[of _ _ "Suc _"] set_mp[OF Suc(1)] dest!: set_mp[OF RPDi_Times]) +qed simp + +lemma RPDs_Star: "RPDs (MStar r) \ {MStar r} \ MTimesL (MStar r) (RPDs r)" + unfolding RPDs_def using RPDi_Star[OF order_refl, of _ r] by (force simp: MTimesL_def) + +lemma finite_RPDs: "finite (RPDs r)" +proof (induct r) + case MSkip + then show ?case by (intro finite_subset[OF RPDs_MSkip]) simp +next + case (MTestPos \) + then show ?case by (intro finite_subset[OF RPDs_Test(2)]) simp +next + case (MTestNeg \) + then show ?case by (intro finite_subset[OF RPDs_Test(3)]) simp +next + case (MPlus r s) + then show ?case by (intro finite_subset[OF RPDs_Plus]) simp +next + case (MTimes r s) + then show ?case by (intro finite_subset[OF RPDs_Times]) (simp add: MTimesL_def) +next + case (MStar r) + then show ?case by (intro finite_subset[OF RPDs_Star]) (simp add: MTimesL_def) +qed + +context begin + +private abbreviation (input) "addRPD r \ \S. insert r S \ Set.bind (insert r S) RPD" + +private lemma mono_addRPD: "mono (addRPD r)" + unfolding mono_def Set.bind_def by auto + +private lemma RPDs_aux1: "lfp (addRPD r) \ RPDs r" + by (rule lfp_induct[OF mono_addRPD], auto intro: RPDs_refl RPDs_trans simp: Set.bind_def) + +private lemma RPDs_aux2: "RPDi i r \ lfp (addRPD r)" +proof (induct i) + case 0 + then show ?case + by (subst lfp_unfold[OF mono_addRPD]) auto +next + case (Suc i) + then show ?case + by (subst lfp_unfold[OF mono_addRPD]) (auto simp: RPDi_Suc_alt simp del: RPDi.simps) +qed + +lemma RPDs_alt: "RPDs r = lfp (addRPD r)" + using RPDs_aux1 RPDs_aux2 by (force simp: RPDs_def) + +lemma RPDs_code[code]: + "RPDs r = saturate (addRPD r) {}" + unfolding RPDs_alt saturate_def + by (rule lfp_while[OF mono_addRPD _ finite_RPDs, of r]) (auto simp: RPDs_refl RPDs_trans Set.bind_def) + +end + +subsection \The executable monitor\ + +type_synonym ts = nat + +type_synonym 'a mbuf2 = "'a table list \ 'a table list" +type_synonym 'a mbufn = "'a table list list" +type_synonym 'a msaux = "(ts \ 'a table) list" +type_synonym 'a muaux = "(ts \ 'a table \ 'a table) list" +type_synonym 'a mr\aux = "(ts \ (mregex, 'a table) mapping) list" +type_synonym 'a ml\aux = "(ts \ 'a table list \ 'a table) list" + +datatype mconstraint = MEq | MLess | MLessEq + +record args = + args_ivl :: \ + args_n :: nat + args_L :: "nat set" + args_R :: "nat set" + args_pos :: bool + +datatype (dead 'msaux, dead 'muaux) mformula = + MRel "event_data table" + | MPred Formula.name "Formula.trm list" + | MLet Formula.name nat nat "('msaux, 'muaux) mformula" "('msaux, 'muaux) mformula" + | MAnd "nat set" "('msaux, 'muaux) mformula" bool "nat set" "('msaux, 'muaux) mformula" "event_data mbuf2" + | MAndAssign "('msaux, 'muaux) mformula" "nat \ Formula.trm" + | MAndRel "('msaux, 'muaux) mformula" "Formula.trm \ bool \ mconstraint \ Formula.trm" + | MAnds "nat set list" "nat set list" "('msaux, 'muaux) mformula list" "event_data mbufn" + | MOr "('msaux, 'muaux) mformula" "('msaux, 'muaux) mformula" "event_data mbuf2" + | MNeg "('msaux, 'muaux) mformula" + | MExists "('msaux, 'muaux) mformula" + | MAgg bool nat Formula.agg_op nat "Formula.trm" "('msaux, 'muaux) mformula" + | MPrev \ "('msaux, 'muaux) mformula" bool "event_data table list" "ts list" + | MNext \ "('msaux, 'muaux) mformula" bool "ts list" + | MSince args "('msaux, 'muaux) mformula" "('msaux, 'muaux) mformula" "event_data mbuf2" "ts list" "'msaux" + | MUntil args "('msaux, 'muaux) mformula" "('msaux, 'muaux) mformula" "event_data mbuf2" "ts list" "'muaux" + | MMatchP \ "mregex" "mregex list" "('msaux, 'muaux) mformula list" "event_data mbufn" "ts list" "event_data mr\aux" + | MMatchF \ "mregex" "mregex list" "('msaux, 'muaux) mformula list" "event_data mbufn" "ts list" "event_data ml\aux" + +record ('msaux, 'muaux) mstate = + mstate_i :: nat + mstate_m :: "('msaux, 'muaux) mformula" + mstate_n :: nat + +fun eq_rel :: "nat \ Formula.trm \ Formula.trm \ event_data table" where + "eq_rel n (Formula.Const x) (Formula.Const y) = (if x = y then unit_table n else empty_table)" +| "eq_rel n (Formula.Var x) (Formula.Const y) = singleton_table n x y" +| "eq_rel n (Formula.Const x) (Formula.Var y) = singleton_table n y x" +| "eq_rel n _ _ = undefined" + +lemma regex_atms_size: "x \ regex.atms r \ size x < regex.size_regex size r" + by (induct r) auto + +lemma atms_size: + assumes "x \ atms r" + shows "size x < Regex.size_regex size r" +proof - + { fix y assume "y \ regex.atms r" "case y of formula.Neg z \ x = z | _ \ False" + then have "size x < Regex.size_regex size r" + by (cases y rule: formula.exhaust) (auto dest: regex_atms_size) + } + with assms show ?thesis + unfolding atms_def + by (auto split: formula.splits dest: regex_atms_size) +qed + +definition init_args :: "\ \ nat \ nat set \ nat set \ bool \ args" where + "init_args I n L R pos = \args_ivl = I, args_n = n, args_L = L, args_R = R, args_pos = pos\" + +locale msaux = + fixes valid_msaux :: "args \ ts \ 'msaux \ event_data msaux \ bool" + and init_msaux :: "args \ 'msaux" + and add_new_ts_msaux :: "args \ ts \ 'msaux \ 'msaux" + and join_msaux :: "args \ event_data table \ 'msaux \ 'msaux" + and add_new_table_msaux :: "args \ event_data table \ 'msaux \ 'msaux" + and result_msaux :: "args \ 'msaux \ event_data table" + assumes valid_init_msaux: "L \ R \ + valid_msaux (init_args I n L R pos) 0 (init_msaux (init_args I n L R pos)) []" + assumes valid_add_new_ts_msaux: "valid_msaux args cur aux auxlist \ nt \ cur \ + valid_msaux args nt (add_new_ts_msaux args nt aux) + (filter (\(t, rel). enat (nt - t) \ right (args_ivl args)) auxlist)" + assumes valid_join_msaux: "valid_msaux args cur aux auxlist \ + table (args_n args) (args_L args) rel1 \ + valid_msaux args cur (join_msaux args rel1 aux) + (map (\(t, rel). (t, join rel (args_pos args) rel1)) auxlist)" + assumes valid_add_new_table_msaux: "valid_msaux args cur aux auxlist \ + table (args_n args) (args_R args) rel2 \ + valid_msaux args cur (add_new_table_msaux args rel2 aux) + (case auxlist of + [] => [(cur, rel2)] + | ((t, y) # ts) \ if t = cur then (t, y \ rel2) # ts else (cur, rel2) # auxlist)" + and valid_result_msaux: "valid_msaux args cur aux auxlist \ result_msaux args aux = + foldr (\) [rel. (t, rel) \ auxlist, left (args_ivl args) \ cur - t] {}" + +fun check_before :: "\ \ ts \ (ts \ 'a \ 'b) \ bool" where + "check_before I dt (t, a, b) \ enat t + right I < enat dt" + +fun proj_thd :: "('a \ 'b \ 'c) \ 'c" where + "proj_thd (t, a1, a2) = a2" + +definition update_until :: "args \ event_data table \ event_data table \ ts \ event_data muaux \ event_data muaux" where + "update_until args rel1 rel2 nt aux = + (map (\x. case x of (t, a1, a2) \ (t, if (args_pos args) then join a1 True rel1 else a1 \ rel1, + if mem (nt - t) (args_ivl args) then a2 \ join rel2 (args_pos args) a1 else a2)) aux) @ + [(nt, rel1, if left (args_ivl args) = 0 then rel2 else empty_table)]" + +lemma map_proj_thd_update_until: "map proj_thd (takeWhile (check_before (args_ivl args) nt) auxlist) = + map proj_thd (takeWhile (check_before (args_ivl args) nt) (update_until args rel1 rel2 nt auxlist))" +proof (induction auxlist) + case Nil + then show ?case by (simp add: update_until_def) +next + case (Cons a auxlist) + then show ?case + by (cases "right (args_ivl args)") (auto simp add: update_until_def split: if_splits prod.splits) +qed + +fun eval_until :: "\ \ ts \ event_data muaux \ event_data table list \ event_data muaux" where + "eval_until I nt [] = ([], [])" +| "eval_until I nt ((t, a1, a2) # aux) = (if t + right I < nt then + (let (xs, aux) = eval_until I nt aux in (a2 # xs, aux)) else ([], (t, a1, a2) # aux))" + +lemma eval_until_length: + "eval_until I nt auxlist = (res, auxlist') \ length auxlist = length res + length auxlist'" + by (induction I nt auxlist arbitrary: res auxlist' rule: eval_until.induct) + (auto split: if_splits prod.splits) + +lemma eval_until_res: "eval_until I nt auxlist = (res, auxlist') \ + res = map proj_thd (takeWhile (check_before I nt) auxlist)" + by (induction I nt auxlist arbitrary: res auxlist' rule: eval_until.induct) + (auto split: prod.splits) + +lemma eval_until_auxlist': "eval_until I nt auxlist = (res, auxlist') \ + auxlist' = drop (length res) auxlist" + by (induction I nt auxlist arbitrary: res auxlist' rule: eval_until.induct) + (auto split: if_splits prod.splits) + +locale muaux = + fixes valid_muaux :: "args \ ts \ 'muaux \ event_data muaux \ bool" + and init_muaux :: "args \ 'muaux" + and add_new_muaux :: "args \ event_data table \ event_data table \ ts \ 'muaux \ 'muaux" + and length_muaux :: "args \ 'muaux \ nat" + and eval_muaux :: "args \ ts \ 'muaux \ event_data table list \ 'muaux" + assumes valid_init_muaux: "L \ R \ + valid_muaux (init_args I n L R pos) 0 (init_muaux (init_args I n L R pos)) []" + assumes valid_add_new_muaux: "valid_muaux args cur aux auxlist \ + table (args_n args) (args_L args) rel1 \ + table (args_n args) (args_R args) rel2 \ + nt \ cur \ + valid_muaux args nt (add_new_muaux args rel1 rel2 nt aux) + (update_until args rel1 rel2 nt auxlist)" + assumes valid_length_muaux: "valid_muaux args cur aux auxlist \ length_muaux args aux = length auxlist" + assumes valid_eval_muaux: "valid_muaux args cur aux auxlist \ nt \ cur \ + eval_muaux args nt aux = (res, aux') \ eval_until (args_ivl args) nt auxlist = (res', auxlist') \ + res = res' \ valid_muaux args cur aux' auxlist'" + +locale maux = msaux valid_msaux init_msaux add_new_ts_msaux join_msaux add_new_table_msaux result_msaux + + muaux valid_muaux init_muaux add_new_muaux length_muaux eval_muaux + for valid_msaux :: "args \ ts \ 'msaux \ event_data msaux \ bool" + and init_msaux :: "args \ 'msaux" + and add_new_ts_msaux :: "args \ ts \ 'msaux \ 'msaux" + and join_msaux :: "args \ event_data table \ 'msaux \ 'msaux" + and add_new_table_msaux :: "args \ event_data table \ 'msaux \ 'msaux" + and result_msaux :: "args \ 'msaux \ event_data table" + and valid_muaux :: "args \ ts \ 'muaux \ event_data muaux \ bool" + and init_muaux :: "args \ 'muaux" + and add_new_muaux :: "args \ event_data table \ event_data table \ ts \ 'muaux \ 'muaux" + and length_muaux :: "args \ 'muaux \ nat" + and eval_muaux :: "args \ nat \ 'muaux \ event_data table list \ 'muaux" + +fun split_assignment :: "nat set \ Formula.formula \ nat \ Formula.trm" where + "split_assignment X (Formula.Eq t1 t2) = (case (t1, t2) of + (Formula.Var x, Formula.Var y) \ if x \ X then (y, t1) else (x, t2) + | (Formula.Var x, _) \ (x, t2) + | (_, Formula.Var y) \ (y, t1))" +| "split_assignment _ _ = undefined" + +fun split_constraint :: "Formula.formula \ Formula.trm \ bool \ mconstraint \ Formula.trm" where + "split_constraint (Formula.Eq t1 t2) = (t1, True, MEq, t2)" +| "split_constraint (Formula.Less t1 t2) = (t1, True, MLess, t2)" +| "split_constraint (Formula.LessEq t1 t2) = (t1, True, MLessEq, t2)" +| "split_constraint (Formula.Neg (Formula.Eq t1 t2)) = (t1, False, MEq, t2)" +| "split_constraint (Formula.Neg (Formula.Less t1 t2)) = (t1, False, MLess, t2)" +| "split_constraint (Formula.Neg (Formula.LessEq t1 t2)) = (t1, False, MLessEq, t2)" +| "split_constraint _ = undefined" + +function (in maux) (sequential) minit0 :: "nat \ Formula.formula \ ('msaux, 'muaux) mformula" where + "minit0 n (Formula.Neg \) = (if fv \ = {} then MNeg (minit0 n \) else MRel empty_table)" +| "minit0 n (Formula.Eq t1 t2) = MRel (eq_rel n t1 t2)" +| "minit0 n (Formula.Pred e ts) = MPred e ts" +| "minit0 n (Formula.Let p b \ \) = MLet p (Formula.nfv \) b (minit0 (Formula.nfv \) \) (minit0 n \)" +| "minit0 n (Formula.Or \ \) = MOr (minit0 n \) (minit0 n \) ([], [])" +| "minit0 n (Formula.And \ \) = (if safe_assignment (fv \) \ then + MAndAssign (minit0 n \) (split_assignment (fv \) \) + else if safe_formula \ then + MAnd (fv \) (minit0 n \) True (fv \) (minit0 n \) ([], []) + else if is_constraint \ then + MAndRel (minit0 n \) (split_constraint \) + else (case \ of Formula.Neg \ \ + MAnd (fv \) (minit0 n \) False (fv \) (minit0 n \) ([], [])))" +| "minit0 n (Formula.Ands l) = (let (pos, neg) = partition safe_formula l in + let mpos = map (minit0 n) pos in + let mneg = map (minit0 n) (map remove_neg neg) in + let vpos = map fv pos in + let vneg = map fv neg in + MAnds vpos vneg (mpos @ mneg) (replicate (length l) []))" +| "minit0 n (Formula.Exists \) = MExists (minit0 (Suc n) \)" +| "minit0 n (Formula.Agg y \ b f \) = MAgg (fv \ \ {0.. b f (minit0 (b + n) \)" +| "minit0 n (Formula.Prev I \) = MPrev I (minit0 n \) True [] []" +| "minit0 n (Formula.Next I \) = MNext I (minit0 n \) True []" +| "minit0 n (Formula.Since \ I \) = (if safe_formula \ + then MSince (init_args I n (Formula.fv \) (Formula.fv \) True) (minit0 n \) (minit0 n \) ([], []) [] (init_msaux (init_args I n (Formula.fv \) (Formula.fv \) True)) + else (case \ of + Formula.Neg \ \ MSince (init_args I n (Formula.fv \) (Formula.fv \) False) (minit0 n \) (minit0 n \) ([], []) [] (init_msaux (init_args I n (Formula.fv \) (Formula.fv \) False)) + | _ \ undefined))" +| "minit0 n (Formula.Until \ I \) = (if safe_formula \ + then MUntil (init_args I n (Formula.fv \) (Formula.fv \) True) (minit0 n \) (minit0 n \) ([], []) [] (init_muaux (init_args I n (Formula.fv \) (Formula.fv \) True)) + else (case \ of + Formula.Neg \ \ MUntil (init_args I n (Formula.fv \) (Formula.fv \) False) (minit0 n \) (minit0 n \) ([], []) [] (init_muaux (init_args I n (Formula.fv \) (Formula.fv \) False)) + | _ \ undefined))" +| "minit0 n (Formula.MatchP I r) = + (let (mr, \s) = to_mregex r + in MMatchP I mr (sorted_list_of_set (RPDs mr)) (map (minit0 n) \s) (replicate (length \s) []) [] [])" +| "minit0 n (Formula.MatchF I r) = + (let (mr, \s) = to_mregex r + in MMatchF I mr (sorted_list_of_set (LPDs mr)) (map (minit0 n) \s) (replicate (length \s) []) [] [])" +| "minit0 n _ = undefined" + by pat_completeness auto +termination (in maux) + by (relation "measure (\(_, \). size \)") + (auto simp: less_Suc_eq_le size_list_estimation' size_remove_neg + dest!: to_mregex_ok[OF sym] atms_size) + +definition (in maux) minit :: "Formula.formula \ ('msaux, 'muaux) mstate" where + "minit \ = (let n = Formula.nfv \ in \mstate_i = 0, mstate_m = minit0 n \, mstate_n = n\)" + +fun mprev_next :: "\ \ event_data table list \ ts list \ event_data table list \ event_data table list \ ts list" where + "mprev_next I [] ts = ([], [], ts)" +| "mprev_next I xs [] = ([], xs, [])" +| "mprev_next I xs [t] = ([], xs, [t])" +| "mprev_next I (x # xs) (t # t' # ts) = (let (ys, zs) = mprev_next I xs (t' # ts) + in ((if mem (t' - t) I then x else empty_table) # ys, zs))" + +fun mbuf2_add :: "event_data table list \ event_data table list \ event_data mbuf2 \ event_data mbuf2" where + "mbuf2_add xs' ys' (xs, ys) = (xs @ xs', ys @ ys')" + +fun mbuf2_take :: "(event_data table \ event_data table \ 'b) \ event_data mbuf2 \ 'b list \ event_data mbuf2" where + "mbuf2_take f (x # xs, y # ys) = (let (zs, buf) = mbuf2_take f (xs, ys) in (f x y # zs, buf))" +| "mbuf2_take f (xs, ys) = ([], (xs, ys))" + +fun mbuf2t_take :: "(event_data table \ event_data table \ ts \ 'b \ 'b) \ 'b \ + event_data mbuf2 \ ts list \ 'b \ event_data mbuf2 \ ts list" where + "mbuf2t_take f z (x # xs, y # ys) (t # ts) = mbuf2t_take f (f x y t z) (xs, ys) ts" +| "mbuf2t_take f z (xs, ys) ts = (z, (xs, ys), ts)" + +lemma size_list_length_diff1: "xs \ [] \ [] \ set xs \ + size_list (\xs. length xs - Suc 0) xs < size_list length xs" +proof (induct xs) + case (Cons x xs) + then show ?case + by (cases xs) auto +qed simp + +fun mbufn_add :: "event_data table list list \ event_data mbufn \ event_data mbufn" where + "mbufn_add xs' xs = List.map2 (@) xs xs'" + +function mbufn_take :: "(event_data table list \ 'b \ 'b) \ 'b \ event_data mbufn \ 'b \ event_data mbufn" where + "mbufn_take f z buf = (if buf = [] \ [] \ set buf then (z, buf) + else mbufn_take f (f (map hd buf) z) (map tl buf))" + by pat_completeness auto +termination by (relation "measure (\(_, _, buf). size_list length buf)") + (auto simp: comp_def Suc_le_eq size_list_length_diff1) + +fun mbufnt_take :: "(event_data table list \ ts \ 'b \ 'b) \ + 'b \ event_data mbufn \ ts list \ 'b \ event_data mbufn \ ts list" where + "mbufnt_take f z buf ts = + (if [] \ set buf \ ts = [] then (z, buf, ts) + else mbufnt_take f (f (map hd buf) (hd ts) z) (map tl buf) (tl ts))" + +fun match :: "Formula.trm list \ event_data list \ (nat \ event_data) option" where + "match [] [] = Some Map.empty" +| "match (Formula.Const x # ts) (y # ys) = (if x = y then match ts ys else None)" +| "match (Formula.Var x # ts) (y # ys) = (case match ts ys of + None \ None + | Some f \ (case f x of + None \ Some (f(x \ y)) + | Some z \ if y = z then Some f else None))" +| "match _ _ = None" + +fun meval_trm :: "Formula.trm \ event_data tuple \ event_data" where + "meval_trm (Formula.Var x) v = the (v ! x)" +| "meval_trm (Formula.Const x) v = x" +| "meval_trm (Formula.Plus x y) v = meval_trm x v + meval_trm y v" +| "meval_trm (Formula.Minus x y) v = meval_trm x v - meval_trm y v" +| "meval_trm (Formula.UMinus x) v = - meval_trm x v" +| "meval_trm (Formula.Mult x y) v = meval_trm x v * meval_trm y v" +| "meval_trm (Formula.Div x y) v = meval_trm x v div meval_trm y v" +| "meval_trm (Formula.Mod x y) v = meval_trm x v mod meval_trm y v" +| "meval_trm (Formula.F2i x) v = EInt (integer_of_event_data (meval_trm x v))" +| "meval_trm (Formula.I2f x) v = EFloat (double_of_event_data (meval_trm x v))" + +definition eval_agg :: "nat \ bool \ nat \ Formula.agg_op \ nat \ Formula.trm \ + event_data table \ event_data table" where + "eval_agg n g0 y \ b f rel = (if g0 \ rel = empty_table + then singleton_table n y (eval_agg_op \ {}) + else (\k. + let group = Set.filter (\x. drop b x = k) rel; + M = (\y. (y, ecard (Set.filter (\x. meval_trm f x = y) group))) ` meval_trm f ` group + in k[y:=Some (eval_agg_op \ M)]) ` (drop b) ` rel)" + +definition (in maux) update_since :: "args \ event_data table \ event_data table \ ts \ + 'msaux \ event_data table \ 'msaux" where + "update_since args rel1 rel2 nt aux = + (let aux0 = join_msaux args rel1 (add_new_ts_msaux args nt aux); + aux' = add_new_table_msaux args rel2 aux0 + in (result_msaux args aux', aux'))" + +definition "lookup = Mapping.lookup_default empty_table" + +fun \_lax where + "\_lax guard \s (MSkip n) = (if n = 0 then guard else empty_table)" +| "\_lax guard \s (MTestPos i) = join guard True (\s ! i)" +| "\_lax guard \s (MTestNeg i) = join guard False (\s ! i)" +| "\_lax guard \s (MPlus r s) = \_lax guard \s r \ \_lax guard \s s" +| "\_lax guard \s (MTimes r s) = join (\_lax guard \s r) True (\_lax guard \s s)" +| "\_lax guard \s (MStar r) = guard" + +fun r\_strict where + "r\_strict n \s (MSkip m) = (if m = 0 then unit_table n else empty_table)" +| "r\_strict n \s (MTestPos i) = \s ! i" +| "r\_strict n \s (MTestNeg i) = (if \s ! i = empty_table then unit_table n else empty_table)" +| "r\_strict n \s (MPlus r s) = r\_strict n \s r \ r\_strict n \s s" +| "r\_strict n \s (MTimes r s) = \_lax (r\_strict n \s r) \s s" +| "r\_strict n \s (MStar r) = unit_table n" + +fun l\_strict where + "l\_strict n \s (MSkip m) = (if m = 0 then unit_table n else empty_table)" +| "l\_strict n \s (MTestPos i) = \s ! i" +| "l\_strict n \s (MTestNeg i) = (if \s ! i = empty_table then unit_table n else empty_table)" +| "l\_strict n \s (MPlus r s) = l\_strict n \s r \ l\_strict n \s s" +| "l\_strict n \s (MTimes r s) = \_lax (l\_strict n \s s) \s r" +| "l\_strict n \s (MStar r) = unit_table n" + +fun r\ :: "(mregex \ mregex) \ (mregex, 'a table) mapping \ 'a table list \ mregex \ 'a table" where + "r\ \ X \s (MSkip n) = (case n of 0 \ empty_table | Suc m \ lookup X (\ (MSkip m)))" +| "r\ \ X \s (MTestPos i) = empty_table" +| "r\ \ X \s (MTestNeg i) = empty_table" +| "r\ \ X \s (MPlus r s) = r\ \ X \s r \ r\ \ X \s s" +| "r\ \ X \s (MTimes r s) = r\ (\t. \ (MTimes r t)) X \s s \ \_lax (r\ \ X \s r) \s s" +| "r\ \ X \s (MStar r) = r\ (\t. \ (MTimes (MStar r) t)) X \s r" + +fun l\ :: "(mregex \ mregex) \ (mregex, 'a table) mapping \ 'a table list \ mregex \ 'a table" where + "l\ \ X \s (MSkip n) = (case n of 0 \ empty_table | Suc m \ lookup X (\ (MSkip m)))" +| "l\ \ X \s (MTestPos i) = empty_table" +| "l\ \ X \s (MTestNeg i) = empty_table" +| "l\ \ X \s (MPlus r s) = l\ \ X \s r \ l\ \ X \s s" +| "l\ \ X \s (MTimes r s) = l\ (\t. \ (MTimes t s)) X \s r \ \_lax (l\ \ X \s s) \s r" +| "l\ \ X \s (MStar r) = l\ (\t. \ (MTimes t (MStar r))) X \s r" + +lift_definition mrtabulate :: "mregex list \ (mregex \ 'b table) \ (mregex, 'b table) mapping" + is "\ks f. (map_of (List.map_filter (\k. let fk = f k in if fk = empty_table then None else Some (k, fk)) ks))" . + +lemma lookup_tabulate: + "distinct xs \ lookup (mrtabulate xs f) x = (if x \ set xs then f x else empty_table)" + unfolding lookup_default_def lookup_def + by transfer (auto simp: Let_def map_filter_def map_of_eq_None_iff o_def image_image dest!: map_of_SomeD + split: if_splits option.splits) + +definition update_matchP :: "nat \ \ \ mregex \ mregex list \ event_data table list \ ts \ + event_data mr\aux \ event_data table \ event_data mr\aux" where + "update_matchP n I mr mrs rels nt aux = + (let aux = (case [(t, mrtabulate mrs (\mr. + r\ id rel rels mr \ (if t = nt then r\_strict n rels mr else {}))). + (t, rel) \ aux, enat (nt - t) \ right I] + of [] \ [(nt, mrtabulate mrs (r\_strict n rels))] + | x # aux' \ (if fst x = nt then x # aux' + else (nt, mrtabulate mrs (r\_strict n rels)) # x # aux')) + in (foldr (\) [lookup rel mr. (t, rel) \ aux, left I \ nt - t] {}, aux))" + +definition update_matchF_base where + "update_matchF_base n I mr mrs rels nt = + (let X = mrtabulate mrs (l\_strict n rels) + in ([(nt, rels, if left I = 0 then lookup X mr else empty_table)], X))" + +definition update_matchF_step where + "update_matchF_step I mr mrs nt = (\(t, rels', rel) (aux', X). + (let Y = mrtabulate mrs (l\ id X rels') + in ((t, rels', if mem (nt - t) I then rel \ lookup Y mr else rel) # aux', Y)))" + +definition update_matchF :: "nat \ \ \ mregex \ mregex list \ event_data table list \ ts \ event_data ml\aux \ event_data ml\aux" where + "update_matchF n I mr mrs rels nt aux = + fst (foldr (update_matchF_step I mr mrs nt) aux (update_matchF_base n I mr mrs rels nt))" + +fun eval_matchF :: "\ \ mregex \ ts \ event_data ml\aux \ event_data table list \ event_data ml\aux" where + "eval_matchF I mr nt [] = ([], [])" +| "eval_matchF I mr nt ((t, rels, rel) # aux) = (if t + right I < nt then + (let (xs, aux) = eval_matchF I mr nt aux in (rel # xs, aux)) else ([], (t, rels, rel) # aux))" + +primrec map_split where + "map_split f [] = ([], [])" +| "map_split f (x # xs) = + (let (y, z) = f x; (ys, zs) = map_split f xs + in (y # ys, z # zs))" + +fun eval_assignment :: "nat \ Formula.trm \ event_data tuple \ event_data tuple" where + "eval_assignment (x, t) y = (y[x:=Some (meval_trm t y)])" + +fun eval_constraint0 :: "mconstraint \ event_data \ event_data \ bool" where + "eval_constraint0 MEq x y = (x = y)" +| "eval_constraint0 MLess x y = (x < y)" +| "eval_constraint0 MLessEq x y = (x \ y)" + +fun eval_constraint :: "Formula.trm \ bool \ mconstraint \ Formula.trm \ event_data tuple \ bool" where + "eval_constraint (t1, p, c, t2) x = (eval_constraint0 c (meval_trm t1 x) (meval_trm t2 x) = p)" + +primrec (in maux) meval :: "nat \ ts \ Formula.database \ ('msaux, 'muaux) mformula \ + event_data table list \ ('msaux, 'muaux) mformula" where + "meval n t db (MRel rel) = ([rel], MRel rel)" +| "meval n t db (MPred e ts) = (map (\X. (\f. Table.tabulate f 0 n) ` Option.these + (match ts ` X)) (case Mapping.lookup db e of None \ [{}] | Some xs \ xs), MPred e ts)" +| "meval n t db (MLet p m b \ \) = + (let (xs, \) = meval m t db \; (ys, \) = meval n t (Mapping.update p (map (image (drop b o map the)) xs) db) \ + in (ys, MLet p m b \ \))" +| "meval n t db (MAnd A_\ \ pos A_\ \ buf) = + (let (xs, \) = meval n t db \; (ys, \) = meval n t db \; + (zs, buf) = mbuf2_take (\r1 r2. bin_join n A_\ r1 pos A_\ r2) (mbuf2_add xs ys buf) + in (zs, MAnd A_\ \ pos A_\ \ buf))" +| "meval n t db (MAndAssign \ conf) = + (let (xs, \) = meval n t db \ in (map (\r. eval_assignment conf ` r) xs, MAndAssign \ conf))" +| "meval n t db (MAndRel \ conf) = + (let (xs, \) = meval n t db \ in (map (Set.filter (eval_constraint conf)) xs, MAndRel \ conf))" +| "meval n t db (MAnds A_pos A_neg L buf) = + (let R = map (meval n t db) L in + let buf = mbufn_add (map fst R) buf in + let (zs, buf) = mbufn_take (\xs zs. zs @ [mmulti_join n A_pos A_neg xs]) [] buf in + (zs, MAnds A_pos A_neg (map snd R) buf))" +| "meval n t db (MOr \ \ buf) = + (let (xs, \) = meval n t db \; (ys, \) = meval n t db \; + (zs, buf) = mbuf2_take (\r1 r2. r1 \ r2) (mbuf2_add xs ys buf) + in (zs, MOr \ \ buf))" +| "meval n t db (MNeg \) = + (let (xs, \) = meval n t db \ in (map (\r. (if r = empty_table then unit_table n else empty_table)) xs, MNeg \))" +| "meval n t db (MExists \) = + (let (xs, \) = meval (Suc n) t db \ in (map (\r. tl ` r) xs, MExists \))" +| "meval n t db (MAgg g0 y \ b f \) = + (let (xs, \) = meval (b + n) t db \ in (map (eval_agg n g0 y \ b f) xs, MAgg g0 y \ b f \))" +| "meval n t db (MPrev I \ first buf nts) = + (let (xs, \) = meval n t db \; + (zs, buf, nts) = mprev_next I (buf @ xs) (nts @ [t]) + in (if first then empty_table # zs else zs, MPrev I \ False buf nts))" +| "meval n t db (MNext I \ first nts) = + (let (xs, \) = meval n t db \; + (xs, first) = (case (xs, first) of (_ # xs, True) \ (xs, False) | a \ a); + (zs, _, nts) = mprev_next I xs (nts @ [t]) + in (zs, MNext I \ first nts))" +| "meval n t db (MSince args \ \ buf nts aux) = + (let (xs, \) = meval n t db \; (ys, \) = meval n t db \; + ((zs, aux), buf, nts) = mbuf2t_take (\r1 r2 t (zs, aux). + let (z, aux) = update_since args r1 r2 t aux + in (zs @ [z], aux)) ([], aux) (mbuf2_add xs ys buf) (nts @ [t]) + in (zs, MSince args \ \ buf nts aux))" +| "meval n t db (MUntil args \ \ buf nts aux) = + (let (xs, \) = meval n t db \; (ys, \) = meval n t db \; + (aux, buf, nts) = mbuf2t_take (add_new_muaux args) aux (mbuf2_add xs ys buf) (nts @ [t]); + (zs, aux) = eval_muaux args (case nts of [] \ t | nt # _ \ nt) aux + in (zs, MUntil args \ \ buf nts aux))" +| "meval n t db (MMatchP I mr mrs \s buf nts aux) = + (let (xss, \s) = map_split id (map (meval n t db) \s); + ((zs, aux), buf, nts) = mbufnt_take (\rels t (zs, aux). + let (z, aux) = update_matchP n I mr mrs rels t aux + in (zs @ [z], aux)) ([], aux) (mbufn_add xss buf) (nts @ [t]) + in (zs, MMatchP I mr mrs \s buf nts aux))" +| "meval n t db (MMatchF I mr mrs \s buf nts aux) = + (let (xss, \s) = map_split id (map (meval n t db) \s); + (aux, buf, nts) = mbufnt_take (update_matchF n I mr mrs) aux (mbufn_add xss buf) (nts @ [t]); + (zs, aux) = eval_matchF I mr (case nts of [] \ t | nt # _ \ nt) aux + in (zs, MMatchF I mr mrs \s buf nts aux))" + +definition (in maux) mstep :: "Formula.database \ ts \ ('msaux, 'muaux) mstate \ (nat \ event_data table) list \ ('msaux, 'muaux) mstate" where + "mstep tdb st = + (let (xs, m) = meval (mstate_n st) (snd tdb) (fst tdb) (mstate_m st) + in (List.enumerate (mstate_i st) xs, + \mstate_i = mstate_i st + length xs, mstate_m = m, mstate_n = mstate_n st\))" + +subsection \Verdict delay\ + +context fixes \ :: Formula.trace begin + +fun progress :: "(Formula.name \ nat) \ Formula.formula \ nat \ nat" where + "progress P (Formula.Pred e ts) j = (case P e of None \ j | Some k \ k)" +| "progress P (Formula.Let p b \ \) j = progress (P(p \ progress P \ j)) \ j" +| "progress P (Formula.Eq t1 t2) j = j" +| "progress P (Formula.Less t1 t2) j = j" +| "progress P (Formula.LessEq t1 t2) j = j" +| "progress P (Formula.Neg \) j = progress P \ j" +| "progress P (Formula.Or \ \) j = min (progress P \ j) (progress P \ j)" +| "progress P (Formula.And \ \) j = min (progress P \ j) (progress P \ j)" +| "progress P (Formula.Ands l) j = (if l = [] then j else Min (set (map (\\. progress P \ j) l)))" +| "progress P (Formula.Exists \) j = progress P \ j" +| "progress P (Formula.Agg y \ b f \) j = progress P \ j" +| "progress P (Formula.Prev I \) j = (if j = 0 then 0 else min (Suc (progress P \ j)) j)" +| "progress P (Formula.Next I \) j = progress P \ j - 1" +| "progress P (Formula.Since \ I \) j = min (progress P \ j) (progress P \ j)" +| "progress P (Formula.Until \ I \) j = + Inf {i. \k. k < j \ k \ min (progress P \ j) (progress P \ j) \ \ \ i + right I \ \ \ k}" +| "progress P (Formula.MatchP I r) j = min_regex_default (progress P) r j" +| "progress P (Formula.MatchF I r) j = + Inf {i. \k. k < j \ k \ min_regex_default (progress P) r j \ \ \ i + right I \ \ \ k}" + +definition "progress_regex P = min_regex_default (progress P)" + +declare progress.simps[simp del] +lemmas progress_simps[simp] = progress.simps[folded progress_regex_def[THEN fun_cong, THEN fun_cong]] + +end + +definition "pred_mapping Q = pred_fun (\_. True) (pred_option Q)" +definition "rel_mapping Q = rel_fun (=) (rel_option Q)" + +lemma pred_mapping_alt: "pred_mapping Q P = (\p \ dom P. Q (the (P p)))" + unfolding pred_mapping_def pred_fun_def option.pred_set dom_def + by (force split: option.splits) + +lemma rel_mapping_alt: "rel_mapping Q P P' = (dom P = dom P' \ (\p \ dom P. Q (the (P p)) (the (P' p))))" + unfolding rel_mapping_def rel_fun_def rel_option_iff dom_def + by (force split: option.splits) + +lemma rel_mapping_map_upd[simp]: "Q x y \ rel_mapping Q P P' \ rel_mapping Q (P(p \ x)) (P'(p \ y))" + by (auto simp: rel_mapping_alt) + +lemma pred_mapping_map_upd[simp]: "Q x \ pred_mapping Q P \ pred_mapping Q (P(p \ x))" + by (auto simp: pred_mapping_alt) + +lemma pred_mapping_empty[simp]: "pred_mapping Q Map.empty" + by (auto simp: pred_mapping_alt) + +lemma pred_mapping_mono: "pred_mapping Q P \ Q \ R \ pred_mapping R P" + by (auto simp: pred_mapping_alt) + +lemma pred_mapping_mono_strong: "pred_mapping Q P \ + (\p. p \ dom P \ Q (the (P p)) \ R (the (P p))) \ pred_mapping R P" + by (auto simp: pred_mapping_alt) + +lemma progress_mono_gen: "j \ j' \ rel_mapping (\) P P' \ progress \ P \ j \ progress \ P' \ j'" +proof (induction \ arbitrary: P P') + case (Pred e ts) + then show ?case + by (force simp: rel_mapping_alt dom_def split: option.splits) +next + case (Ands l) + then show ?case + by (auto simp: image_iff intro!: Min.coboundedI[THEN order_trans]) +next + case (Until \ I \) + from Until(1,2)[of P P'] Until.prems show ?case + by (cases "right I") + (auto dest: trans_le_add1[OF \_mono] intro!: cInf_superset_mono) +next + case (MatchF I r) + from MatchF(1)[of _ P P'] MatchF.prems show ?case + by (cases "right I"; cases "regex.atms r = {}") + (auto 0 3 simp: Min_le_iff progress_regex_def dest: trans_le_add1[OF \_mono] + intro!: cInf_superset_mono elim!: less_le_trans order_trans) +qed (force simp: Min_le_iff progress_regex_def split: option.splits)+ + +lemma rel_mapping_reflp: "reflp Q \ rel_mapping Q P P" + by (auto simp: rel_mapping_alt reflp_def) + +lemmas progress_mono = progress_mono_gen[OF _ rel_mapping_reflp[unfolded reflp_def], simplified] + +lemma progress_le_gen: "pred_mapping (\x. x \ j) P \ progress \ P \ j \ j" +proof (induction \ arbitrary: P) + case (Pred e ts) + then show ?case + by (auto simp: pred_mapping_alt dom_def split: option.splits) +next + case (Ands l) + then show ?case + by (auto simp: image_iff intro!: Min.coboundedI[where a="progress \ P (hd l) j", THEN order_trans]) +next + case (Until \ I \) + then show ?case + by (cases "right I") + (auto intro: trans_le_add1[OF \_mono] intro!: cInf_lower) +next + case (MatchF I r) + then show ?case + by (cases "right I") + (auto intro: trans_le_add1[OF \_mono] intro!: cInf_lower) +qed (force simp: Min_le_iff progress_regex_def split: option.splits)+ + +lemma progress_le: "progress \ Map.empty \ j \ j" + using progress_le_gen[of _ Map.empty] by auto + +lemma progress_0_gen[simp]: + "pred_mapping (\x. x = 0) P \ progress \ P \ 0 = 0" + using progress_le_gen[of 0 P] by auto + +lemma progress_0[simp]: + "progress \ Map.empty \ 0 = 0" + by (auto simp: pred_mapping_alt) + +definition max_mapping :: "('b \ 'a option) \ ('b \ 'a option) \ 'b \ ('a :: linorder) option" where + "max_mapping P P' x = (case (P x, P' x) of + (None, None) \ None + | (Some x, None) \ None + | (None, Some x) \ None + | (Some x, Some y) \ Some (max x y))" + +definition Max_mapping :: "('b \ 'a option) set \ 'b \ ('a :: linorder) option" where + "Max_mapping Ps x = (if (\P \ Ps. P x \ None) then Some (Max ((\P. the (P x)) ` Ps)) else None)" + +lemma dom_max_mapping[simp]: "dom (max_mapping P1 P2) = dom P1 \ dom P2" + unfolding max_mapping_def by (auto split: option.splits) + +lemma dom_Max_mapping[simp]: "dom (Max_mapping X) = (\P \ X. dom P)" + unfolding Max_mapping_def by (auto split: if_splits) + +lemma Max_mapping_coboundedI: + assumes "finite X" "\Q \ X. dom Q = dom P" "P \ X" + shows "rel_mapping (\) P (Max_mapping X)" + unfolding rel_mapping_alt +proof (intro conjI ballI) + from assms(3) have "X \ {}" by auto + then show "dom P = dom (Max_mapping X)" using assms(2) by auto +next + fix p + assume "p \ dom P" + with assms show "the (P p) \ the (Max_mapping X p)" + by (force simp add: Max_mapping_def intro!: Max.coboundedI imageI) +qed + +lemma rel_mapping_trans: "P OO Q \ R \ + rel_mapping P P1 P2 \ rel_mapping Q P2 P3 \ rel_mapping R P1 P3" + by (force simp: rel_mapping_alt dom_def set_eq_iff) + +abbreviation range_mapping :: "nat \ nat \ ('b \ nat option) \ bool" where + "range_mapping i j P \ pred_mapping (\x. i \ x \ x \ j) P" + +lemma range_mapping_relax: + "range_mapping i j P \ i' \ i \ j' \ j \ range_mapping i' j' P" + by (auto simp: pred_mapping_alt dom_def set_eq_iff max_mapping_def split: option.splits) + +lemma range_mapping_max_mapping[simp]: + "range_mapping i j1 P1 \ range_mapping i j2 P2 \ range_mapping i (max j1 j2) (max_mapping P1 P2)" + by (auto simp: pred_mapping_alt dom_def set_eq_iff max_mapping_def split: option.splits) + +lemma range_mapping_Max_mapping[simp]: + "finite X \ X \ {} \ \x\X. range_mapping i (j x) (P x) \ range_mapping i (Max (j ` X)) (Max_mapping (P ` X))" + by (force simp: pred_mapping_alt Max_mapping_def dom_def image_iff + intro!: Max_ge_iff[THEN iffD2] split: if_splits) + +lemma pred_mapping_le: + "pred_mapping ((\) i) P1 \ rel_mapping (\) P1 P2 \ pred_mapping ((\) (i :: nat)) P2" + by (force simp: rel_mapping_alt pred_mapping_alt dom_def set_eq_iff) + +lemma pred_mapping_le': + "pred_mapping ((\) j) P1 \ i \ j \ rel_mapping (\) P1 P2 \ pred_mapping ((\) (i :: nat)) P2" + by (force simp: rel_mapping_alt pred_mapping_alt dom_def set_eq_iff) + +lemma max_mapping_cobounded1: "dom P1 \ dom P2 \ rel_mapping (\) P1 (max_mapping P1 P2)" + unfolding max_mapping_def rel_mapping_alt by (auto simp: dom_def split: option.splits) + +lemma max_mapping_cobounded2: "dom P2 \ dom P1 \ rel_mapping (\) P2 (max_mapping P1 P2)" + unfolding max_mapping_def rel_mapping_alt by (auto simp: dom_def split: option.splits) + +lemma max_mapping_fun_upd2[simp]: + "max_mapping P1 (P2(p := y))(p \ x) = (max_mapping P1 P2)(p \ x)" + by (auto simp: max_mapping_def) + +lemma rel_mapping_max_mapping_fun_upd: "dom P2 \ dom P1 \ p \ dom P2 \ the (P2 p) \ y \ + rel_mapping (\) P2 (max_mapping P1 P2(p \ y))" + by (auto simp: rel_mapping_alt max_mapping_def split: option.splits) + +lemma progress_ge_gen: "Formula.future_bounded \ \ + \P j. dom P = S \ range_mapping i j P \ i \ progress \ P \ j" +proof (induction \ arbitrary: i S) + case (Pred e ts) + then show ?case + by (intro exI[of _ "\e. if e \ S then Some i else None"]) + (auto split: option.splits if_splits simp: rel_mapping_alt pred_mapping_alt dom_def) +next + case (Let p b \ \) + from Let.prems obtain P2 j2 where P2: "dom P2 = insert p S" "range_mapping i j2 P2" + "i \ progress \ P2 \ j2" + by (atomize_elim, intro Let(2)) (force simp: pred_mapping_alt rel_mapping_alt dom_def)+ + from Let.prems obtain P1 j1 where P1: "dom P1 = S" "range_mapping (the (P2 p)) j1 P1" + "the (P2 p) \ progress \ P1 \ j1" + by (atomize_elim, intro Let(1)) auto + let ?P12 = "max_mapping P1 P2" + from P1 P2 have le1: "progress \ P1 \ j1 \ progress \ (?P12(p := P1 p)) \ (max j1 j2)" + by (intro progress_mono_gen) (auto simp: rel_mapping_alt max_mapping_def) + from P1 P2 have le2: "progress \ P2 \ j2 \ progress \ (?P12(p \ progress \ P1 \ j1)) \ (max j1 j2)" + by (intro progress_mono_gen) (auto simp: rel_mapping_alt max_mapping_def) + show ?case + unfolding progress.simps + proof (intro exI[of _ "?P12(p := P1 p)"] exI[of _ "max j1 j2"] conjI) + show "dom (?P12(p := P1 p)) = S" + using P1 P2 by (auto simp: dom_def max_mapping_def) + next + show "range_mapping i (max j1 j2) (?P12(p := P1 p))" + using P1 P2 by (force simp add: pred_mapping_alt dom_def max_mapping_def split: option.splits) + next + have "i \ progress \ P2 \ j2" by fact + also have "... \ progress \ (?P12(p \ progress \ P1 \ j1)) \ (max j1 j2)" + using le2 by blast + also have "... \ progress \ (?P12(p := P1 p)(p\progress \ (?P12(p := P1 p)) \ (max j1 j2))) \ (max j1 j2)" + by (auto intro!: progress_mono_gen simp: le1 rel_mapping_alt) + finally show "i \ ..." . + qed +next + case (Eq _ _) + then show ?case + by (intro exI[of _ "\e. if e \ S then Some i else None"]) (auto split: if_splits simp: pred_mapping_alt) +next + case (Less _ _) + then show ?case + by (intro exI[of _ "\e. if e \ S then Some i else None"]) (auto split: if_splits simp: pred_mapping_alt) +next + case (LessEq _ _) + then show ?case + by (intro exI[of _ "\e. if e \ S then Some i else None"]) (auto split: if_splits simp: pred_mapping_alt) +next + case (Or \1 \2) + from Or(3) obtain P1 j1 where P1: "dom P1 = S" "range_mapping i j1 P1" "i \ progress \ P1 \1 j1" + using Or(1)[of S i] by auto + moreover + from Or(3) obtain P2 j2 where P2: "dom P2 = S" "range_mapping i j2 P2" "i \ progress \ P2 \2 j2" + using Or(2)[of S i] by auto + ultimately have "i \ progress \ (max_mapping P1 P2) (Formula.Or \1 \2) (max j1 j2)" + by (auto 0 3 elim!: order.trans[OF _ progress_mono_gen] intro: max_mapping_cobounded1 max_mapping_cobounded2) + with P1 P2 show ?case by (intro exI[of _ "max_mapping P1 P2"] exI[of _ "max j1 j2"]) auto +next + case (And \1 \2) + from And(3) obtain P1 j1 where P1: "dom P1 = S" "range_mapping i j1 P1" "i \ progress \ P1 \1 j1" + using And(1)[of S i] by auto + moreover + from And(3) obtain P2 j2 where P2: "dom P2 = S" "range_mapping i j2 P2" "i \ progress \ P2 \2 j2" + using And(2)[of S i] by auto + ultimately have "i \ progress \ (max_mapping P1 P2) (Formula.And \1 \2) (max j1 j2)" + by (auto 0 3 elim!: order.trans[OF _ progress_mono_gen] intro: max_mapping_cobounded1 max_mapping_cobounded2) + with P1 P2 show ?case by (intro exI[of _ "max_mapping P1 P2"] exI[of _ "max j1 j2"]) auto +next + case (Ands l) + show ?case proof (cases "l = []") + case True + then show ?thesis + by (intro exI[of _ "\e. if e \ S then Some i else None"]) + (auto split: if_splits simp: pred_mapping_alt) + next + case False + then obtain \ where "\ \ set l" by (cases l) auto + from Ands.prems have "\\\set l. Formula.future_bounded \" + by (simp add: list.pred_set) + { fix \ + assume "\ \ set l" + with Ands.prems obtain P j where "dom P = S" "range_mapping i j P" "i \ progress \ P \ j" + by (atomize_elim, intro Ands(1)[of \ S i]) (auto simp: list.pred_set) + then have "\Pj. dom (fst Pj) = S \ range_mapping i (snd Pj) (fst Pj) \ i \ progress \ (fst Pj) \ (snd Pj)" + (is "\Pj. ?P Pj") + by (intro exI[of _ "(P, j)"]) auto + } + then have "\\\set l. \Pj. dom (fst Pj) = S \ range_mapping i (snd Pj) (fst Pj) \ i \ progress \ (fst Pj) \ (snd Pj)" + (is "\\\set l. \Pj. ?P Pj \") + by blast + with Ands(1) Ands.prems False have "\Pjf. \\\set l. ?P (Pjf \) \" + by (auto simp: Ball_def intro: choice) + then obtain Pjf where Pjf: "\\\set l. ?P (Pjf \) \" .. + define Pf where "Pf = fst o Pjf" + define jf where "jf = snd o Pjf" + have *: "dom (Pf \) = S" "range_mapping i (jf \) (Pf \)" "i \ progress \ (Pf \) \ (jf \)" + if "\ \ set l" for \ + using Pjf[THEN bspec, OF that] unfolding Pf_def jf_def by auto + with False show ?thesis + unfolding progress.simps eq_False[THEN iffD2, OF False] if_False + by ((subst Min_ge_iff; simp add: False), + intro exI[where x="MAX \\set l. jf \"] exI[where x="Max_mapping (Pf ` set l)"] + conjI ballI order.trans[OF *(3) progress_mono_gen] Max_mapping_coboundedI) + (auto simp: False *[OF \\ \ set l\] \\ \ set l\) + qed +next + case (Exists \) + then show ?case by simp +next + case (Prev I \) + then obtain P j where "dom P = S" "range_mapping i j P" "i \ progress \ P \ j" + by (atomize_elim, intro Prev(1)) (auto simp: pred_mapping_alt dom_def) + with Prev(2) have + "dom P = S \ range_mapping i (max i j) P \ i \ progress \ P (formula.Prev I \) (max i j)" + by (auto simp: le_Suc_eq max_def pred_mapping_alt split: if_splits + elim: order.trans[OF _ progress_mono]) + then show ?case by blast +next + case (Next I \) + then obtain P j where "dom P = S" "range_mapping (Suc i) j P" "Suc i \ progress \ P \ j" + by (atomize_elim, intro Next(1)) (auto simp: pred_mapping_alt dom_def) + then show ?case + by (intro exI[of _ P] exI[of _ j]) (auto 0 3 simp: pred_mapping_alt dom_def) +next + case (Since \1 I \2) + from Since(3) obtain P1 j1 where P1: "dom P1 = S" "range_mapping i j1 P1" "i \ progress \ P1 \1 j1" + using Since(1)[of S i] by auto + moreover + from Since(3) obtain P2 j2 where P2: "dom P2 = S" "range_mapping i j2 P2" "i \ progress \ P2 \2 j2" + using Since(2)[of S i] by auto + ultimately have "i \ progress \ (max_mapping P1 P2) (Formula.Since \1 I \2) (max j1 j2)" + by (auto elim!: order.trans[OF _ progress_mono_gen] simp: max_mapping_cobounded1 max_mapping_cobounded2) + with P1 P2 show ?case by (intro exI[of _ "max_mapping P1 P2"] exI[of _ "max j1 j2"]) + (auto elim!: pred_mapping_le intro: max_mapping_cobounded1) +next + case (Until \1 I \2) + from Until.prems obtain b where [simp]: "right I = enat b" + by (cases "right I") (auto) + obtain i' where "i < i'" and "\ \ i + b + 1 \ \ \ i'" + using ex_le_\[where x="\ \ i + b + 1"] by (auto simp add: less_eq_Suc_le) + then have 1: "\ \ i + b < \ \ i'" by simp + from Until.prems obtain P1 j1 where P1: "dom P1 = S" "range_mapping (Suc i') j1 P1" "Suc i' \ progress \ P1 \1 j1" + by (atomize_elim, intro Until(1)) (auto simp: pred_mapping_alt dom_def) + from Until.prems obtain P2 j2 where P2: "dom P2 = S" "range_mapping (Suc i') j2 P2" "Suc i' \ progress \ P2 \2 j2" + by (atomize_elim, intro Until(2)) (auto simp: pred_mapping_alt dom_def) + let ?P12 = "max_mapping P1 P2" + have "i \ progress \ ?P12 (Formula.Until \1 I \2) (max j1 j2)" + unfolding progress.simps + proof (intro cInf_greatest, goal_cases nonempty greatest) + case nonempty + then show ?case + by (auto simp: trans_le_add1[OF \_mono] intro!: exI[of _ "max j1 j2"]) + next + case (greatest x) + from P1(2,3) have "i' < j1" + by (auto simp: less_eq_Suc_le intro!: progress_le_gen elim!: order.trans pred_mapping_mono_strong) + then have "i' < max j1 j2" by simp + have "progress \ P1 \1 j1 \ progress \ ?P12 \1 (max j1 j2)" + using P1(1) P2(1) by (auto intro!: progress_mono_gen max_mapping_cobounded1) + moreover have "progress \ P2 \2 j2 \ progress \ ?P12 \2 (max j1 j2)" + using P1(1) P2(1) by (auto intro!: progress_mono_gen max_mapping_cobounded2) + ultimately have "i' \ min (progress \ ?P12 \1 (max j1 j2)) (progress \ ?P12 \2 (max j1 j2))" + using P1(3) P2(3) by simp + with greatest \i' < max j1 j2\ have "\ \ i' \ \ \ x + b" + by simp + with 1 have "\ \ i < \ \ x" by simp + then show ?case by (auto dest!: less_\D) + qed + with P1 P2 \i < i'\ show ?case + by (intro exI[of _ "max_mapping P1 P2"] exI[of _ "max j1 j2"]) (auto simp: range_mapping_relax) +next + case (MatchP I r) + then show ?case + proof (cases "regex.atms r = {}") + case True + with MatchP.prems show ?thesis + unfolding progress.simps + by (intro exI[of _ "\e. if e \ S then Some i else None"] exI[of _ i]) + (auto split: if_splits simp: pred_mapping_alt regex.pred_set) + next + case False + define pick where "pick = (\\. SOME Pj. dom (fst Pj) = S \ range_mapping i (snd Pj) (fst Pj) \ + i \ progress \ (fst Pj) \ (snd Pj))" + let ?pickP = "fst o pick" let ?pickj = "snd o pick" + from MatchP have pick: "\ \ regex.atms r \ dom (?pickP \) = S \ + range_mapping i (?pickj \) (?pickP \) \ i \ progress \ (?pickP \) \ (?pickj \)" for \ + unfolding pick_def o_def future_bounded.simps regex.pred_set + by (intro someI_ex[where P = "\Pj. dom (fst Pj) = S \ range_mapping i (snd Pj) (fst Pj) \ + i \ progress \ (fst Pj) \ (snd Pj)"]) auto + with False show ?thesis + unfolding progress.simps + by (intro exI[of _ "Max_mapping (?pickP ` regex.atms r)"] exI[of _ "Max (?pickj ` regex.atms r)"]) + (auto simp: Max_mapping_coboundedI + order_trans[OF pick[THEN conjunct2, THEN conjunct2] progress_mono_gen]) + qed +next + case (MatchF I r) + from MatchF.prems obtain b where [simp]: "right I = enat b" + by auto + obtain i' where i': "i < i'" "\ \ i + b + 1 \ \ \ i'" + using ex_le_\[where x="\ \ i + b + 1"] by (auto simp add: less_eq_Suc_le) + then have 1: "\ \ i + b < \ \ i'" by simp + have ix: "i \ x" if "\ \ i' \ b + \ \ x" "b + \ \ i < \ \ i'" for x + using less_\D[of \ i] that less_le_trans by fastforce + show ?case + proof (cases "regex.atms r = {}") + case True + with MatchF.prems i' ix show ?thesis + unfolding progress.simps + by (intro exI[of _ "\e. if e \ S then Some (Suc i') else None"] exI[of _ "Suc i'"]) + (auto split: if_splits simp: pred_mapping_alt regex.pred_set add.commute less_Suc_eq + intro!: cInf_greatest dest!: spec[of _ i'] less_imp_le[THEN \_mono, of _ i' \]) + next + case False + then obtain \ where \: "\ \ regex.atms r" by auto + define pick where "pick = (\\. SOME Pj. dom (fst Pj) = S \ range_mapping (Suc i') (snd Pj) (fst Pj) \ + Suc i' \ progress \ (fst Pj) \ (snd Pj))" + define pickP where "pickP = fst o pick" define pickj where "pickj = snd o pick" + from MatchF have pick: "\ \ regex.atms r \ dom (pickP \) = S \ + range_mapping (Suc i') (pickj \) (pickP \) \ Suc i' \ progress \ (pickP \) \ (pickj \)" for \ + unfolding pick_def o_def future_bounded.simps regex.pred_set pickj_def pickP_def + by (intro someI_ex[where P = "\Pj. dom (fst Pj) = S \ range_mapping (Suc i') (snd Pj) (fst Pj) \ + Suc i' \ progress \ (fst Pj) \ (snd Pj)"]) auto + let ?P = "Max_mapping (pickP ` regex.atms r)" let ?j = "Max (pickj ` regex.atms r)" + from pick[OF \] False \ have "Suc i' \ ?j" + by (intro order_trans[OF pick[THEN conjunct2, THEN conjunct2], OF \] order_trans[OF progress_le_gen]) + (auto simp: Max_ge_iff dest: range_mapping_relax[of _ _ _ 0, OF _ _ order_refl, simplified]) + moreover + note i' 1 ix + moreover + from MatchF.prems have "Regex.pred_regex Formula.future_bounded r" + by auto + ultimately show ?thesis using \_mono[of _ ?j \] less_\D[of \ i] pick False + by (intro exI[of _ "?j"] exI[of _ "?P"]) + (auto 0 3 intro!: cInf_greatest + order_trans[OF le_SucI[OF order_refl] order_trans[OF pick[THEN conjunct2, THEN conjunct2] progress_mono_gen]] + range_mapping_Max_mapping[OF _ _ ballI[OF range_mapping_relax[of "Suc i'" _ _ i, OF _ _ order_refl]]] + simp: ac_simps Suc_le_eq trans_le_add2 Max_mapping_coboundedI progress_regex_def + dest: spec[of _ "i'"] spec[of _ ?j]) + qed +qed (auto split: option.splits) + +lemma progress_ge: "Formula.future_bounded \ \ \j. i \ progress \ Map.empty \ j" + using progress_ge_gen[of \ "{}" i \] + by auto + +lemma cInf_restrict_nat: + fixes x :: nat + assumes "x \ A" + shows "Inf A = Inf {y \ A. y \ x}" + using assms by (auto intro!: antisym intro: cInf_greatest cInf_lower Inf_nat_def1) + +lemma progress_time_conv: + assumes "\i \ i = \ \' i" + shows "progress \ P \ j = progress \' P \ j" + using assms proof (induction \ arbitrary: P) + case (Until \1 I \2) + have *: "i \ j - 1 \ i < j" if "j \ 0" for i + using that by auto + with Until show ?case + proof (cases "right I") + case (enat b) + then show ?thesis + proof (cases "j") + case (Suc n) + with enat * Until show ?thesis + using \_mono[THEN trans_le_add1] + by (auto 8 0 + intro!: box_equals[OF arg_cong[where f=Inf] + cInf_restrict_nat[symmetric, where x=n] cInf_restrict_nat[symmetric, where x=n]]) + qed simp + qed simp +next + case (MatchF I r) + have *: "i \ j - 1 \ i < j" if "j \ 0" for i + using that by auto + with MatchF show ?case using \_mono[THEN trans_le_add1] + by (cases "right I"; cases j) + ((auto 6 0 simp: progress_le_gen progress_regex_def intro!: box_equals[OF arg_cong[where f=Inf] + cInf_restrict_nat[symmetric, where x="j-1"] cInf_restrict_nat[symmetric, where x="j-1"]]) [])+ +qed (auto simp: progress_regex_def) + +lemma Inf_UNIV_nat: "(Inf UNIV :: nat) = 0" + by (simp add: cInf_eq_minimum) + +lemma progress_prefix_conv: + assumes "prefix_of \ \" and "prefix_of \ \'" + shows "progress \ P \ (plen \) = progress \' P \ (plen \)" + using assms by (auto intro: progress_time_conv \_prefix_conv) + +lemma bounded_rtranclp_mono: + fixes n :: "'x :: linorder" + assumes "\i j. R i j \ j < n \ S i j" "\i j. R i j \ i \ j" + shows "rtranclp R i j \ j < n \ rtranclp S i j" +proof (induct rule: rtranclp_induct) + case (step y z) + then show ?case + using assms(1,2)[of y z] + by (auto elim!: rtrancl_into_rtrancl[to_pred, rotated]) +qed auto + +lemma sat_prefix_conv_gen: + assumes "prefix_of \ \" and "prefix_of \ \'" + shows "i < progress \ P \ (plen \) \ dom V = dom V' \ dom P = dom V \ + pred_mapping (\x. x \ plen \) P \ + (\p i \. p \ dom V \ i < the (P p) \ the (V p) i = the (V' p) i) \ + Formula.sat \ V v i \ \ Formula.sat \' V' v i \" +proof (induction \ arbitrary: P V V' v i) + case (Pred e ts) + from Pred.prems(1,4) have "i < plen \" + by (blast intro!: order.strict_trans2 progress_le_gen) + show ?case proof (cases "V e") + case None + then have "V' e = None" using \dom V = dom V'\ by auto + with None \_prefix_conv[OF assms(1,2) \i < plen \\] show ?thesis by simp + next + case (Some a) + obtain a' where "V' e = Some a'" using Some \dom V = dom V'\ by auto + then have "i < the (P e)" + using Pred.prems(1-3) by (auto split: option.splits) + then have "the (V e) i = the (V' e) i" + using Some by (intro Pred.prems(5)) (simp_all add: domI) + with Some \V' e = Some a'\ show ?thesis by simp + qed +next + case (Let p b \ \) + let ?V = "\V \. (V(p \ + \i. {v. length v = Formula.nfv \ - b \ + (\zs. length zs = b \ + Formula.sat \ V (zs @ v) i \)}))" + show ?case unfolding sat.simps proof (rule Let.IH(2)) + from Let.prems show "i < progress \ (P(p \ progress \ P \ (plen \))) \ (plen \)" + by simp + from Let.prems show "dom (?V V \) = dom (?V V' \')" + by simp + from Let.prems show "dom (P(p \ progress \ P \ (plen \))) = dom (?V V \)" + by simp + from Let.prems show "pred_mapping (\x. x \ plen \) (P(p \ progress \ P \ (plen \)))" + by (auto intro!: pred_mapping_map_upd elim!: progress_le_gen) + next + fix p' i \' + assume 1: "p' \ dom (?V V \)" and 2: "i < the ((P(p \ progress \ P \ (plen \))) p')" + show "the (?V V \ p') i = the (?V V' \' p') i" proof (cases "p' = p") + case True + with Let 2 show ?thesis by auto + next + case False + with 1 2 show ?thesis by (auto intro!: Let.prems(5)) + qed + qed +next + case (Eq t1 t2) + show ?case by simp +next + case (Neg \) + then show ?case by simp +next + case (Or \1 \2) + then show ?case by auto +next + case (Ands l) + from Ands.prems have "\\\set l. i < progress \ P \ (plen \)" + by (cases l) simp_all + with Ands show ?case unfolding sat_Ands by blast +next + case (Exists \) + then show ?case by simp +next + case (Prev I \) + with \_prefix_conv[OF assms(1,2)] show ?case + by (cases i) (auto split: if_splits) +next + case (Next I \) + then have "Suc i < plen \" + by (auto intro: order.strict_trans2[OF _ progress_le_gen[of _ P \ \]]) + with Next.prems \_prefix_conv[OF assms(1,2)] show ?case + unfolding sat.simps + by (intro conj_cong Next) auto +next + case (Since \1 I \2) + then have "i < plen \" + by (auto elim!: order.strict_trans2[OF _ progress_le_gen]) + with Since.prems \_prefix_conv[OF assms(1,2)] show ?case + unfolding sat.simps + by (intro conj_cong ex_cong ball_cong Since) auto +next + case (Until \1 I \2) + from Until.prems obtain b where right[simp]: "right I = enat b" + by (cases "right I") (auto simp add: Inf_UNIV_nat) + from Until.prems obtain j where "\ \ i + b + 1 \ \ \ j" + "j \ progress \ P \1 (plen \)" "j \ progress \ P \2 (plen \)" + by atomize_elim (auto 0 4 simp add: less_eq_Suc_le not_le intro: Suc_leI dest: spec[of _ "i"] + dest!: le_cInf_iff[THEN iffD1, rotated -1]) + then have 1: "k < progress \ P \1 (plen \)" and 2: "k < progress \ P \2 (plen \)" + if "\ \ k \ \ \ i + b" for k + using that by (fastforce elim!: order.strict_trans2[rotated] intro: less_\D[of \])+ + have 3: "k < plen \" if "\ \ k \ \ \ i + b" for k + using 1[OF that] Until(6) by (auto simp only: less_eq_Suc_le order.trans[OF _ progress_le_gen]) + + from Until.prems have "i < progress \' P (Formula.Until \1 I \2) (plen \)" + unfolding progress_prefix_conv[OF assms(1,2)] by blast + then obtain j where "\ \' i + b + 1 \ \ \' j" + "j \ progress \' P \1 (plen \)" "j \ progress \' P \2 (plen \)" + by atomize_elim (auto 0 4 simp add: less_eq_Suc_le not_le intro: Suc_leI dest: spec[of _ "i"] + dest!: le_cInf_iff[THEN iffD1, rotated -1]) + then have 11: "k < progress \ P \1 (plen \)" and 21: "k < progress \ P \2 (plen \)" + if "\ \' k \ \ \' i + b" for k + unfolding progress_prefix_conv[OF assms(1,2)] + using that by (fastforce elim!: order.strict_trans2[rotated] intro: less_\D[of \'])+ + have 31: "k < plen \" if "\ \' k \ \ \' i + b" for k + using 11[OF that] Until(6) by (auto simp only: less_eq_Suc_le order.trans[OF _ progress_le_gen]) + show ?case unfolding sat.simps + proof ((intro ex_cong iffI; elim conjE), goal_cases LR RL) + case (LR j) + with Until(1)[OF 1] Until(2)[OF 2] \_prefix_conv[OF assms(1,2) 3] Until.prems show ?case + by (auto 0 4 simp: le_diff_conv add.commute dest: less_imp_le order.trans[OF \_mono, rotated]) + next + case (RL j) + with Until(1)[OF 11] Until(2)[OF 21] \_prefix_conv[OF assms(1,2) 31] Until.prems show ?case + by (auto 0 4 simp: le_diff_conv add.commute dest: less_imp_le order.trans[OF \_mono, rotated]) + qed +next + case (MatchP I r) + then have "i < plen \" + by (force simp: pred_mapping_alt elim!: order.strict_trans2[OF _ progress_le_gen]) + with MatchP.prems \_prefix_conv[OF assms(1,2)] show ?case + unfolding sat.simps + by (intro ex_cong conj_cong match_cong_strong MatchP) (auto simp: progress_regex_def split: if_splits) +next + case (MatchF I r) + from MatchF.prems obtain b where right[simp]: "right I = enat b" + by (cases "right I") (auto simp add: Inf_UNIV_nat) + show ?case + proof (cases "regex.atms r = {}") + case True + from MatchF.prems(1) obtain j where "\ \ i + b + 1 \ \ \ j" "j \ plen \" + by atomize_elim (auto 0 4 simp add: less_eq_Suc_le not_le dest!: le_cInf_iff[THEN iffD1, rotated -1]) + then have 1: "k < plen \" if "\ \ k \ \ \ i + b" for k + by (meson \_mono discrete not_le order.strict_trans2 that) + from MatchF.prems have "i < progress \' P (Formula.MatchF I r) (plen \)" + unfolding progress_prefix_conv[OF assms(1,2)] by blast + then obtain j where "\ \' i + b + 1 \ \ \' j" "j \ plen \" + by atomize_elim (auto 0 4 simp add: less_eq_Suc_le not_le dest!: le_cInf_iff[THEN iffD1, rotated -1]) + then have 2: "k < plen \" if "\ \' k \ \ \' i + b" for k + by (meson \_mono discrete not_le order.strict_trans2 that) + from MatchF.prems(1,4) True show ?thesis + unfolding sat.simps conj_commute[of "left I \ _" "_ \ _"] + proof (intro ex_cong conj_cong match_cong_strong, goal_cases left right sat) + case (left j) + then show ?case + by (intro iffI) + ((subst (1 2) \_prefix_conv[OF assms(1,2) 1, symmetric]; auto elim: order.trans[OF \_mono, rotated]), + (subst (1 2) \_prefix_conv[OF assms(1,2) 2]; auto elim: order.trans[OF \_mono, rotated])) + next + case (right j) + then show ?case + by (intro iffI) + ((subst (1 2) \_prefix_conv[OF assms(1,2) 2, symmetric]; auto elim: order.trans[OF \_mono, rotated]), + (subst (1 2) \_prefix_conv[OF assms(1,2) 2]; auto elim: order.trans[OF \_mono, rotated])) + qed auto + next + case False + from MatchF.prems(1) False obtain j where "\ \ i + b + 1 \ \ \ j" "(\x\regex.atms r. j \ progress \ P x (plen \))" + by atomize_elim (auto 0 6 simp add: less_eq_Suc_le not_le progress_regex_def + dest!: le_cInf_iff[THEN iffD1, rotated -1]) + then have 1: "\ \ regex.atms r \ k < progress \ P \ (plen \)" if "\ \ k \ \ \ i + b" for k \ + using that + by (fastforce elim!: order.strict_trans2[rotated] intro: less_\D[of \]) + then have 2: "k < plen \" if "\ \ k \ \ \ i + b" "regex.atms r \ {}" for k + using that + by (fastforce intro: order.strict_trans2[OF _ progress_le_gen[OF MatchF(5), of \], of k]) + + from MatchF.prems have "i < progress \' P (Formula.MatchF I r) (plen \)" + unfolding progress_prefix_conv[OF assms(1,2)] by blast + with False obtain j where "\ \' i + b + 1 \ \ \' j" "(\x\regex.atms r. j \ progress \' P x (plen \))" + by atomize_elim (auto 0 6 simp add: less_eq_Suc_le not_le progress_regex_def + dest!: le_cInf_iff[THEN iffD1, rotated -1]) + then have 11: "\ \ regex.atms r \ k < progress \ P \ (plen \)" if "\ \' k \ \ \' i + b" for k \ + using that using progress_prefix_conv[OF assms(1,2)] + by (auto 0 3 elim!: order.strict_trans2[rotated] intro: less_\D[of \']) + have 21: "k < plen \" if "\ \' k \ \ \' i + b" for k + using 11[OF that(1)] False by (fastforce intro: order.strict_trans2[OF _ progress_le_gen[OF MatchF(5), of \], of k]) + show ?thesis unfolding sat.simps conj_commute[of "left I \ _" "_ \ _"] + proof ((intro ex_cong conj_cong match_cong_strong MatchF(1)[OF _ _ MatchF(3-6)]; assumption?), goal_cases right left progress) + case (right j) + with False show ?case + by (intro iffI) + ((subst (1 2) \_prefix_conv[OF assms(1,2) 2, symmetric]; auto elim: order.trans[OF \_mono, rotated]), + (subst (1 2) \_prefix_conv[OF assms(1,2) 21]; auto elim: order.trans[OF \_mono, rotated])) + next + case (left j) + with False show ?case unfolding right enat_ord_code le_diff_conv add.commute[of b] + by (intro iffI) + ((subst (1 2) \_prefix_conv[OF assms(1,2) 21, symmetric]; auto elim: order.trans[OF \_mono, rotated]), + (subst (1 2) \_prefix_conv[OF assms(1,2) 21]; auto elim: order.trans[OF \_mono, rotated])) + next + case (progress j k z) + with False show ?case unfolding right enat_ord_code le_diff_conv add.commute[of b] + by (elim 1[rotated]) + (subst (1 2) \_prefix_conv[OF assms(1,2) 21]; auto elim!: order.trans[OF \_mono, rotated]) + qed + qed +qed auto + +lemma sat_prefix_conv: + assumes "prefix_of \ \" and "prefix_of \ \'" + shows "i < progress \ Map.empty \ (plen \) \ + Formula.sat \ Map.empty v i \ \ Formula.sat \' Map.empty v i \" + by (erule sat_prefix_conv_gen[OF assms]) auto + +lemma progress_remove_neg[simp]: "progress \ P (remove_neg \) j = progress \ P \ j" + by (cases \) simp_all + +lemma safe_progress_get_and: "safe_formula \ \ + Min ((\\. progress \ P \ j) ` set (get_and_list \)) = progress \ P \ j" + by (induction \ rule: get_and_list.induct) auto + +lemma progress_convert_multiway: "safe_formula \ \ progress \ P (convert_multiway \) j = progress \ P \ j" +proof (induction \ arbitrary: P rule: safe_formula_induct) + case (And_safe \ \) + let ?c = "convert_multiway (Formula.And \ \)" + let ?c\ = "convert_multiway \" + let ?c\ = "convert_multiway \" + have c_eq: "?c = Formula.Ands (get_and_list ?c\ @ get_and_list ?c\)" + using And_safe by simp + from \safe_formula \\ have "safe_formula ?c\" by (rule safe_convert_multiway) + moreover from \safe_formula \\ have "safe_formula ?c\" by (rule safe_convert_multiway) + ultimately show ?case + unfolding c_eq + using And_safe.IH + by (auto simp: get_and_nonempty Min.union safe_progress_get_and) +next + case (And_Not \ \) + let ?c = "convert_multiway (Formula.And \ (Formula.Neg \))" + let ?c\ = "convert_multiway \" + let ?c\ = "convert_multiway \" + have c_eq: "?c = Formula.Ands (Formula.Neg ?c\ # get_and_list ?c\)" + using And_Not by simp + from \safe_formula \\ have "safe_formula ?c\" by (rule safe_convert_multiway) + moreover from \safe_formula \\ have "safe_formula ?c\" by (rule safe_convert_multiway) + ultimately show ?case + unfolding c_eq + using And_Not.IH + by (auto simp: get_and_nonempty Min.union safe_progress_get_and) +next + case (MatchP I r) + from MatchP show ?case + unfolding progress.simps regex.map convert_multiway.simps regex.set_map image_image + by (intro if_cong arg_cong[of _ _ Min] image_cong) + (auto 0 4 simp: atms_def elim!: disjE_Not2 dest: safe_regex_safe_formula) +next + case (MatchF I r) + from MatchF show ?case + unfolding progress.simps regex.map convert_multiway.simps regex.set_map image_image + by (intro if_cong arg_cong[of _ _ Min] arg_cong[of _ _ Inf] arg_cong[of _ _ "(\) _"] + image_cong Collect_cong all_cong1 imp_cong conj_cong image_cong) + (auto 0 4 simp: atms_def elim!: disjE_Not2 dest: safe_regex_safe_formula) +qed auto + + +interpretation verimon: monitor_timed_progress Formula.future_bounded "\\. progress \ Map.empty" + by (unfold_locales, (fact progress_mono progress_le progress_time_conv sat_prefix_conv | + simp add: mmonitorable_def progress_ge)+) + +abbreviation "mverdicts \ verimon.verdicts" + + +subsection \Correctness\ + +subsubsection \Invariants\ + +definition wf_mbuf2 :: "nat \ nat \ nat \ (nat \ event_data table \ bool) \ (nat \ event_data table \ bool) \ + event_data mbuf2 \ bool" where + "wf_mbuf2 i ja jb P Q buf \ i \ ja \ i \ jb \ (case buf of (xs, ys) \ + list_all2 P [i.. list_all2 Q [i.. 'b \ 'c \ bool) \ 'a list \ 'b list \ 'c list \ bool" for P :: "('a \ 'b \ 'c \ bool)" where + "list_all3 P [] [] []" +| "P a1 a2 a3 \ list_all3 P q1 q2 q3 \ list_all3 P (a1 # q1) (a2 # q2) (a3 # q3)" + +lemma list_all3_list_all2D: "list_all3 P xs ys zs \ + (length xs = length ys \ list_all2 (case_prod P) (zip xs ys) zs)" + by (induct xs ys zs rule: list_all3.induct) auto + +lemma list_all2_list_all3I: "length xs = length ys \ list_all2 (case_prod P) (zip xs ys) zs \ + list_all3 P xs ys zs" + by (induct xs ys arbitrary: zs rule: list_induct2) + (auto simp: list_all2_Cons1 intro: list_all3.intros) + +lemma list_all3_list_all2_eq: "list_all3 P xs ys zs \ + (length xs = length ys \ list_all2 (case_prod P) (zip xs ys) zs)" + using list_all2_list_all3I list_all3_list_all2D by blast + +lemma list_all3_mapD: "list_all3 P (map f xs) (map g ys) (map h zs) \ + list_all3 (\x y z. P (f x) (g y) (h z)) xs ys zs" + by (induct "map f xs" "map g ys" "map h zs" arbitrary: xs ys zs rule: list_all3.induct) + (auto intro: list_all3.intros) + +lemma list_all3_mapI: "list_all3 (\x y z. P (f x) (g y) (h z)) xs ys zs \ + list_all3 P (map f xs) (map g ys) (map h zs)" + by (induct xs ys zs rule: list_all3.induct) + (auto intro: list_all3.intros) + +lemma list_all3_map_iff: "list_all3 P (map f xs) (map g ys) (map h zs) \ + list_all3 (\x y z. P (f x) (g y) (h z)) xs ys zs" + using list_all3_mapD list_all3_mapI by blast + +lemmas list_all3_map = + list_all3_map_iff[where g=id and h=id, unfolded list.map_id id_apply] + list_all3_map_iff[where f=id and h=id, unfolded list.map_id id_apply] + list_all3_map_iff[where f=id and g=id, unfolded list.map_id id_apply] + +lemma list_all3_conv_all_nth: + "list_all3 P xs ys zs = + (length xs = length ys \ length ys = length zs \ (\i < length xs. P (xs!i) (ys!i) (zs!i)))" + by (auto simp add: list_all3_list_all2_eq list_all2_conv_all_nth) + +lemma list_all3_refl [intro?]: + "(\x. x \ set xs \ P x x x) \ list_all3 P xs xs xs" + by (simp add: list_all3_conv_all_nth) + +definition wf_mbufn :: "nat \ nat list \ (nat \ event_data table \ bool) list \ event_data mbufn \ bool" where + "wf_mbufn i js Ps buf \ list_all3 (\P j xs. i \ j \ list_all2 P [i.. _ \ _ \ nat \ nat \ event_data list set \ + Formula.formula \ Formula.formula \ event_data mbuf2 \ bool" where + "wf_mbuf2' \ P V j n R \ \ buf \ wf_mbuf2 (min (progress \ P \ j) (progress \ P \ j)) + (progress \ P \ j) (progress \ P \ j) + (\i. qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) i \)) + (\i. qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) i \)) buf" + +definition wf_mbufn' :: "Formula.trace \ _ \ _ \ nat \ nat \ event_data list set \ + Formula.formula Regex.regex \ event_data mbufn \ bool" where + "wf_mbufn' \ P V j n R r buf \ (case to_mregex r of (mr, \s) \ + wf_mbufn (progress_regex \ P r j) (map (\\. progress \ P \ j) \s) + (map (\\ i. qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) i \)) \s) + buf)" + +lemma wf_mbuf2'_UNIV_alt: "wf_mbuf2' \ P V j n UNIV \ \ buf \ (case buf of (xs, ys) \ + list_all2 (\i. wf_table n (Formula.fv \) (\v. Formula.sat \ V (map the v) i \)) + [min (progress \ P \ j) (progress \ P \ j) ..< (progress \ P \ j)] xs \ + list_all2 (\i. wf_table n (Formula.fv \) (\v. Formula.sat \ V (map the v) i \)) + [min (progress \ P \ j) (progress \ P \ j) ..< (progress \ P \ j)] ys)" + unfolding wf_mbuf2'_def wf_mbuf2_def + by (simp add: mem_restr_UNIV[THEN eqTrueI, abs_def] split: prod.split) + +definition wf_ts :: "Formula.trace \ _ \ nat \ Formula.formula \ Formula.formula \ ts list \ bool" where + "wf_ts \ P j \ \ ts \ list_all2 (\i t. t = \ \ i) [min (progress \ P \ j) (progress \ P \ j).. _ \ nat \ Formula.formula Regex.regex \ ts list \ bool" where + "wf_ts_regex \ P j r ts \ list_all2 (\i t. t = \ \ i) [progress_regex \ P r j.. I \ \ Formula.Since (if pos then \ else Formula.Neg \) I \" + +definition (in msaux) wf_since_aux :: "Formula.trace \ _ \ event_data list set \ args \ + Formula.formula \ Formula.formula \ 'msaux \ nat \ bool" where + "wf_since_aux \ V R args \ \ aux ne \ Formula.fv \ \ Formula.fv \ \ (\cur auxlist. valid_msaux args cur aux auxlist \ + cur = (if ne = 0 then 0 else \ \ (ne - 1)) \ + sorted_wrt (\x y. fst x > fst y) auxlist \ + (\t X. (t, X) \ set auxlist \ ne \ 0 \ t \ \ \ (ne - 1) \ \ \ (ne - 1) - t \ right (args_ivl args) \ (\i. \ \ i = t) \ + qtable (args_n args) (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) (ne-1) (Sincep (args_pos args) \ (point (\ \ (ne - 1) - t)) \)) X) \ + (\t. ne \ 0 \ t \ \ \ (ne - 1) \ \ \ (ne - 1) - t \ right (args_ivl args) \ (\i. \ \ i = t) \ + (\X. (t, X) \ set auxlist)))" + +definition wf_matchP_aux :: "Formula.trace \ _ \ nat \ event_data list set \ + \ \ Formula.formula Regex.regex \ event_data mr\aux \ nat \ bool" where + "wf_matchP_aux \ V n R I r aux ne \ sorted_wrt (\x y. fst x > fst y) aux \ + (\t X. (t, X) \ set aux \ ne \ 0 \ t \ \ \ (ne-1) \ \ \ (ne-1) - t \ right I \ (\i. \ \ i = t) \ + (case to_mregex r of (mr, \s) \ + (\ms \ RPDs mr. qtable n (Formula.fv_regex r) (mem_restr R) (\v. Formula.sat \ V (map the v) (ne-1) + (Formula.MatchP (point (\ \ (ne-1) - t)) (from_mregex ms \s))) + (lookup X ms)))) \ + (\t. ne \ 0 \ t \ \ \ (ne-1) \ \ \ (ne-1) - t \ right I \ (\i. \ \ i = t) \ + (\X. (t, X) \ set aux))" + +lemma qtable_mem_restr_UNIV: "qtable n A(mem_restr UNIV) Q X = wf_table n A Q X" + unfolding qtable_def by auto + +lemma (in msaux) wf_since_aux_UNIV_alt: + "wf_since_aux \ V UNIV args \ \ aux ne \ Formula.fv \ \ Formula.fv \ \ (\cur auxlist. valid_msaux args cur aux auxlist \ + cur = (if ne = 0 then 0 else \ \ (ne - 1)) \ + sorted_wrt (\x y. fst x > fst y) auxlist \ + (\t X. (t, X) \ set auxlist \ ne \ 0 \ t \ \ \ (ne - 1) \ \ \ (ne - 1) - t \ right (args_ivl args) \ (\i. \ \ i = t) \ + wf_table (args_n args) (Formula.fv \) + (\v. Formula.sat \ V (map the v) (ne - 1) (Sincep (args_pos args) \ (point (\ \ (ne - 1) - t)) \)) X) \ + (\t. ne \ 0 \ t \ \ \ (ne - 1) \ \ \ (ne - 1) - t \ right (args_ivl args) \ (\i. \ \ i = t) \ + (\X. (t, X) \ set auxlist)))" + unfolding wf_since_aux_def qtable_mem_restr_UNIV .. + +definition wf_until_auxlist :: "Formula.trace \ _ \ nat \ event_data list set \ bool \ + Formula.formula \ \ \ Formula.formula \ event_data muaux \ nat \ bool" where + "wf_until_auxlist \ V n R pos \ I \ auxlist ne \ + list_all2 (\x i. case x of (t, r1, r2) \ t = \ \ i \ + qtable n (Formula.fv \) (mem_restr R) (\v. if pos then (\k\{i.. V (map the v) k \) + else (\k\{i.. V (map the v) k \)) r1 \ + qtable n (Formula.fv \) (mem_restr R) (\v. (\j. i \ j \ j < ne + length auxlist \ mem (\ \ j - \ \ i) I \ + Formula.sat \ V (map the v) j \ \ + (\k\{i.. V (map the v) k \ else \ Formula.sat \ V (map the v) k \))) r2) + auxlist [ne.. _ \ event_data list set \ args \ + Formula.formula \ Formula.formula \ 'muaux \ nat \ bool" where + "wf_until_aux \ V R args \ \ aux ne \ Formula.fv \ \ Formula.fv \ \ + (\cur auxlist. valid_muaux args cur aux auxlist \ + cur = (if ne + length auxlist = 0 then 0 else \ \ (ne + length auxlist - 1)) \ + wf_until_auxlist \ V (args_n args) R (args_pos args) \ (args_ivl args) \ auxlist ne)" + +lemma (in muaux) wf_until_aux_UNIV_alt: + "wf_until_aux \ V UNIV args \ \ aux ne \ Formula.fv \ \ Formula.fv \ \ + (\cur auxlist. valid_muaux args cur aux auxlist \ + cur = (if ne + length auxlist = 0 then 0 else \ \ (ne + length auxlist - 1)) \ + list_all2 (\x i. case x of (t, r1, r2) \ t = \ \ i \ + wf_table (args_n args) (Formula.fv \) (\v. if (args_pos args) + then (\k\{i.. V (map the v) k \) + else (\k\{i.. V (map the v) k \)) r1 \ + wf_table (args_n args) (Formula.fv \) (\v. \j. i \ j \ j < ne + length auxlist \ mem (\ \ j - \ \ i) (args_ivl args) \ + Formula.sat \ V (map the v) j \ \ + (\k\{i.. V (map the v) k \ else \ Formula.sat \ V (map the v) k \)) r2) + auxlist [ne.. _ \ nat \ event_data list set \ + \ \ Formula.formula Regex.regex \ event_data ml\aux \ nat \ nat \ bool" where + "wf_matchF_aux \ V n R I r aux ne k \ (case to_mregex r of (mr, \s) \ + list_all2 (\x i. case x of (t, rels, rel) \ t = \ \ i \ + list_all2 (\\. qtable n (Formula.fv \) (mem_restr R) (\v. + Formula.sat \ V (map the v) i \)) \s rels \ + qtable n (Formula.fv_regex r) (mem_restr R) (\v. (\j. i \ j \ j < ne + length aux + k \ mem (\ \ j - \ \ i) I \ + Regex.match (Formula.sat \ V (map the v)) r i j)) rel) + aux [ne.. V n R I r st i = + (case st of (aux, Y) \ aux \ [] \ wf_matchF_aux \ V n R I r aux i 0 \ + (case to_mregex r of (mr, \s) \ \ms \ LPDs mr. + qtable n (Formula.fv_regex r) (mem_restr R) (\v. + Regex.match (Formula.sat \ V (map the v)) (from_mregex ms \s) i (i + length aux - 1)) (lookup Y ms)))" + +definition lift_envs' :: "nat \ event_data list set \ event_data list set" where + "lift_envs' b R = (\(xs,ys). xs @ ys) ` ({xs. length xs = b} \ R)" + +fun formula_of_constraint :: "Formula.trm \ bool \ mconstraint \ Formula.trm \ Formula.formula" where + "formula_of_constraint (t1, True, MEq, t2) = Formula.Eq t1 t2" +| "formula_of_constraint (t1, True, MLess, t2) = Formula.Less t1 t2" +| "formula_of_constraint (t1, True, MLessEq, t2) = Formula.LessEq t1 t2" +| "formula_of_constraint (t1, False, MEq, t2) = Formula.Neg (Formula.Eq t1 t2)" +| "formula_of_constraint (t1, False, MLess, t2) = Formula.Neg (Formula.Less t1 t2)" +| "formula_of_constraint (t1, False, MLessEq, t2) = Formula.Neg (Formula.LessEq t1 t2)" + +inductive (in maux) wf_mformula :: "Formula.trace \ nat \ _ \ _ \ + nat \ event_data list set \ ('msaux, 'muaux) mformula \ Formula.formula \ bool" + for \ j where + Eq: "is_simple_eq t1 t2 \ + \x\Formula.fv_trm t1. x < n \ \x\Formula.fv_trm t2. x < n \ + wf_mformula \ j P V n R (MRel (eq_rel n t1 t2)) (Formula.Eq t1 t2)" + | neq_Var: "x < n \ + wf_mformula \ j P V n R (MRel empty_table) (Formula.Neg (Formula.Eq (Formula.Var x) (Formula.Var x)))" + | Pred: "\x\Formula.fv (Formula.Pred e ts). x < n \ + \t\set ts. Formula.is_Var t \ Formula.is_Const t \ + wf_mformula \ j P V n R (MPred e ts) (Formula.Pred e ts)" + | Let: "wf_mformula \ j P V m UNIV \ \' \ + wf_mformula \ j (P(p \ progress \ P \' j)) + (V(p \ \i. {v. length v = m - b \ (\zs. length zs = b \ Formula.sat \ V (zs @ v) i \')})) n R \ \' \ + {0.. Formula.fv \' \ b \ m \ m = Formula.nfv \' \ + wf_mformula \ j P V n R (MLet p m b \ \) (Formula.Let p b \' \')" + | And: "wf_mformula \ j P V n R \ \' \ wf_mformula \ j P V n R \ \' \ + if pos then \ = Formula.And \' \' + else \ = Formula.And \' (Formula.Neg \') \ Formula.fv \' \ Formula.fv \' \ + wf_mbuf2' \ P V j n R \' \' buf \ + wf_mformula \ j P V n R (MAnd (fv \') \ pos (fv \') \ buf) \" + | AndAssign: "wf_mformula \ j P V n R \ \' \ + x < n \ x \ Formula.fv \' \ Formula.fv_trm t \ Formula.fv \' \ (x, t) = conf \ + \' = Formula.Eq (Formula.Var x) t \ \' = Formula.Eq t (Formula.Var x) \ + wf_mformula \ j P V n R (MAndAssign \ conf) (Formula.And \' \')" + | AndRel: "wf_mformula \ j P V n R \ \' \ + \' = formula_of_constraint conf \ + (let (t1, _, _, t2) = conf in Formula.fv_trm t1 \ Formula.fv_trm t2 \ Formula.fv \') \ + wf_mformula \ j P V n R (MAndRel \ conf) (Formula.And \' \')" + | Ands: "list_all2 (\\ \'. wf_mformula \ j P V n R \ \') l (l_pos @ map remove_neg l_neg) \ + wf_mbufn (progress \ P (Formula.Ands l') j) (map (\\. progress \ P \ j) (l_pos @ map remove_neg l_neg)) (map (\\ i. + qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) i \)) (l_pos @ map remove_neg l_neg)) buf \ + (l_pos, l_neg) = partition safe_formula l' \ + l_pos \ [] \ + list_all safe_formula (map remove_neg l_neg) \ + A_pos = map fv l_pos \ + A_neg = map fv l_neg \ + \(set A_neg) \ \(set A_pos) \ + wf_mformula \ j P V n R (MAnds A_pos A_neg l buf) (Formula.Ands l')" + | Or: "wf_mformula \ j P V n R \ \' \ wf_mformula \ j P V n R \ \' \ + Formula.fv \' = Formula.fv \' \ + wf_mbuf2' \ P V j n R \' \' buf \ + wf_mformula \ j P V n R (MOr \ \ buf) (Formula.Or \' \')" + | Neg: "wf_mformula \ j P V n R \ \' \ Formula.fv \' = {} \ + wf_mformula \ j P V n R (MNeg \) (Formula.Neg \')" + | Exists: "wf_mformula \ j P V (Suc n) (lift_envs R) \ \' \ + wf_mformula \ j P V n R (MExists \) (Formula.Exists \')" + | Agg: "wf_mformula \ j P V (b + n) (lift_envs' b R) \ \' \ + y < n \ + y + b \ Formula.fv \' \ + {0.. Formula.fv \' \ + Formula.fv_trm f \ Formula.fv \' \ + g0 = (Formula.fv \' \ {0.. + wf_mformula \ j P V n R (MAgg g0 y \ b f \) (Formula.Agg y \ b f \')" + | Prev: "wf_mformula \ j P V n R \ \' \ + first \ j = 0 \ + list_all2 (\i. qtable n (Formula.fv \') (mem_restr R) (\v. Formula.sat \ V (map the v) i \')) + [min (progress \ P \' j) (j-1).. P \' j] buf \ + list_all2 (\i t. t = \ \ i) [min (progress \ P \' j) (j-1).. + wf_mformula \ j P V n R (MPrev I \ first buf nts) (Formula.Prev I \')" + | Next: "wf_mformula \ j P V n R \ \' \ + first \ progress \ P \' j = 0 \ + list_all2 (\i t. t = \ \ i) [progress \ P \' j - 1.. + wf_mformula \ j P V n R (MNext I \ first nts) (Formula.Next I \')" + | Since: "wf_mformula \ j P V n R \ \' \ wf_mformula \ j P V n R \ \' \ + if args_pos args then \'' = \' else \'' = Formula.Neg \' \ + safe_formula \'' = args_pos args \ + args_ivl args = I \ + args_n args = n \ + args_L args = Formula.fv \' \ + args_R args = Formula.fv \' \ + Formula.fv \' \ Formula.fv \' \ + wf_mbuf2' \ P V j n R \' \' buf \ + wf_ts \ P j \' \' nts \ + wf_since_aux \ V R args \' \' aux (progress \ P (Formula.Since \'' I \') j) \ + wf_mformula \ j P V n R (MSince args \ \ buf nts aux) (Formula.Since \'' I \')" + | Until: "wf_mformula \ j P V n R \ \' \ wf_mformula \ j P V n R \ \' \ + if args_pos args then \'' = \' else \'' = Formula.Neg \' \ + safe_formula \'' = args_pos args \ + args_ivl args = I \ + args_n args = n \ + args_L args = Formula.fv \' \ + args_R args = Formula.fv \' \ + Formula.fv \' \ Formula.fv \' \ + wf_mbuf2' \ P V j n R \' \' buf \ + wf_ts \ P j \' \' nts \ + wf_until_aux \ V R args \' \' aux (progress \ P (Formula.Until \'' I \') j) \ + progress \ P (Formula.Until \'' I \') j + length_muaux args aux = min (progress \ P \' j) (progress \ P \' j) \ + wf_mformula \ j P V n R (MUntil args \ \ buf nts aux) (Formula.Until \'' I \')" + | MatchP: "(case to_mregex r of (mr', \s') \ + list_all2 (wf_mformula \ j P V n R) \s \s' \ mr = mr') \ + mrs = sorted_list_of_set (RPDs mr) \ + safe_regex Past Strict r \ + wf_mbufn' \ P V j n R r buf \ + wf_ts_regex \ P j r nts \ + wf_matchP_aux \ V n R I r aux (progress \ P (Formula.MatchP I r) j) \ + wf_mformula \ j P V n R (MMatchP I mr mrs \s buf nts aux) (Formula.MatchP I r)" + | MatchF: "(case to_mregex r of (mr', \s') \ + list_all2 (wf_mformula \ j P V n R) \s \s' \ mr = mr') \ + mrs = sorted_list_of_set (LPDs mr) \ + safe_regex Futu Strict r \ + wf_mbufn' \ P V j n R r buf \ + wf_ts_regex \ P j r nts \ + wf_matchF_aux \ V n R I r aux (progress \ P (Formula.MatchF I r) j) 0 \ + progress \ P (Formula.MatchF I r) j + length aux = progress_regex \ P r j \ + wf_mformula \ j P V n R (MMatchF I mr mrs \s buf nts aux) (Formula.MatchF I r)" + +definition (in maux) wf_mstate :: "Formula.formula \ Formula.prefix \ event_data list set \ ('msaux, 'muaux) mstate \ bool" where + "wf_mstate \ \ R st \ mstate_n st = Formula.nfv \ \ (\\. prefix_of \ \ \ + mstate_i st = progress \ Map.empty \ (plen \) \ + wf_mformula \ (plen \) Map.empty Map.empty (mstate_n st) R (mstate_m st) \)" + + +subsubsection \Initialisation\ + + +lemma wf_mbuf2'_0: "pred_mapping (\x. x = 0) P \ wf_mbuf2' \ P V 0 n R \ \ ([], [])" + unfolding wf_mbuf2'_def wf_mbuf2_def by simp + +lemma wf_mbufn'_0: "to_mregex r = (mr, \s) \ pred_mapping (\x. x = 0) P \ wf_mbufn' \ P V 0 n R r (replicate (length \s) [])" + unfolding wf_mbufn'_def wf_mbufn_def map_replicate_const[symmetric] + by (auto simp: list_all3_map intro: list_all3_refl simp: Min_eq_iff progress_regex_def) + +lemma wf_ts_0: "wf_ts \ P 0 \ \ []" + unfolding wf_ts_def by simp + +lemma wf_ts_regex_0: "wf_ts_regex \ P 0 r []" + unfolding wf_ts_regex_def by simp + +lemma (in msaux) wf_since_aux_Nil: "Formula.fv \' \ Formula.fv \' \ + wf_since_aux \ V R (init_args I n (Formula.fv \') (Formula.fv \') b) \' \' (init_msaux (init_args I n (Formula.fv \') (Formula.fv \') b)) 0" + unfolding wf_since_aux_def by (auto intro!: valid_init_msaux) + +lemma (in muaux) wf_until_aux_Nil: "Formula.fv \' \ Formula.fv \' \ + wf_until_aux \ V R (init_args I n (Formula.fv \') (Formula.fv \') b) \' \' (init_muaux (init_args I n (Formula.fv \') (Formula.fv \') b)) 0" + unfolding wf_until_aux_def wf_until_auxlist_def by (auto intro: valid_init_muaux) + +lemma wf_matchP_aux_Nil: "wf_matchP_aux \ V n R I r [] 0" + unfolding wf_matchP_aux_def by simp + +lemma wf_matchF_aux_Nil: "wf_matchF_aux \ V n R I r [] 0 k" + unfolding wf_matchF_aux_def by simp + +lemma fv_regex_alt: "safe_regex m g r \ Formula.fv_regex r = (\\ \ atms r. Formula.fv \)" + unfolding fv_regex_alt atms_def + by (auto 0 3 dest: safe_regex_safe_formula) + +lemmas to_mregex_atms = + to_mregex_ok[THEN conjunct1, THEN equalityD1, THEN set_mp, rotated] + +lemma (in maux) wf_minit0: "safe_formula \ \ \x\Formula.fv \. x < n \ + pred_mapping (\x. x = 0) P \ + wf_mformula \ 0 P V n R (minit0 n \) \" +proof (induction arbitrary: n R P V rule: safe_formula_induct) + case (Eq_Const c d) + then show ?case + by (auto simp add: is_simple_eq_def simp del: eq_rel.simps intro!: wf_mformula.Eq) +next + case (Eq_Var1 c x) + then show ?case + by (auto simp add: is_simple_eq_def simp del: eq_rel.simps intro!: wf_mformula.Eq) +next + case (Eq_Var2 c x) + then show ?case + by (auto simp add: is_simple_eq_def simp del: eq_rel.simps intro!: wf_mformula.Eq) +next + case (neq_Var x y) + then show ?case by (auto intro!: wf_mformula.neq_Var) +next + case (Pred e ts) + then show ?case by (auto intro!: wf_mformula.Pred) +next + case (Let p b \ \) + with fvi_less_nfv show ?case + by (auto simp: pred_mapping_alt dom_def intro!: wf_mformula.Let Let(4,5)) +next + case (And_assign \ \) + then have 1: "\x\fv \. x < n" by simp + from 1 \safe_assignment (fv \) \\ + obtain x t where + "x < n" "x \ fv \" "fv_trm t \ fv \" + "\ = Formula.Eq (Formula.Var x) t \ \ = Formula.Eq t (Formula.Var x)" + unfolding safe_assignment_def by (force split: formula.splits trm.splits) + with And_assign show ?case + by (auto intro!: wf_mformula.AndAssign split: trm.splits) +next + case (And_safe \ \) + then show ?case by (auto intro!: wf_mformula.And wf_mbuf2'_0) +next + case (And_constraint \ \) + from \fv \ \ fv \\ \is_constraint \\ + obtain t1 p c t2 where + "(t1, p, c, t2) = split_constraint \" + "formula_of_constraint (split_constraint \) = \" + "fv_trm t1 \ fv_trm t2 \ fv \" + by (induction rule: is_constraint.induct) auto + with And_constraint show ?case + by (auto 0 3 intro!: wf_mformula.AndRel) +next + case (And_Not \ \) + then show ?case by (auto intro!: wf_mformula.And wf_mbuf2'_0) +next + case (Ands l pos neg) + note posneg = "Ands.hyps"(1) + let ?wf_minit = "\x. wf_mformula \ 0 P V n R (minit0 n x)" + let ?pos = "filter safe_formula l" + let ?neg = "filter (Not \ safe_formula) l" + have "list_all2 ?wf_minit ?pos pos" + using Ands.IH(1) Ands.prems posneg by (auto simp: list_all_iff intro!: list.rel_refl_strong) + moreover have "list_all2 ?wf_minit (map remove_neg ?neg) (map remove_neg neg)" + using Ands.IH(2) Ands.prems posneg by (auto simp: list.rel_map list_all_iff intro!: list.rel_refl_strong) + moreover have "list_all3 (\_ _ _. True) (?pos @ map remove_neg ?neg) (?pos @ map remove_neg ?neg) l" + by (auto simp: list_all3_conv_all_nth comp_def sum_length_filter_compl) + moreover have "l \ [] \ (MIN \\set l. (0 :: nat)) = 0" + by (cases l) (auto simp: Min_eq_iff) + ultimately show ?case using Ands.hyps Ands.prems(2) + by (auto simp: wf_mbufn_def list_all3_map list.rel_map map_replicate_const[symmetric] subset_eq + map_map[symmetric] map_append[symmetric] simp del: map_map map_append + intro!: wf_mformula.Ands list_all2_appendI) +next + case (Neg \) + then show ?case by (auto intro!: wf_mformula.Neg) +next + case (Or \ \) + then show ?case by (auto intro!: wf_mformula.Or wf_mbuf2'_0) +next + case (Exists \) + then show ?case by (auto simp: fvi_Suc_bound intro!: wf_mformula.Exists) +next + case (Agg y \ b f \) + then show ?case by (auto intro!: wf_mformula.Agg Agg.IH fvi_plus_bound) +next + case (Prev I \) + thm wf_mformula.Prev[where P=P] + then show ?case by (auto intro!: wf_mformula.Prev) +next + case (Next I \) + then show ?case by (auto intro!: wf_mformula.Next) +next + case (Since \ I \) + then show ?case + using wf_since_aux_Nil + by (auto simp add: init_args_def intro!: wf_mformula.Since wf_mbuf2'_0 wf_ts_0) +next + case (Not_Since \ I \) + then show ?case + using wf_since_aux_Nil + by (auto simp add: init_args_def intro!: wf_mformula.Since wf_mbuf2'_0 wf_ts_0) +next + case (Until \ I \) + then show ?case + using valid_length_muaux[OF valid_init_muaux[OF Until(1)]] wf_until_aux_Nil + by (auto simp add: init_args_def simp del: progress_simps intro!: wf_mformula.Until wf_mbuf2'_0 wf_ts_0) +next + case (Not_Until \ I \) + then show ?case + using valid_length_muaux[OF valid_init_muaux[OF Not_Until(1)]] wf_until_aux_Nil + by (auto simp add: init_args_def simp del: progress_simps intro!: wf_mformula.Until wf_mbuf2'_0 wf_ts_0) +next + case (MatchP I r) + then show ?case + by (auto simp: list.rel_map fv_regex_alt simp del: progress_simps split: prod.split + intro!: wf_mformula.MatchP list.rel_refl_strong wf_mbufn'_0 wf_ts_regex_0 wf_matchP_aux_Nil + dest!: to_mregex_atms) +next + case (MatchF I r) + then show ?case + by (auto simp: list.rel_map fv_regex_alt progress_le Min_eq_iff progress_regex_def + simp del: progress_simps split: prod.split + intro!: wf_mformula.MatchF list.rel_refl_strong wf_mbufn'_0 wf_ts_regex_0 wf_matchF_aux_Nil + dest!: to_mregex_atms) +qed + +lemma (in maux) wf_mstate_minit: "safe_formula \ \ wf_mstate \ pnil R (minit \)" + unfolding wf_mstate_def minit_def Let_def + by (auto intro!: wf_minit0 fvi_less_nfv) + + +subsubsection \Evaluation\ + +lemma match_wf_tuple: "Some f = match ts xs \ + wf_tuple n (\t\set ts. Formula.fv_trm t) (Table.tabulate f 0 n)" + by (induction ts xs arbitrary: f rule: match.induct) + (fastforce simp: wf_tuple_def split: if_splits option.splits)+ + +lemma match_fvi_trm_None: "Some f = match ts xs \ \t\set ts. x \ Formula.fv_trm t \ f x = None" + by (induction ts xs arbitrary: f rule: match.induct) (auto split: if_splits option.splits) + +lemma match_fvi_trm_Some: "Some f = match ts xs \ t \ set ts \ x \ Formula.fv_trm t \ f x \ None" + by (induction ts xs arbitrary: f rule: match.induct) (auto split: if_splits option.splits) + +lemma match_eval_trm: "\t\set ts. \i\Formula.fv_trm t. i < n \ Some f = match ts xs \ + map (Formula.eval_trm (Table.tabulate (\i. the (f i)) 0 n)) ts = xs" +proof (induction ts xs arbitrary: f rule: match.induct) + case (3 x ts y ys) + from 3(1)[symmetric] 3(2,3) show ?case + by (auto 0 3 dest: match_fvi_trm_Some sym split: option.splits if_splits intro!: eval_trm_fv_cong) +qed (auto split: if_splits) + +lemma wf_tuple_tabulate_Some: "wf_tuple n A (Table.tabulate f 0 n) \ x \ A \ x < n \ \y. f x = Some y" + unfolding wf_tuple_def by auto + +lemma ex_match: "wf_tuple n (\t\set ts. Formula.fv_trm t) v \ + \t\set ts. (\x\Formula.fv_trm t. x < n) \ (Formula.is_Var t \ Formula.is_Const t) \ + \f. match ts (map (Formula.eval_trm (map the v)) ts) = Some f \ v = Table.tabulate f 0 n" +proof (induction ts "map (Formula.eval_trm (map the v)) ts" arbitrary: v rule: match.induct) + case (3 x ts y ys) + then show ?case + proof (cases "x \ (\t\set ts. Formula.fv_trm t)") + case True + with 3 show ?thesis + by (auto simp: insert_absorb dest!: wf_tuple_tabulate_Some meta_spec[of _ v]) + next + case False + with 3(3,4) have + *: "map (Formula.eval_trm (map the v)) ts = map (Formula.eval_trm (map the (v[x := None]))) ts" + by (auto simp: wf_tuple_def nth_list_update intro!: eval_trm_fv_cong) + from False 3(2-4) obtain f where + "match ts (map (Formula.eval_trm (map the v)) ts) = Some f" "v[x := None] = Table.tabulate f 0 n" + unfolding * + by (atomize_elim, intro 3(1)[of "v[x := None]"]) + (auto simp: wf_tuple_def nth_list_update intro!: eval_trm_fv_cong) + moreover from False this have "f x = None" "length v = n" + by (auto dest: match_fvi_trm_None[OF sym] arg_cong[of _ _ length]) + ultimately show ?thesis using 3(3) + by (auto simp: list_eq_iff_nth_eq wf_tuple_def) + qed +qed (auto simp: wf_tuple_def intro: nth_equalityI) + +lemma eq_rel_eval_trm: "v \ eq_rel n t1 t2 \ is_simple_eq t1 t2 \ + \x\Formula.fv_trm t1 \ Formula.fv_trm t2. x < n \ + Formula.eval_trm (map the v) t1 = Formula.eval_trm (map the v) t2" + by (cases t1; cases t2) (simp_all add: is_simple_eq_def singleton_table_def split: if_splits) + +lemma in_eq_rel: "wf_tuple n (Formula.fv_trm t1 \ Formula.fv_trm t2) v \ + is_simple_eq t1 t2 \ + Formula.eval_trm (map the v) t1 = Formula.eval_trm (map the v) t2 \ + v \ eq_rel n t1 t2" + by (cases t1; cases t2) + (auto simp: is_simple_eq_def singleton_table_def wf_tuple_def unit_table_def + intro!: nth_equalityI split: if_splits) + +lemma table_eq_rel: "is_simple_eq t1 t2 \ + table n (Formula.fv_trm t1 \ Formula.fv_trm t2) (eq_rel n t1 t2)" + by (cases t1; cases t2; simp add: is_simple_eq_def) + +lemma wf_tuple_Suc_fviD: "wf_tuple (Suc n) (Formula.fvi b \) v \ wf_tuple n (Formula.fvi (Suc b) \) (tl v)" + unfolding wf_tuple_def by (simp add: fvi_Suc nth_tl) + +lemma table_fvi_tl: "table (Suc n) (Formula.fvi b \) X \ table n (Formula.fvi (Suc b) \) (tl ` X)" + unfolding table_def by (auto intro: wf_tuple_Suc_fviD) + +lemma wf_tuple_Suc_fvi_SomeI: "0 \ Formula.fvi b \ \ wf_tuple n (Formula.fvi (Suc b) \) v \ + wf_tuple (Suc n) (Formula.fvi b \) (Some x # v)" + unfolding wf_tuple_def + by (auto simp: fvi_Suc less_Suc_eq_0_disj) + +lemma wf_tuple_Suc_fvi_NoneI: "0 \ Formula.fvi b \ \ wf_tuple n (Formula.fvi (Suc b) \) v \ + wf_tuple (Suc n) (Formula.fvi b \) (None # v)" + unfolding wf_tuple_def + by (auto simp: fvi_Suc less_Suc_eq_0_disj) + +lemma qtable_project_fv: "qtable (Suc n) (fv \) (mem_restr (lift_envs R)) P X \ + qtable n (Formula.fvi (Suc 0) \) (mem_restr R) + (\v. \x. P ((if 0 \ fv \ then Some x else None) # v)) (tl ` X)" + using neq0_conv by (fastforce simp: image_iff Bex_def fvi_Suc elim!: qtable_cong dest!: qtable_project) + +lemma mem_restr_lift_envs'_append[simp]: + "length xs = b \ mem_restr (lift_envs' b R) (xs @ ys) = mem_restr R ys" + unfolding mem_restr_def lift_envs'_def + by (auto simp: list_all2_append list.rel_map intro!: exI[where x="map the xs"] list.rel_refl) + +lemma nth_list_update_alt: "xs[i := x] ! j = (if i < length xs \ i = j then x else xs ! j)" + by auto + +lemma wf_tuple_upd_None: "wf_tuple n A xs \ A - {i} = B \ wf_tuple n B (xs[i:=None])" + unfolding wf_tuple_def + by (auto simp: nth_list_update_alt) + +lemma mem_restr_upd_None: "mem_restr R xs \ mem_restr R (xs[i:=None])" + unfolding mem_restr_def + by (auto simp: list_all2_conv_all_nth nth_list_update_alt) + +lemma mem_restr_dropI: "mem_restr (lift_envs' b R) xs \ mem_restr R (drop b xs)" + unfolding mem_restr_def lift_envs'_def + by (auto simp: append_eq_conv_conj list_all2_append2) + +lemma mem_restr_dropD: + assumes "b \ length xs" and "mem_restr R (drop b xs)" + shows "mem_restr (lift_envs' b R) xs" +proof - + let ?R = "\a b. a \ None \ a = Some b" + from assms(2) obtain v where "v \ R" and "list_all2 ?R (drop b xs) v" + unfolding mem_restr_def .. + show ?thesis unfolding mem_restr_def proof + have "list_all2 ?R (take b xs) (map the (take b xs))" + by (auto simp: list.rel_map intro!: list.rel_refl) + moreover note \list_all2 ?R (drop b xs) v\ + ultimately have "list_all2 ?R (take b xs @ drop b xs) (map the (take b xs) @ v)" + by (rule list_all2_appendI) + then show "list_all2 ?R xs (map the (take b xs) @ v)" by simp + show "map the (take b xs) @ v \ lift_envs' b R" + unfolding lift_envs'_def using assms(1) \v \ R\ by auto + qed +qed + +lemma wf_tuple_append: "wf_tuple a {x \ A. x < a} xs \ + wf_tuple b {x - a | x. x \ A \ x \ a} ys \ + wf_tuple (a + b) A (xs @ ys)" + unfolding wf_tuple_def by (auto simp: nth_append eq_diff_iff) + +lemma wf_tuple_map_Some: "length xs = n \ {0.. A \ wf_tuple n A (map Some xs)" + unfolding wf_tuple_def by auto + +lemma wf_tuple_drop: "wf_tuple (b + n) A xs \ {x - b | x. x \ A \ x \ b} = B \ + wf_tuple n B (drop b xs)" + unfolding wf_tuple_def by force + +lemma ecard_image: "inj_on f A \ ecard (f ` A) = ecard A" + unfolding ecard_def by (auto simp: card_image dest: finite_imageD) + +lemma meval_trm_eval_trm: "wf_tuple n A x \ fv_trm t \ A \ \i\A. i < n \ + meval_trm t x = Formula.eval_trm (map the x) t" + unfolding wf_tuple_def + by (induction t) simp_all + +lemma list_update_id: "xs ! i = z \ xs[i:=z] = xs" + by (induction xs arbitrary: i) (auto split: nat.split) + +lemma qtable_wf_tupleD: "qtable n A P Q X \ \x\X. wf_tuple n A x" + unfolding qtable_def table_def by blast + +lemma qtable_eval_agg: + assumes inner: "qtable (b + n) (Formula.fv \) (mem_restr (lift_envs' b R)) + (\v. Formula.sat \ V (map the v) i \) rel" + and n: "\x\Formula.fv (Formula.Agg y \ b f \). x < n" + and fresh: "y + b \ Formula.fv \" + and b_fv: "{0.. Formula.fv \" + and f_fv: "Formula.fv_trm f \ Formula.fv \" + and g0: "g0 = (Formula.fv \ \ {0.. b f \)) (mem_restr R) + (\v. Formula.sat \ V (map the v) i (Formula.Agg y \ b f \)) (eval_agg n g0 y \ b f rel)" + (is "qtable _ ?fv _ ?Q ?rel'") +proof - + define M where "M = (\v. {(x, ecard Zs) | x Zs. + Zs = {zs. length zs = b \ Formula.sat \ V (zs @ v) i \ \ Formula.eval_trm (zs @ v) f = x} \ + Zs \ {}})" + have f_fvi: "Formula.fvi_trm b f \ Formula.fvi b \" + using f_fv by (auto simp: fvi_trm_iff_fv_trm[where b=b] fvi_iff_fv[where b=b]) + show ?thesis proof (cases "g0 \ rel = empty_table") + case True + then have [simp]: "Formula.fvi b \ = {}" + by (auto simp: g0 fvi_iff_fv(1)[where b=b]) + then have [simp]: "Formula.fvi_trm b f = {}" + using f_fvi by auto + show ?thesis proof (rule qtableI) + show "table n ?fv ?rel'" by (simp add: eval_agg_def True) + next + fix v + assume "wf_tuple n ?fv v" "mem_restr R v" + have "\ Formula.sat \ V (zs @ map the v) i \" if [simp]: "length zs = b" for zs + proof - + let ?zs = "map2 (\z i. if i \ Formula.fv \ then Some z else None) zs [0.. fv \. x < b} ?zs" + by (simp add: wf_tuple_def) + then have "wf_tuple (b + n) (Formula.fv \) (?zs @ v[y:=None])" + using \wf_tuple n ?fv v\ True + by (auto simp: g0 intro!: wf_tuple_append wf_tuple_upd_None) + then have "\ Formula.sat \ V (map the (?zs @ v[y:=None])) i \" + using True \mem_restr R v\ + by (auto simp del: map_append dest!: in_qtableI[OF inner, rotated -1] + intro!: mem_restr_upd_None) + also have "Formula.sat \ V (map the (?zs @ v[y:=None])) i \ \ Formula.sat \ V (zs @ map the v) i \" + using True by (auto simp: g0 nth_append intro!: sat_fv_cong) + finally show ?thesis . + qed + then have M_empty: "M (map the v) = {}" + unfolding M_def by blast + show "Formula.sat \ V (map the v) i (Formula.Agg y \ b f \)" + if "v \ eval_agg n g0 y \ b f rel" + using M_empty True that n + by (simp add: M_def eval_agg_def g0 singleton_table_def) + have "v \ singleton_table n y (the (v ! y))" "length v = n" + using \wf_tuple n ?fv v\ unfolding wf_tuple_def singleton_table_def + by (auto simp add: tabulate_alt map_nth + intro!: trans[OF map_cong[where g="(!) v", simplified nth_map, OF refl], symmetric]) + then show "v \ eval_agg n g0 y \ b f rel" + if "Formula.sat \ V (map the v) i (Formula.Agg y \ b f \)" + using M_empty True that n + by (simp add: M_def eval_agg_def g0) + qed + next + case non_default_case: False + have union_fv: "{0.. (\x. x + b) ` Formula.fvi b \ = fv \" + using b_fv + by (auto simp: fvi_iff_fv(1)[where b=b] intro!: image_eqI[where b=x and x="x - b" for x]) + have b_n: "\x\fv \. x < b + n" + proof + fix x assume "x \ fv \" + show "x < b + n" proof (cases "x \ b") + case True + with \x \ fv \\ have "x - b \ ?fv" + by (simp add: fvi_iff_fv(1)[where b=b]) + then show ?thesis using n f_fvi by (auto simp: Un_absorb2) + qed simp + qed + + define M' where "M' = (\k. let group = Set.filter (\x. drop b x = k) rel; + images = meval_trm f ` group + in (\y. (y, ecard (Set.filter (\x. meval_trm f x = y) group))) ` images)" + have M'_M: "M' (drop b x) = M (map the (drop b x))" if "x \ rel" "mem_restr (lift_envs' b R) x" for x + proof - + from that have wf_x: "wf_tuple (b + n) (fv \) x" + by (auto elim!: in_qtableE[OF inner]) + then have wf_zs_x: "wf_tuple (b + n) (fv \) (map Some zs @ drop b x)" + if "length zs = b" for zs + using that b_fv + by (auto intro!: wf_tuple_append wf_tuple_map_Some wf_tuple_drop) + have 1: "(length zs = b \ Formula.sat \ V (zs @ map the (drop b x)) i \ \ + Formula.eval_trm (zs @ map the (drop b x)) f = y) \ + (\a. a \ rel \ take b a = map Some zs \ drop b a = drop b x \ meval_trm f a = y)" + (is "?A \ (\a. ?B a)") for y zs + proof (intro iffI conjI) + assume ?A + then have "?B (map Some zs @ drop (length zs) x)" + using in_qtableI[OF inner wf_zs_x] \mem_restr (lift_envs' b R) x\ + meval_trm_eval_trm[OF wf_zs_x f_fv b_n] + by (auto intro!: mem_restr_dropI) + then show "\a. ?B a" .. + next + assume "\a. ?B a" + then obtain a where "?B a" .. + then have "a \ rel" and a_eq: "a = map Some zs @ drop b x" + using append_take_drop_id[of b a] by auto + then have "length a = b + n" + using inner unfolding qtable_def table_def + by (blast intro!: wf_tuple_length) + then show "length zs = b" + using wf_tuple_length[OF wf_x] unfolding a_eq by simp + then have "mem_restr (lift_envs' b R) a" + using \mem_restr _ x\ unfolding a_eq by (auto intro!: mem_restr_dropI) + then show "Formula.sat \ V (zs @ map the (drop b x)) i \" + using in_qtableE[OF inner \a \ rel\] + by (auto simp: a_eq sat_fv_cong[THEN iffD1, rotated -1]) + from \?B a\ show "Formula.eval_trm (zs @ map the (drop b x)) f = y" + using meval_trm_eval_trm[OF wf_zs_x f_fv b_n, OF \length zs = b\] + unfolding a_eq by simp + qed + have 2: "map Some (map the (take b a)) = take b a" if "a \ rel" for a + using that b_fv inner[THEN qtable_wf_tupleD] + unfolding table_def wf_tuple_def + by (auto simp: list_eq_iff_nth_eq) + have 3: "ecard {zs. \a. a \ rel \ take b a = map Some zs \ drop b a = drop b x \ P a} = + ecard {a. a \ rel \ drop b a = drop b x \ P a}" (is "ecard ?A = ecard ?B") for P + proof - + have "ecard ?A = ecard ((\zs. map Some zs @ drop b x) ` ?A)" + by (auto intro!: ecard_image[symmetric] inj_onI) + also have "(\zs. map Some zs @ drop b x) ` ?A = ?B" + by (subst (1 2) eq_commute) (auto simp: image_iff, metis "2" append_take_drop_id) + finally show ?thesis . + qed + show ?thesis + unfolding M_def M'_def + by (auto simp: non_default_case Let_def image_def Set.filter_def 1 3, metis "2") + qed + have drop_lift: "mem_restr (lift_envs' b R) x" if "x \ rel" "mem_restr R ((drop b x)[y:=z])" for x z + proof - + have "(drop b x)[y:=None] = (drop b x)[y:=drop b x ! y]" proof - + from \x \ rel\ have "drop b x ! y = None" + using fresh n inner[THEN qtable_wf_tupleD] + by (simp add: add.commute wf_tuple_def) + then show ?thesis by simp + qed + then have "(drop b x)[y:=None] = drop b x" by simp + moreover from \x \ rel\ have "length x = b + n" + using inner[THEN qtable_wf_tupleD] + by (simp add: wf_tuple_def) + moreover from that(2) have "mem_restr R ((drop b x)[y:=z, y:=None])" + by (rule mem_restr_upd_None) + ultimately show ?thesis + by (auto intro!: mem_restr_dropD) + qed + + { + fix v + assume "mem_restr R v" + have "v \ (\k. k[y:=Some (eval_agg_op \ (M' k))]) ` drop b ` rel \ + v \ (\k. k[y:=Some (eval_agg_op \ (M (map the k)))]) ` drop b ` rel" + (is "v \ ?A \ v \ ?B") + proof + assume "v \ ?A" + then obtain v' where *: "v' \ rel" "v = (drop b v')[y:=Some (eval_agg_op \ (M' (drop b v')))]" + by auto + then have "M' (drop b v') = M (map the (drop b v'))" + using \mem_restr R v\ by (auto intro!: M'_M drop_lift) + with * show "v \ ?B" by simp + next + assume "v \ ?B" + then obtain v' where *: "v' \ rel" "v = (drop b v')[y:=Some (eval_agg_op \ (M (map the (drop b v'))))]" + by auto + then have "M (map the (drop b v')) = M' (drop b v')" + using \mem_restr R v\ by (auto intro!: M'_M[symmetric] drop_lift) + with * show "v \ ?A" by simp + qed + then have "v \ eval_agg n g0 y \ b f rel \ v \ (\k. k[y:=Some (eval_agg_op \ (M (map the k)))]) ` drop b ` rel" + by (simp add: non_default_case eval_agg_def M'_def Let_def) + } + note alt = this + + show ?thesis proof (rule qtableI) + show "table n ?fv ?rel'" + using inner[THEN qtable_wf_tupleD] n f_fvi + by (auto simp: eval_agg_def non_default_case table_def wf_tuple_def Let_def nth_list_update + fvi_iff_fv[where b=b] add.commute) + next + fix v + assume "wf_tuple n ?fv v" "mem_restr R v" + then have length_v: "length v = n" by (simp add: wf_tuple_def) + + show "Formula.sat \ V (map the v) i (Formula.Agg y \ b f \)" + if "v \ eval_agg n g0 y \ b f rel" + proof - + from that obtain v' where "v' \ rel" + "v = (drop b v')[y:=Some (eval_agg_op \ (M (map the (drop b v'))))]" + using alt[OF \mem_restr R v\] by blast + then have length_v': "length v' = b + n" + using inner[THEN qtable_wf_tupleD] + by (simp add: wf_tuple_def) + have "Formula.sat \ V (map the v') i \" + using \v' \ rel\ \mem_restr R v\ + by (auto simp: \v = _\ elim!: in_qtableE[OF inner] intro!: drop_lift \v' \ rel\) + then have "Formula.sat \ V (map the (take b v') @ map the v) i \" + proof (rule sat_fv_cong[THEN iffD1, rotated], intro ballI) + fix x + assume "x \ fv \" + then have "x \ y + b" using fresh by blast + moreover have "x < length v'" + using \x \ fv \\ b_n by (simp add: length_v') + ultimately show "map the v' ! x = (map the (take b v') @ map the v) ! x" + by (auto simp: \v = _\ nth_append) + qed + then have 1: "M (map the v) \ {}" by (force simp: M_def length_v') + + have "y < length (drop b v')" using n by (simp add: length_v') + moreover have "Formula.sat \ V (zs @ map the v) i \ \ + Formula.sat \ V (zs @ map the (drop b v')) i \" if "length zs = b" for zs + proof (intro sat_fv_cong ballI) + fix x + assume "x \ fv \" + then have "x \ y + b" using fresh by blast + moreover have "x < length v'" + using \x \ fv \\ b_n by (simp add: length_v') + ultimately show "(zs @ map the v) ! x = (zs @ map the (drop b v')) ! x" + by (auto simp: \v = _\ that nth_append) + qed + moreover have "Formula.eval_trm (zs @ map the v) f = + Formula.eval_trm (zs @ map the (drop b v')) f" if "length zs = b" for zs + proof (intro eval_trm_fv_cong ballI) + fix x + assume "x \ fv_trm f" + then have "x \ y + b" using f_fv fresh by blast + moreover have "x < length v'" + using \x \ fv_trm f\ f_fv b_n by (auto simp: length_v') + ultimately show "(zs @ map the v) ! x = (zs @ map the (drop b v')) ! x" + by (auto simp: \v = _\ that nth_append) + qed + ultimately have "map the v ! y = eval_agg_op \ (M (map the v))" + by (simp add: M_def \v = _\ conj_commute cong: conj_cong) + with 1 show ?thesis by (auto simp: M_def) + qed + + show "v \ eval_agg n g0 y \ b f rel" + if sat_Agg: "Formula.sat \ V (map the v) i (Formula.Agg y \ b f \)" + proof - + obtain zs where "length zs = b" and "map Some zs @ v[y:=None] \ rel" + proof (cases "fv \ \ {0.. empty_table" by (simp add: g0) + then obtain x where "x \ rel" by auto + have "(\i < n. (v[y:=None]) ! i = None)" + using True \wf_tuple n ?fv v\ f_fv + by (fastforce simp: wf_tuple_def fvi_iff_fv[where b=b] fvi_trm_iff_fv_trm[where b=b]) + moreover have x: "(\i < n. drop b x ! i = None) \ length x = b + n" + using True \x \ rel\ inner[THEN qtable_wf_tupleD] f_fv + by (auto simp: wf_tuple_def) + ultimately have "v[y:=None] = drop b x" + unfolding list_eq_iff_nth_eq by (auto simp: length_v) + with \x \ rel\ have "take b x @ v[y:=None] \ rel" by simp + moreover have "map (Some \ the) (take b x) = take b x" + using True \x \ rel\ inner[THEN qtable_wf_tupleD] b_fv + by (subst map_cong[where g=id, OF refl]) (auto simp: wf_tuple_def in_set_conv_nth) + ultimately have "map Some (map the (take b x)) @ v[y:=None] \ rel" by simp + then show thesis using x[THEN conjunct2] by (fastforce intro!: that[rotated]) + next + case False + with sat_Agg obtain zs where "length zs = b" and "Formula.sat \ V (zs @ map the v) i \" + by auto + then have "Formula.sat \ V (zs @ map the (v[y:=None])) i \" + using fresh + by (auto simp: map_update not_less nth_append elim!: sat_fv_cong[THEN iffD1, rotated] + intro!: nth_list_update_neq[symmetric]) + then have "map Some zs @ v[y:=None] \ rel" + using b_fv f_fv fresh + by (auto intro!: in_qtableI[OF inner] wf_tuple_append wf_tuple_map_Some + wf_tuple_upd_None \wf_tuple n ?fv v\ mem_restr_upd_None \mem_restr R v\ + simp: \length zs = b\ set_eq_iff fvi_iff_fv[where b=b] fvi_trm_iff_fv_trm[where b=b]) + force+ + with that \length zs = b\ show thesis by blast + qed + then have 1: "v[y:=None] \ drop b ` rel" by (intro image_eqI) auto + + have y_length: "y < length v" using n by (simp add: length_v) + moreover have "Formula.sat \ V (zs @ map the (v[y:=None])) i \ \ + Formula.sat \ V (zs @ map the v) i \" if "length zs = b" for zs + proof (intro sat_fv_cong ballI) + fix x + assume "x \ fv \" + then have "x \ y + b" using fresh by blast + moreover have "x < b + length v" + using \x \ fv \\ b_n by (simp add: length_v) + ultimately show "(zs @ map the (v[y:=None])) ! x = (zs @ map the v) ! x" + by (auto simp: that nth_append) + qed + moreover have "Formula.eval_trm (zs @ map the (v[y:=None])) f = + Formula.eval_trm (zs @ map the v) f" if "length zs = b" for zs + proof (intro eval_trm_fv_cong ballI) + fix x + assume "x \ fv_trm f" + then have "x \ y + b" using f_fv fresh by blast + moreover have "x < b + length v" + using \x \ fv_trm f\ f_fv b_n by (auto simp: length_v) + ultimately show "(zs @ map the (v[y:=None])) ! x = (zs @ map the v) ! x" + by (auto simp: that nth_append) + qed + ultimately have "map the v ! y = eval_agg_op \ (M (map the (v[y:=None])))" + using sat_Agg by (simp add: M_def cong: conj_cong) (simp cong: rev_conj_cong) + then have 2: "v ! y = Some (eval_agg_op \ (M (map the (v[y:=None]))))" + using \wf_tuple n ?fv v\ y_length by (auto simp add: wf_tuple_def) + show ?thesis + unfolding alt[OF \mem_restr R v\] + by (rule image_eqI[where x="v[y:=None]"]) (use 1 2 in \auto simp: y_length list_update_id\) + qed + qed + qed +qed + +lemma mprev: "mprev_next I xs ts = (ys, xs', ts') \ + list_all2 P [i.. list_all2 (\i t. t = \ \ i) [i.. i \ j' \ i < j \ + list_all2 (\i X. if mem (\ \ (Suc i) - \ \ i) I then P i X else X = empty_table) + [i.. + list_all2 P [min j' (j-1).. + list_all2 (\i t. t = \ \ i) [min j' (j-1).. + list_all2 P [Suc i.. list_all2 (\i t. t = \ \ i) [i.. Suc i \ j' \ i < j \ + list_all2 (\i X. if mem (\ \ (Suc i) - \ \ i) I then P (Suc i) X else X = empty_table) + [i.. + list_all2 P [Suc (min (j'-1) (j-1)).. + list_all2 (\i t. t = \ \ i) [min (j'-1) (j-1).. A \ A \ set xs \ x \ foldr (\) xs {}" + by (induction xs) auto + +lemma in_foldr_UnE: "x \ foldr (\) xs {} \ (\A. A \ set xs \ x \ A \ P) \ P" + by (induction xs) auto + +lemma sat_the_restrict: "fv \ \ A \ Formula.sat \ V (map the (restrict A v)) i \ = Formula.sat \ V (map the v) i \" + by (rule sat_fv_cong) (auto intro!: map_the_restrict) + +lemma eps_the_restrict: "fv_regex r \ A \ Regex.eps (Formula.sat \ V (map the (restrict A v))) i r = Regex.eps (Formula.sat \ V (map the v)) i r" + by (rule eps_fv_cong) (auto intro!: map_the_restrict) + +lemma sorted_wrt_filter[simp]: "sorted_wrt R xs \ sorted_wrt R (filter P xs)" + by (induct xs) auto + +lemma concat_map_filter[simp]: + "concat (map f (filter P xs)) = concat (map (\x. if P x then f x else []) xs)" + by (induct xs) auto + +lemma map_filter_alt: + "map f (filter P xs) = concat (map (\x. if P x then [f x] else []) xs)" + by (induct xs) auto + +lemma (in maux) update_since: + assumes pre: "wf_since_aux \ V R args \ \ aux ne" + and qtable1: "qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) ne \) rel1" + and qtable2: "qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) ne \) rel2" + and result_eq: "(rel, aux') = update_since args rel1 rel2 (\ \ ne) aux" + and fvi_subset: "Formula.fv \ \ Formula.fv \" + and args_ivl: "args_ivl args = I" + and args_n: "args_n args = n" + and args_L: "args_L args = Formula.fv \" + and args_R: "args_R args = Formula.fv \" + and args_pos: "args_pos args = pos" + shows "wf_since_aux \ V R args \ \ aux' (Suc ne)" + and "qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) ne (Sincep pos \ I \)) rel" +proof - + let ?wf_tuple = "\v. wf_tuple n (Formula.fv \) v" + note sat.simps[simp del] + from pre[unfolded wf_since_aux_def] obtain cur auxlist where aux: "valid_msaux args cur aux auxlist" + "sorted_wrt (\x y. fst y < fst x) auxlist" + "\t X. (t, X) \ set auxlist \ ne \ 0 \ t \ \ \ (ne - 1) \ \ \ (ne - 1) - t \ right I \ + (\i. \ \ i = t) \ + qtable n (fv \) (mem_restr R) + (\v. Formula.sat \ V (map the v) (ne - 1) (Sincep pos \ (point (\ \ (ne - 1) - t)) \)) X" + "\t. ne \ 0 \ t \ \ \ (ne - 1) \ \ \ (ne - 1) - t \ right I \ (\i. \ \ i = t) \ + (\X. (t, X) \ set auxlist)" + and cur_def: + "cur = (if ne = 0 then 0 else \ \ (ne - 1))" + unfolding args_ivl args_n args_pos by blast + from pre[unfolded wf_since_aux_def] have fv_sub: "Formula.fv \ \ Formula.fv \" by simp + + define aux0 where "aux0 = join_msaux args rel1 (add_new_ts_msaux args (\ \ ne) aux)" + define auxlist0 where "auxlist0 = [(t, join rel pos rel1). (t, rel) \ auxlist, \ \ ne - t \ right I]" + have tabL: "table (args_n args) (args_L args) rel1" + using qtable1[unfolded qtable_def] unfolding args_n[symmetric] args_L[symmetric] by simp + have cur_le: "cur \ \ \ ne" + unfolding cur_def by auto + have valid0: "valid_msaux args (\ \ ne) aux0 auxlist0" unfolding aux0_def auxlist0_def + using valid_join_msaux[OF valid_add_new_ts_msaux[OF aux(1)], OF cur_le tabL] + by (auto simp: args_ivl args_pos cur_def map_filter_alt split_beta cong: map_cong) + from aux(2) have sorted_auxlist0: "sorted_wrt (\x y. fst x > fst y) auxlist0" + unfolding auxlist0_def + by (induction auxlist) (auto simp add: sorted_wrt_append) + have in_auxlist0_1: "(t, X) \ set auxlist0 \ ne \ 0 \ t \ \ \ (ne-1) \ \ \ ne - t \ right I \ + (\i. \ \ i = t) \ + qtable n (Formula.fv \) (mem_restr R) (\v. (Formula.sat \ V (map the v) (ne-1) (Sincep pos \ (point (\ \ (ne-1) - t)) \) \ + (if pos then Formula.sat \ V (map the v) ne \ else \ Formula.sat \ V (map the v) ne \))) X" for t X + unfolding auxlist0_def using fvi_subset + by (auto 0 1 elim!: qtable_join[OF _ qtable1] simp: sat_the_restrict dest!: aux(3)) + then have in_auxlist0_le_\: "(t, X) \ set auxlist0 \ t \ \ \ ne" for t X + by (meson \_mono diff_le_self le_trans) + have in_auxlist0_2: "ne \ 0 \ t \ \ \ (ne-1) \ \ \ ne - t \ right I \ \i. \ \ i = t \ + \X. (t, X) \ set auxlist0" for t + proof - + fix t + assume "ne \ 0" "t \ \ \ (ne-1)" "\ \ ne - t \ right I" "\i. \ \ i = t" + then obtain X where "(t, X) \ set auxlist" + by (atomize_elim, intro aux(4)) + (auto simp: gr0_conv_Suc elim!: order_trans[rotated] intro!: diff_le_mono \_mono) + with \\ \ ne - t \ right I\ have "(t, join X pos rel1) \ set auxlist0" + unfolding auxlist0_def by (auto elim!: bexI[rotated] intro!: exI[of _ X]) + then show "\X. (t, X) \ set auxlist0" + by blast + qed + have auxlist0_Nil: "auxlist0 = [] \ ne = 0 \ ne \ 0 \ (\t. t \ \ \ (ne-1) \ \ \ ne - t \ right I \ + (\i. \ \ i = t))" + using in_auxlist0_2 by (auto) + + have aux'_eq: "aux' = add_new_table_msaux args rel2 aux0" + using result_eq unfolding aux0_def update_since_def Let_def by simp + define auxlist' where + auxlist'_eq: "auxlist' = (case auxlist0 of + [] \ [(\ \ ne, rel2)] + | x # auxlist' \ (if fst x = \ \ ne then (fst x, snd x \ rel2) # auxlist' else (\ \ ne, rel2) # x # auxlist'))" + have tabR: "table (args_n args) (args_R args) rel2" + using qtable2[unfolded qtable_def] unfolding args_n[symmetric] args_R[symmetric] by simp + have valid': "valid_msaux args (\ \ ne) aux' auxlist'" + unfolding aux'_eq auxlist'_eq using valid_add_new_table_msaux[OF valid0 tabR] + by (auto simp: not_le split: list.splits option.splits if_splits) + have sorted_auxlist': "sorted_wrt (\x y. fst x > fst y) auxlist'" + unfolding auxlist'_eq + using sorted_auxlist0 in_auxlist0_le_\ by (cases auxlist0) fastforce+ + have in_auxlist'_1: "t \ \ \ ne \ \ \ ne - t \ right I \ (\i. \ \ i = t) \ + qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) ne (Sincep pos \ (point (\ \ ne - t)) \)) X" + if auxlist': "(t, X) \ set auxlist'" for t X + proof (cases auxlist0) + case Nil + with auxlist' show ?thesis + unfolding auxlist'_eq using qtable2 auxlist0_Nil + by (auto simp: zero_enat_def[symmetric] sat_Since_rec[where i=ne] + dest: spec[of _ "\ \ (ne-1)"] elim!: qtable_cong[OF _ refl]) + next + case (Cons a as) + show ?thesis + proof (cases "t = \ \ ne") + case t: True + show ?thesis + proof (cases "fst a = \ \ ne") + case True + with auxlist' Cons t have "X = snd a \ rel2" + unfolding auxlist'_eq using sorted_auxlist0 by (auto split: if_splits) + moreover from in_auxlist0_1[of "fst a" "snd a"] Cons have "ne \ 0" + "fst a \ \ \ (ne - 1)" "\ \ ne - fst a \ right I" "\i. \ \ i = fst a" + "qtable n (fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) (ne - 1) + (Sincep pos \ (point (\ \ (ne - 1) - fst a)) \) \ (if pos then Formula.sat \ V (map the v) ne \ + else \ Formula.sat \ V (map the v) ne \)) (snd a)" + by (auto simp: True[symmetric] zero_enat_def[symmetric]) + ultimately show ?thesis using qtable2 t True + by (auto simp: sat_Since_rec[where i=ne] sat.simps(6) elim!: qtable_union) + next + case False + with auxlist' Cons t have "X = rel2" + unfolding auxlist'_eq using sorted_auxlist0 in_auxlist0_le_\[of "fst a" "snd a"] by (auto split: if_splits) + with auxlist' Cons t False show ?thesis + unfolding auxlist'_eq using qtable2 in_auxlist0_2[of "\ \ (ne-1)"] in_auxlist0_le_\[of "fst a" "snd a"] sorted_auxlist0 + by (auto simp: sat_Since_rec[where i=ne] sat.simps(3) zero_enat_def[symmetric] enat_0_iff not_le + elim!: qtable_cong[OF _ refl] dest!: le_\_less meta_mp) + qed + next + case False + with auxlist' Cons have "(t, X) \ set auxlist0" + unfolding auxlist'_eq by (auto split: if_splits) + then have "ne \ 0" "t \ \ \ (ne - 1)" "\ \ ne - t \ right I" "\i. \ \ i = t" + "qtable n (fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) (ne - 1) (Sincep pos \ (point (\ \ (ne - 1) - t)) \) \ + (if pos then Formula.sat \ V (map the v) ne \ else \ Formula.sat \ V (map the v) ne \)) X" + using in_auxlist0_1 by blast+ + with False auxlist' Cons show ?thesis + unfolding auxlist'_eq using qtable2 + by (fastforce simp: sat_Since_rec[where i=ne] sat.simps(6) + diff_diff_right[where i="\ \ ne" and j="\ \ _ + \ \ ne" and k="\ \ (ne - 1)", + OF trans_le_add2, simplified] elim!: qtable_cong[OF _ refl] order_trans dest: le_\_less) + qed + qed + + have in_auxlist'_2: "\X. (t, X) \ set auxlist'" if "t \ \ \ ne" "\ \ ne - t \ right I" "\i. \ \ i = t" for t + proof (cases "t = \ \ ne") + case True + then show ?thesis + proof (cases auxlist0) + case Nil + with True show ?thesis unfolding auxlist'_eq by (simp add: zero_enat_def[symmetric]) + next + case (Cons a as) + with True show ?thesis unfolding auxlist'_eq + by (cases "fst a = \ \ ne") (auto simp: zero_enat_def[symmetric]) + qed + next + case False + with that have "ne \ 0" + using le_\_less neq0_conv by blast + moreover from False that have "t \ \ \ (ne-1)" + by (metis One_nat_def Suc_leI Suc_pred \_mono diff_is_0_eq' order.antisym neq0_conv not_le) + ultimately obtain X where "(t, X) \ set auxlist0" using \\ \ ne - t \ right I\ \\i. \ \ i = t\ + using \_mono[of "ne - 1" "ne" \] by (atomize_elim, cases "right I") (auto intro!: in_auxlist0_2 simp del: \_mono) + then show ?thesis unfolding auxlist'_eq using False \\ \ ne - t \ right I\ + by (auto intro: exI[of _ X] split: list.split) + qed + + show "wf_since_aux \ V R args \ \ aux' (Suc ne)" + unfolding wf_since_aux_def args_ivl args_n args_pos + by (auto simp add: fv_sub dest: in_auxlist'_1 intro: sorted_auxlist' in_auxlist'_2 + intro!: exI[of _ auxlist'] valid') + + have "rel = result_msaux args aux'" + using result_eq by (auto simp add: update_since_def Let_def) + with valid' have rel_eq: "rel = foldr (\) [rel. (t, rel) \ auxlist', left I \ \ \ ne - t] {}" + by (auto simp add: args_ivl valid_result_msaux + intro!: arg_cong[where f = "\x. foldr (\) (concat x) {}"] split: option.splits) + have rel_alt: "rel = (\(t, rel) \ set auxlist'. if left I \ \ \ ne - t then rel else empty_table)" + unfolding rel_eq + by (auto elim!: in_foldr_UnE bexI[rotated] intro!: in_foldr_UnI) + show "qtable n (fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) ne (Sincep pos \ I \)) rel" + unfolding rel_alt + proof (rule qtable_Union[where Qi="\(t, X) v. + left I \ \ \ ne - t \ Formula.sat \ V (map the v) ne (Sincep pos \ (point (\ \ ne - t)) \)"], + goal_cases finite qtable equiv) + case (equiv v) + show ?case + proof (rule iffI, erule sat_Since_point, goal_cases left right) + case (left j) + then show ?case using in_auxlist'_2[of "\ \ j", OF _ _ exI, OF _ _ refl] by auto + next + case right + then show ?case by (auto elim!: sat_Since_pointD dest: in_auxlist'_1) + qed + qed (auto dest!: in_auxlist'_1 intro!: qtable_empty) +qed + +lemma fv_regex_from_mregex: + "ok (length \s) mr \ fv_regex (from_mregex mr \s) \ (\\ \ set \s. fv \)" + by (induct mr) (auto simp: Bex_def in_set_conv_nth)+ + +lemma qtable_\_lax: + assumes "ok (length \s) mr" + and "list_all2 (\\ rel. qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) i \) rel) \s rels" + and "fv_regex (from_mregex mr \s) \ A" and "qtable n A (mem_restr R) Q guard" + shows "qtable n A (mem_restr R) + (\v. Regex.eps (Formula.sat \ V (map the v)) i (from_mregex mr \s) \ Q v) (\_lax guard rels mr)" + using assms +proof (induct mr) + case (MPlus mr1 mr2) + from MPlus(3-6) show ?case + by (auto intro!: qtable_union[OF MPlus(1,2)]) +next + case (MTimes mr1 mr2) + then have "fv_regex (from_mregex mr1 \s) \ A" "fv_regex (from_mregex mr2 \s) \ A" + using fv_regex_from_mregex[of \s mr1] fv_regex_from_mregex[of \s mr2] by (auto simp: subset_eq) + with MTimes(3-6) show ?case + by (auto simp: eps_the_restrict restrict_idle intro!: qtable_join[OF MTimes(1,2)]) +qed (auto split: prod.splits if_splits simp: qtable_empty_iff list_all2_conv_all_nth + in_set_conv_nth restrict_idle sat_the_restrict + intro: in_qtableI qtableI elim!: qtable_join[where A=A and C=A]) + +lemma nullary_qtable_cases: "qtable n {} P Q X \ (X = empty_table \ X = unit_table n)" + by (simp add: qtable_def table_empty) + +lemma qtable_empty_unit_table: + "qtable n {} R P empty_table \ qtable n {} R (\v. \ P v) (unit_table n)" + by (auto intro: qtable_unit_table simp add: qtable_empty_iff) + +lemma qtable_unit_empty_table: + "qtable n {} R P (unit_table n) \ qtable n {} R (\v. \ P v) empty_table" + by (auto intro!: qtable_empty elim: in_qtableE simp add: wf_tuple_empty unit_table_def) + +lemma qtable_nonempty_empty_table: + "qtable n {} R P X \ x \ X \ qtable n {} R (\v. \ P v) empty_table" + by (frule nullary_qtable_cases) (auto dest: qtable_unit_empty_table) + + +lemma qtable_r\_strict: + assumes "safe_regex Past Strict (from_mregex mr \s)" "ok (length \s) mr" "A = fv_regex (from_mregex mr \s)" + and "list_all2 (\\ rel. qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) i \) rel) \s rels" + shows "qtable n A (mem_restr R) (\v. Regex.eps (Formula.sat \ V (map the v)) i (from_mregex mr \s)) (r\_strict n rels mr)" + using assms +proof (hypsubst, induct Past Strict "from_mregex mr \s" arbitrary: mr rule: safe_regex_induct) + case (Skip n) + then show ?case + by (cases mr) (auto simp: qtable_empty_iff qtable_unit_table split: if_splits) +next + case (Test \) + then show ?case + by (cases mr) (auto simp: list_all2_conv_all_nth qtable_empty_unit_table + dest!: qtable_nonempty_empty_table split: if_splits) +next + case (Plus r s) + then show ?case + by (cases mr) (fastforce intro: qtable_union split: if_splits)+ +next + case (TimesP r s) + then show ?case + by (cases mr) (auto intro: qtable_cong[OF qtable_\_lax] split: if_splits)+ +next + case (Star r) + then show ?case + by (cases mr) (auto simp: qtable_unit_table split: if_splits) +qed + +lemma qtable_l\_strict: + assumes "safe_regex Futu Strict (from_mregex mr \s)" "ok (length \s) mr" "A = fv_regex (from_mregex mr \s)" + and "list_all2 (\\ rel. qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) i \) rel) \s rels" + shows "qtable n A (mem_restr R) (\v. Regex.eps (Formula.sat \ V (map the v)) i (from_mregex mr \s)) (l\_strict n rels mr)" + using assms +proof (hypsubst, induct Futu Strict "from_mregex mr \s" arbitrary: mr rule: safe_regex_induct) + case (Skip n) + then show ?case + by (cases mr) (auto simp: qtable_empty_iff qtable_unit_table split: if_splits) +next + case (Test \) + then show ?case + by (cases mr) (auto simp: list_all2_conv_all_nth qtable_empty_unit_table + dest!: qtable_nonempty_empty_table split: if_splits) +next + case (Plus r s) + then show ?case + by (cases mr) (fastforce intro: qtable_union split: if_splits)+ +next + case (TimesF r s) + then show ?case + by (cases mr) (auto intro: qtable_cong[OF qtable_\_lax] split: if_splits)+ +next + case (Star r) + then show ?case + by (cases mr) (auto simp: qtable_unit_table split: if_splits) +qed + +lemma rtranclp_False: "(\i j. False)\<^sup>*\<^sup>* = (=)" +proof - + have "(\i j. False)\<^sup>*\<^sup>* i j \ i = j" for i j :: 'a + by (induct i j rule: rtranclp.induct) auto + then show ?thesis + by (auto intro: exI[of _ 0]) +qed + +inductive ok_rctxt for \s where + "ok_rctxt \s id id" +| "ok_rctxt \s \ \' \ ok_rctxt \s (\t. \ (MTimes mr t)) (\t. \' (Regex.Times (from_mregex mr \s) t))" + +lemma ok_rctxt_swap: "ok_rctxt \s \ \' \ from_mregex (\ mr) \s = \' (from_mregex mr \s)" + by (induct \ \' arbitrary: mr rule: ok_rctxt.induct) auto + +lemma ok_rctxt_cong: "ok_rctxt \s \ \' \ Regex.match (Formula.sat \ V v) r = Regex.match (Formula.sat \ V v) s \ + Regex.match (Formula.sat \ V v) (\' r) i j = Regex.match (Formula.sat \ V v) (\' s) i j" + by (induct \ \' arbitrary: r s rule: ok_rctxt.induct) simp_all + +lemma qtable_r\\: + assumes "ok (length \s) mr" "fv_regex (from_mregex mr \s) \ A" + and "list_all2 (\\ rel. qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) j \) rel) \s rels" + and "ok_rctxt \s \ \'" + and "\ms \ \ ` RPD mr. qtable n A (mem_restr R) (\v. Q (map the v) (from_mregex ms \s)) (lookup rel ms)" + shows "qtable n A (mem_restr R) + (\v. \s \ Regex.rpd\ \' (Formula.sat \ V (map the v)) j (from_mregex mr \s). Q (map the v) s) + (r\ \ rel rels mr)" + using assms +proof (induct mr arbitrary: \ \') + case MSkip + then show ?case + by (auto simp: rtranclp_False ok_rctxt_swap qtable_empty_iff + elim!: qtable_cong[OF _ _ ok_rctxt_cong[of _ \ \']] split: nat.splits) +next + case (MPlus mr1 mr2) + from MPlus(3-7) show ?case + by (auto intro!: qtable_union[OF MPlus(1,2)]) +next + case (MTimes mr1 mr2) + from MTimes(3-7) show ?case + by (auto intro!: qtable_union[OF MTimes(2) qtable_\_lax[OF _ _ _ MTimes(1)]] + elim!: ok_rctxt.intros(2) simp: MTimesL_def Ball_def) +next + case (MStar mr) + from MStar(2-6) show ?case + by (auto intro!: qtable_cong[OF MStar(1)] intro: ok_rctxt.intros simp: MTimesL_def Ball_def) +qed (auto simp: qtable_empty_iff) + +lemmas qtable_r\ = qtable_r\\[OF _ _ _ ok_rctxt.intros(1), unfolded rpd\_rpd image_id id_apply] + +inductive ok_lctxt for \s where + "ok_lctxt \s id id" +| "ok_lctxt \s \ \' \ ok_lctxt \s (\t. \ (MTimes t mr)) (\t. \' (Regex.Times t (from_mregex mr \s)))" + +lemma ok_lctxt_swap: "ok_lctxt \s \ \' \ from_mregex (\ mr) \s = \' (from_mregex mr \s)" + by (induct \ \' arbitrary: mr rule: ok_lctxt.induct) auto + +lemma ok_lctxt_cong: "ok_lctxt \s \ \' \ Regex.match (Formula.sat \ V v) r = Regex.match (Formula.sat \ V v) s \ + Regex.match (Formula.sat \ V v) (\' r) i j = Regex.match (Formula.sat \ V v) (\' s) i j" + by (induct \ \' arbitrary: r s rule: ok_lctxt.induct) simp_all + +lemma qtable_l\\: + assumes "ok (length \s) mr" "fv_regex (from_mregex mr \s) \ A" + and "list_all2 (\\ rel. qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) j \) rel) \s rels" + and "ok_lctxt \s \ \'" + and "\ms \ \ ` LPD mr. qtable n A (mem_restr R) (\v. Q (map the v) (from_mregex ms \s)) (lookup rel ms)" + shows "qtable n A (mem_restr R) + (\v. \s \ Regex.lpd\ \' (Formula.sat \ V (map the v)) j (from_mregex mr \s). Q (map the v) s) + (l\ \ rel rels mr)" + using assms +proof (induct mr arbitrary: \ \') + case MSkip + then show ?case + by (auto simp: rtranclp_False ok_lctxt_swap qtable_empty_iff + elim!: qtable_cong[OF _ _ ok_rctxt_cong[of _ \ \']] split: nat.splits) +next + case (MPlus mr1 mr2) + from MPlus(3-7) show ?case + by (auto intro!: qtable_union[OF MPlus(1,2)]) +next + case (MTimes mr1 mr2) + from MTimes(3-7) show ?case + by (auto intro!: qtable_union[OF MTimes(1) qtable_\_lax[OF _ _ _ MTimes(2)]] + elim!: ok_lctxt.intros(2) simp: MTimesR_def Ball_def) +next + case (MStar mr) + from MStar(2-6) show ?case + by (auto intro!: qtable_cong[OF MStar(1)] intro: ok_lctxt.intros simp: MTimesR_def Ball_def) +qed (auto simp: qtable_empty_iff) + +lemmas qtable_l\ = qtable_l\\[OF _ _ _ ok_lctxt.intros(1), unfolded lpd\_lpd image_id id_apply] + +lemma RPD_fv_regex_le: + "ms \ RPD mr \ fv_regex (from_mregex ms \s) \ fv_regex (from_mregex mr \s)" + by (induct mr arbitrary: ms) (auto simp: MTimesL_def split: nat.splits)+ + +lemma RPD_safe: "safe_regex Past g (from_mregex mr \s) \ + ms \ RPD mr \ safe_regex Past g (from_mregex ms \s)" +proof (induct Past g "from_mregex mr \s" arbitrary: mr ms rule: safe_regex_induct) + case Skip + then show ?case + by (cases mr) (auto split: nat.splits) +next + case (Test g \) + then show ?case + by (cases mr) auto +next + case (Plus g r s mrs) + then show ?case + proof (cases mrs) + case (MPlus mr ms) + with Plus(3-5) show ?thesis + by (auto dest!: Plus(1,2)) + qed auto +next + case (TimesP g r s mrs) + then show ?case + proof (cases mrs) + case (MTimes mr ms) + with TimesP(3-5) show ?thesis + by (cases g) (auto 0 4 simp: MTimesL_def dest: RPD_fv_regex_le TimesP(1,2)) + qed auto +next + case (Star g r) + then show ?case + proof (cases mr) + case (MStar x6) + with Star(2-4) show ?thesis + by (cases g) (auto 0 4 simp: MTimesL_def dest: RPD_fv_regex_le + elim!: safe_cosafe[rotated] dest!: Star(1)) + qed auto +qed + +lemma RPDi_safe: "safe_regex Past g (from_mregex mr \s) \ + ms \ RPDi n mr ==> safe_regex Past g (from_mregex ms \s)" + by (induct n arbitrary: ms mr) (auto dest: RPD_safe) + +lemma RPDs_safe: "safe_regex Past g (from_mregex mr \s) \ + ms \ RPDs mr ==> safe_regex Past g (from_mregex ms \s)" + unfolding RPDs_def by (auto dest: RPDi_safe) + +lemma RPD_safe_fv_regex: "safe_regex Past Strict (from_mregex mr \s) \ + ms \ RPD mr \ fv_regex (from_mregex ms \s) = fv_regex (from_mregex mr \s)" +proof (induct Past Strict "from_mregex mr \s" arbitrary: mr rule: safe_regex_induct) + case (Skip n) + then show ?case + by (cases mr) (auto split: nat.splits) +next + case (Test \) + then show ?case + by (cases mr) auto +next + case (Plus r s) + then show ?case + by (cases mr) auto +next + case (TimesP r s) + then show ?case + by (cases mr) (auto 0 3 simp: MTimesL_def dest: RPD_fv_regex_le split: modality.splits) +next + case (Star r) + then show ?case + by (cases mr) (auto 0 3 simp: MTimesL_def dest: RPD_fv_regex_le) +qed + +lemma RPDi_safe_fv_regex: "safe_regex Past Strict (from_mregex mr \s) \ + ms \ RPDi n mr ==> fv_regex (from_mregex ms \s) = fv_regex (from_mregex mr \s)" + by (induct n arbitrary: ms mr) (auto 5 0 dest: RPD_safe_fv_regex RPD_safe) + +lemma RPDs_safe_fv_regex: "safe_regex Past Strict (from_mregex mr \s) \ + ms \ RPDs mr ==> fv_regex (from_mregex ms \s) = fv_regex (from_mregex mr \s)" + unfolding RPDs_def by (auto dest: RPDi_safe_fv_regex) + +lemma RPD_ok: "ok m mr \ ms \ RPD mr \ ok m ms" +proof (induct mr arbitrary: ms) + case (MPlus mr1 mr2) + from MPlus(3,4) show ?case + by (auto elim: MPlus(1,2)) +next + case (MTimes mr1 mr2) + from MTimes(3,4) show ?case + by (auto elim: MTimes(1,2) simp: MTimesL_def) +next + case (MStar mr) + from MStar(2,3) show ?case + by (auto elim: MStar(1) simp: MTimesL_def) +qed (auto split: nat.splits) + +lemma RPDi_ok: "ok m mr \ ms \ RPDi n mr \ ok m ms" + by (induct n arbitrary: ms mr) (auto intro: RPD_ok) + +lemma RPDs_ok: "ok m mr \ ms \ RPDs mr \ ok m ms" + unfolding RPDs_def by (auto intro: RPDi_ok) + +lemma LPD_fv_regex_le: + "ms \ LPD mr \ fv_regex (from_mregex ms \s) \ fv_regex (from_mregex mr \s)" + by (induct mr arbitrary: ms) (auto simp: MTimesR_def split: nat.splits)+ + +lemma LPD_safe: "safe_regex Futu g (from_mregex mr \s) \ + ms \ LPD mr ==> safe_regex Futu g (from_mregex ms \s)" +proof (induct Futu g "from_mregex mr \s" arbitrary: mr ms rule: safe_regex_induct) + case Skip + then show ?case + by (cases mr) (auto split: nat.splits) +next + case (Test g \) + then show ?case + by (cases mr) auto +next + case (Plus g r s mrs) + then show ?case + proof (cases mrs) + case (MPlus mr ms) + with Plus(3-5) show ?thesis + by (auto dest!: Plus(1,2)) + qed auto +next + case (TimesF g r s mrs) + then show ?case + proof (cases mrs) + case (MTimes mr ms) + with TimesF(3-5) show ?thesis + by (cases g) (auto 0 4 simp: MTimesR_def dest: LPD_fv_regex_le split: modality.splits dest: TimesF(1,2)) + qed auto +next + case (Star g r) + then show ?case + proof (cases mr) + case (MStar x6) + with Star(2-4) show ?thesis + by (cases g) (auto 0 4 simp: MTimesR_def dest: LPD_fv_regex_le + elim!: safe_cosafe[rotated] dest!: Star(1)) + qed auto +qed + +lemma LPDi_safe: "safe_regex Futu g (from_mregex mr \s) \ + ms \ LPDi n mr ==> safe_regex Futu g (from_mregex ms \s)" + by (induct n arbitrary: ms mr) (auto dest: LPD_safe) + +lemma LPDs_safe: "safe_regex Futu g (from_mregex mr \s) \ + ms \ LPDs mr ==> safe_regex Futu g (from_mregex ms \s)" + unfolding LPDs_def by (auto dest: LPDi_safe) + +lemma LPD_safe_fv_regex: "safe_regex Futu Strict (from_mregex mr \s) \ + ms \ LPD mr ==> fv_regex (from_mregex ms \s) = fv_regex (from_mregex mr \s)" +proof (induct Futu Strict "from_mregex mr \s" arbitrary: mr rule: safe_regex_induct) + case Skip + then show ?case + by (cases mr) (auto split: nat.splits) +next + case (Test \) + then show ?case + by (cases mr) auto +next + case (Plus r s) + then show ?case + by (cases mr) auto +next + case (TimesF r s) + then show ?case + by (cases mr) (auto 0 3 simp: MTimesR_def dest: LPD_fv_regex_le split: modality.splits) +next + case (Star r) + then show ?case + by (cases mr) (auto 0 3 simp: MTimesR_def dest: LPD_fv_regex_le) +qed + +lemma LPDi_safe_fv_regex: "safe_regex Futu Strict (from_mregex mr \s) \ + ms \ LPDi n mr ==> fv_regex (from_mregex ms \s) = fv_regex (from_mregex mr \s)" + by (induct n arbitrary: ms mr) (auto 5 0 dest: LPD_safe_fv_regex LPD_safe) + +lemma LPDs_safe_fv_regex: "safe_regex Futu Strict (from_mregex mr \s) \ + ms \ LPDs mr ==> fv_regex (from_mregex ms \s) = fv_regex (from_mregex mr \s)" + unfolding LPDs_def by (auto dest: LPDi_safe_fv_regex) + +lemma LPD_ok: "ok m mr \ ms \ LPD mr \ ok m ms" +proof (induct mr arbitrary: ms) + case (MPlus mr1 mr2) + from MPlus(3,4) show ?case + by (auto elim: MPlus(1,2)) +next + case (MTimes mr1 mr2) + from MTimes(3,4) show ?case + by (auto elim: MTimes(1,2) simp: MTimesR_def) +next + case (MStar mr) + from MStar(2,3) show ?case + by (auto elim: MStar(1) simp: MTimesR_def) +qed (auto split: nat.splits) + +lemma LPDi_ok: "ok m mr \ ms \ LPDi n mr \ ok m ms" + by (induct n arbitrary: ms mr) (auto intro: LPD_ok) + +lemma LPDs_ok: "ok m mr \ ms \ LPDs mr \ ok m ms" + unfolding LPDs_def by (auto intro: LPDi_ok) + +lemma update_matchP: + assumes pre: "wf_matchP_aux \ V n R I r aux ne" + and safe: "safe_regex Past Strict r" + and mr: "to_mregex r = (mr, \s)" + and mrs: "mrs = sorted_list_of_set (RPDs mr)" + and qtables: "list_all2 (\\ rel. qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) ne \) rel) \s rels" + and result_eq: "(rel, aux') = update_matchP n I mr mrs rels (\ \ ne) aux" + shows "wf_matchP_aux \ V n R I r aux' (Suc ne)" + and "qtable n (Formula.fv_regex r) (mem_restr R) (\v. Formula.sat \ V (map the v) ne (Formula.MatchP I r)) rel" +proof - + let ?wf_tuple = "\v. wf_tuple n (Formula.fv_regex r) v" + let ?update = "\rel t. mrtabulate mrs (\mr. + r\ id rel rels mr \ (if t = \ \ ne then r\_strict n rels mr else {}))" + note sat.simps[simp del] + + define aux0 where "aux0 = [(t, ?update rel t). (t, rel) \ aux, enat (\ \ ne - t) \ right I]" + have sorted_aux0: "sorted_wrt (\x y. fst x > fst y) aux0" + using pre[unfolded wf_matchP_aux_def, THEN conjunct1] + unfolding aux0_def + by (induction aux) (auto simp add: sorted_wrt_append) + { fix ms + assume "ms \ RPDs mr" + then have "fv_regex (from_mregex ms \s) = fv_regex r" + "safe_regex Past Strict (from_mregex ms \s)" "ok (length \s) ms" "RPD ms \ RPDs mr" + using safe RPDs_safe RPDs_safe_fv_regex mr from_mregex_to_mregex RPDs_ok to_mregex_ok RPDs_trans + by fastforce+ + } note * = this + have **: "\ \ ne - (\ \ i + \ \ ne - \ \ (ne - Suc 0)) = \ \ (ne - Suc 0) - \ \ i" for i + by (metis (no_types, lifting) Nat.diff_diff_right \_mono add.commute add_diff_cancel_left diff_le_self le_add2 order_trans) + have ***: "\ \ i = \ \ ne" + if "\ \ ne \ \ \ i" "\ \ i \ \ \ (ne - Suc 0)" "ne > 0" for i + by (metis (no_types, lifting) Suc_pred \_mono diff_le_self le_\_less le_antisym not_less_eq that) + then have in_aux0_1: "(t, X) \ set aux0 \ ne \ 0 \ t \ \ \ ne \ \ \ ne - t \ right I \ + (\i. \ \ i = t) \ + (\ms\RPDs mr. qtable n (fv_regex r) (mem_restr R) (\v. Formula.sat \ V (map the v) ne + (Formula.MatchP (point (\ \ ne - t)) (from_mregex ms \s))) (lookup X ms))" for t X + unfolding aux0_def using safe mr mrs + by (auto simp: lookup_tabulate map_of_map_restrict restrict_map_def finite_RPDs * ** RPDs_trans diff_le_mono2 + intro!: sat_MatchP_rec[of \ _ _ ne, THEN iffD2] + qtable_union[OF qtable_r\[OF _ _ qtables] qtable_r\_strict[OF _ _ _ qtables], + of ms "fv_regex r" "\v r. Formula.sat \ V v (ne - Suc 0) (Formula.MatchP (point 0) r)" _ ms for ms] + qtable_cong[OF qtable_r\[OF _ _ qtables], + of ms "fv_regex r" "\v r. Formula.sat \ V v (ne - Suc 0) (Formula.MatchP (point (\ \ (ne - Suc 0) - \ \ i)) r)" + _ _ "(\v. Formula.sat \ V (map the v) ne (Formula.MatchP (point (\ \ ne - \ \ i)) (from_mregex ms \s)))" for ms i] + dest!: assms(1)[unfolded wf_matchP_aux_def, THEN conjunct2, THEN conjunct1, rule_format] + sat_MatchP_rec["of" \ _ _ ne, THEN iffD1] + elim!: bspec order.trans[OF _ \_mono] bexI[rotated] split: option.splits if_splits) (* slow 7 sec *) + then have in_aux0_le_\: "(t, X) \ set aux0 \ t \ \ \ ne" for t X + by (meson \_mono diff_le_self le_trans) + have in_aux0_2: "ne \ 0 \ t \ \ \ (ne-1) \ \ \ ne - t \ right I \ \i. \ \ i = t \ + \X. (t, X) \ set aux0" for t + proof - + fix t + assume "ne \ 0" "t \ \ \ (ne-1)" "\ \ ne - t \ right I" "\i. \ \ i = t" + then obtain X where "(t, X) \ set aux" + by (atomize_elim, intro assms(1)[unfolded wf_matchP_aux_def, THEN conjunct2, THEN conjunct2, rule_format]) + (auto simp: gr0_conv_Suc elim!: order_trans[rotated] intro!: diff_le_mono \_mono) + with \\ \ ne - t \ right I\ have "(t, ?update X t) \ set aux0" + unfolding aux0_def by (auto simp: id_def elim!: bexI[rotated] intro!: exI[of _ X]) + then show "\X. (t, X) \ set aux0" + by blast + qed + have aux0_Nil: "aux0 = [] \ ne = 0 \ ne \ 0 \ (\t. t \ \ \ (ne-1) \ \ \ ne - t \ right I \ + (\i. \ \ i = t))" + using in_aux0_2 by (cases "ne = 0") (auto) + + have aux'_eq: "aux' = (case aux0 of + [] \ [(\ \ ne, mrtabulate mrs (r\_strict n rels))] + | x # aux' \ (if fst x = \ \ ne then x # aux' + else (\ \ ne, mrtabulate mrs (r\_strict n rels)) # x # aux'))" + using result_eq unfolding aux0_def update_matchP_def Let_def by simp + have sorted_aux': "sorted_wrt (\x y. fst x > fst y) aux'" + unfolding aux'_eq + using sorted_aux0 in_aux0_le_\ by (cases aux0) (fastforce)+ + + have in_aux'_1: "t \ \ \ ne \ \ \ ne - t \ right I \ (\i. \ \ i = t) \ + (\ms\RPDs mr. qtable n (Formula.fv_regex r) (mem_restr R) (\v. + Formula.sat \ V (map the v) ne (Formula.MatchP (point (\ \ ne - t)) (from_mregex ms \s))) (lookup X ms))" + if aux': "(t, X) \ set aux'" for t X + proof (cases aux0) + case Nil + with aux' show ?thesis + unfolding aux'_eq using safe mrs qtables aux0_Nil * + by (auto simp: zero_enat_def[symmetric] sat_MatchP_rec[where i=ne] + lookup_tabulate finite_RPDs split: option.splits + intro!: qtable_cong[OF qtable_r\_strict] + dest: spec[of _ "\ \ (ne-1)"]) + next + case (Cons a as) + show ?thesis + proof (cases "t = \ \ ne") + case t: True + show ?thesis + proof (cases "fst a = \ \ ne") + case True + with aux' Cons t have "X = snd a" + unfolding aux'_eq using sorted_aux0 by auto + moreover from in_aux0_1[of "fst a" "snd a"] Cons have "ne \ 0" + "fst a \ \ \ ne" "\ \ ne - fst a \ right I" "\i. \ \ i = fst a" + "\ms \ RPDs mr. qtable n (fv_regex r) (mem_restr R) (\v. Formula.sat \ V (map the v) ne + (Formula.MatchP (point (\ \ ne - fst a)) (from_mregex ms \s))) (lookup (snd a) ms)" + by auto + ultimately show ?thesis using t True + by auto + next + case False + with aux' Cons t have "X = mrtabulate mrs (r\_strict n rels)" + unfolding aux'_eq using sorted_aux0 in_aux0_le_\[of "fst a" "snd a"] by auto + with aux' Cons t False show ?thesis + unfolding aux'_eq using safe mrs qtables * in_aux0_2[of "\ \ (ne-1)"] in_aux0_le_\[of "fst a" "snd a"] sorted_aux0 + by (auto simp: sat_MatchP_rec[where i=ne] zero_enat_def[symmetric] enat_0_iff not_le + lookup_tabulate finite_RPDs split: option.splits + intro!: qtable_cong[OF qtable_r\_strict] dest!: le_\_less meta_mp) + qed + next + case False + with aux' Cons have "(t, X) \ set aux0" + unfolding aux'_eq by (auto split: if_splits) + then have "ne \ 0" "t \ \ \ ne" "\ \ ne - t \ right I" "\i. \ \ i = t" + "\ms \ RPDs mr. qtable n (fv_regex r) (mem_restr R) (\v. Formula.sat \ V (map the v) ne + (Formula.MatchP (point (\ \ ne - t)) (from_mregex ms \s))) (lookup X ms)" + using in_aux0_1 by blast+ + with False aux' Cons show ?thesis + unfolding aux'_eq by auto + qed + qed + + have in_aux'_2: "\X. (t, X) \ set aux'" if "t \ \ \ ne" "\ \ ne - t \ right I" "\i. \ \ i = t" for t + proof (cases "t = \ \ ne") + case True + then show ?thesis + proof (cases aux0) + case Nil + with True show ?thesis unfolding aux'_eq by simp + next + case (Cons a as) + with True show ?thesis unfolding aux'_eq using eq_fst_iff[of t a] + by (cases "fst a = \ \ ne") auto + qed + next + case False + with that have "ne \ 0" + using le_\_less neq0_conv by blast + moreover from False that have "t \ \ \ (ne-1)" + by (metis One_nat_def Suc_leI Suc_pred \_mono diff_is_0_eq' order.antisym neq0_conv not_le) + ultimately obtain X where "(t, X) \ set aux0" using \\ \ ne - t \ right I\ \\i. \ \ i = t\ + by atomize_elim (auto intro!: in_aux0_2) + then show ?thesis unfolding aux'_eq using False + by (auto intro: exI[of _ X] split: list.split) + qed + + show "wf_matchP_aux \ V n R I r aux' (Suc ne)" + unfolding wf_matchP_aux_def using mr + by (auto dest: in_aux'_1 intro: sorted_aux' in_aux'_2) + + have rel_eq: "rel = foldr (\) [lookup rel mr. (t, rel) \ aux', left I \ \ \ ne - t] {}" + unfolding aux'_eq aux0_def + using result_eq by (simp add: update_matchP_def Let_def) + have rel_alt: "rel = (\(t, rel) \ set aux'. if left I \ \ \ ne - t then lookup rel mr else empty_table)" + unfolding rel_eq + by (auto elim!: in_foldr_UnE bexI[rotated] intro!: in_foldr_UnI) + show "qtable n (fv_regex r) (mem_restr R) (\v. Formula.sat \ V (map the v) ne (Formula.MatchP I r)) rel" + unfolding rel_alt + proof (rule qtable_Union[where Qi="\(t, X) v. + left I \ \ \ ne - t \ Formula.sat \ V (map the v) ne (Formula.MatchP (point (\ \ ne - t)) r)"], + goal_cases finite qtable equiv) + case (equiv v) + show ?case + proof (rule iffI, erule sat_MatchP_point, goal_cases left right) + case (left j) + then show ?case using in_aux'_2[of "\ \ j", OF _ _ exI, OF _ _ refl] by auto + next + case right + then show ?case by (auto elim!: sat_MatchP_pointD dest: in_aux'_1) + qed + qed (auto dest!: in_aux'_1 intro!: qtable_empty dest!: bspec[OF _ RPDs_refl] + simp: from_mregex_eq[OF safe mr]) +qed + +lemma length_update_until: "length (update_until args rel1 rel2 nt aux) = Suc (length aux)" + unfolding update_until_def by simp + +lemma wf_update_until_auxlist: + assumes pre: "wf_until_auxlist \ V n R pos \ I \ auxlist ne" + and qtable1: "qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) (ne + length auxlist) \) rel1" + and qtable2: "qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) (ne + length auxlist) \) rel2" + and fvi_subset: "Formula.fv \ \ Formula.fv \" + and args_ivl: "args_ivl args = I" + and args_n: "args_n args = n" + and args_pos: "args_pos args = pos" + shows "wf_until_auxlist \ V n R pos \ I \ (update_until args rel1 rel2 (\ \ (ne + length auxlist)) auxlist) ne" + unfolding wf_until_auxlist_def length_update_until + unfolding update_until_def list.rel_map add_Suc_right upt.simps eqTrueI[OF le_add1] if_True +proof (rule list_all2_appendI, unfold list.rel_map, goal_cases old new) + case old + show ?case + proof (rule list.rel_mono_strong[OF assms(1)[unfolded wf_until_auxlist_def]]; safe, goal_cases mono1 mono2) + case (mono1 i X Y v) + then show ?case + by (fastforce simp: args_ivl args_n args_pos sat_the_restrict less_Suc_eq + elim!: qtable_join[OF _ qtable1] qtable_union[OF _ qtable1]) + next + case (mono2 i X Y v) + then show ?case using fvi_subset + by (auto 0 3 simp: args_ivl args_n args_pos sat_the_restrict less_Suc_eq split: if_splits + elim!: qtable_union[OF _ qtable_join_fixed[OF qtable2]] + elim: qtable_cong[OF _ refl] intro: exI[of _ "ne + length auxlist"]) (* slow 8 sec*) + qed +next + case new + then show ?case + by (auto intro!: qtable_empty qtable1 qtable2[THEN qtable_cong] exI[of _ "ne + length auxlist"] + simp: args_ivl args_n args_pos less_Suc_eq zero_enat_def[symmetric]) +qed + +lemma (in muaux) wf_update_until: + assumes pre: "wf_until_aux \ V R args \ \ aux ne" + and qtable1: "qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) (ne + length_muaux args aux) \) rel1" + and qtable2: "qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) (ne + length_muaux args aux) \) rel2" + and fvi_subset: "Formula.fv \ \ Formula.fv \" + and args_ivl: "args_ivl args = I" + and args_n: "args_n args = n" + and args_L: "args_L args = Formula.fv \" + and args_R: "args_R args = Formula.fv \" + and args_pos: "args_pos args = pos" + shows "wf_until_aux \ V R args \ \ (add_new_muaux args rel1 rel2 (\ \ (ne + length_muaux args aux)) aux) ne \ + length_muaux args (add_new_muaux args rel1 rel2 (\ \ (ne + length_muaux args aux)) aux) = Suc (length_muaux args aux)" +proof - + from pre obtain cur auxlist where valid_aux: "valid_muaux args cur aux auxlist" and + cur: "cur = (if ne + length auxlist = 0 then 0 else \ \ (ne + length auxlist - 1))" and + pre_list: "wf_until_auxlist \ V n R pos \ I \ auxlist ne" + unfolding wf_until_aux_def args_ivl args_n args_pos by auto + have length_aux: "length_muaux args aux = length auxlist" + using valid_length_muaux[OF valid_aux] . + define nt where "nt \ \ \ (ne + length_muaux args aux)" + have nt_mono: "cur \ nt" + unfolding cur nt_def length_aux by simp + define auxlist' where "auxlist' \ update_until args rel1 rel2 (\ \ (ne + length auxlist)) auxlist" + have length_auxlist': "length auxlist' = Suc (length auxlist)" + unfolding auxlist'_def by (auto simp add: length_update_until) + have tab1: "table (args_n args) (args_L args) rel1" + using qtable1 unfolding args_n[symmetric] args_L[symmetric] by (auto simp add: qtable_def) + have tab2: "table (args_n args) (args_R args) rel2" + using qtable2 unfolding args_n[symmetric] args_R[symmetric] by (auto simp add: qtable_def) + have fv_sub: "fv \ \ fv \" + using pre unfolding wf_until_aux_def by auto + moreover have valid_add_new_auxlist: "valid_muaux args nt (add_new_muaux args rel1 rel2 nt aux) auxlist'" + using valid_add_new_muaux[OF valid_aux tab1 tab2 nt_mono] + unfolding auxlist'_def nt_def length_aux . + moreover have "length_muaux args (add_new_muaux args rel1 rel2 nt aux) = Suc (length_muaux args aux)" + using valid_length_muaux[OF valid_add_new_auxlist] unfolding length_auxlist' length_aux[symmetric] . + moreover have "wf_until_auxlist \ V n R pos \ I \ auxlist' ne" + using wf_update_until_auxlist[OF pre_list qtable1[unfolded length_aux] qtable2[unfolded length_aux] fv_sub args_ivl args_n args_pos] + unfolding auxlist'_def . + moreover have "\ \ (ne + length auxlist) = (if ne + length auxlist' = 0 then 0 else \ \ (ne + length auxlist' - 1))" + unfolding cur length_auxlist' by auto + ultimately show ?thesis + unfolding wf_until_aux_def nt_def length_aux args_ivl args_n args_pos by fast +qed + +lemma length_update_matchF_base: + "length (fst (update_matchF_base I mr mrs nt entry st)) = Suc 0" + by (auto simp: Let_def update_matchF_base_def) + +lemma length_update_matchF_step: + "length (fst (update_matchF_step I mr mrs nt entry st)) = Suc (length (fst st))" + by (auto simp: Let_def update_matchF_step_def split: prod.splits) + +lemma length_foldr_update_matchF_step: + "length (fst (foldr (update_matchF_step I mr mrs nt) aux base)) = length aux + length (fst base)" + by (induct aux arbitrary: base) (auto simp: Let_def length_update_matchF_step) + +lemma length_update_matchF: "length (update_matchF n I mr mrs rels nt aux) = Suc (length aux)" + unfolding update_matchF_def update_matchF_base_def length_foldr_update_matchF_step + by (auto simp: Let_def) + +lemma wf_update_matchF_base_invar: + assumes safe: "safe_regex Futu Strict r" + and mr: "to_mregex r = (mr, \s)" + and mrs: "mrs = sorted_list_of_set (LPDs mr)" + and qtables: "list_all2 (\\ rel. qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) j \) rel) \s rels" + shows "wf_matchF_invar \ V n R I r (update_matchF_base n I mr mrs rels (\ \ j)) j" +proof - + have from_mregex: "from_mregex mr \s = r" + using safe mr using from_mregex_eq by blast + { fix ms + assume "ms \ LPDs mr" + then have "fv_regex (from_mregex ms \s) = fv_regex r" + "safe_regex Futu Strict (from_mregex ms \s)" "ok (length \s) ms" "LPD ms \ LPDs mr" + using safe LPDs_safe LPDs_safe_fv_regex mr from_mregex_to_mregex LPDs_ok to_mregex_ok LPDs_trans + by fastforce+ + } note * = this + show ?thesis + unfolding wf_matchF_invar_def wf_matchF_aux_def update_matchF_base_def mr prod.case Let_def mrs + using safe + by (auto simp: * from_mregex qtables qtable_empty_iff zero_enat_def[symmetric] + lookup_tabulate finite_LPDs eps_match less_Suc_eq LPDs_refl + intro!: qtable_cong[OF qtable_l\_strict[where \s=\s]] intro: qtables exI[of _ j] + split: option.splits) +qed + +lemma Un_empty_table[simp]: "rel \ empty_table = rel" "empty_table \ rel = rel" + unfolding empty_table_def by auto + +lemma wf_matchF_invar_step: + assumes wf: "wf_matchF_invar \ V n R I r st (Suc i)" + and safe: "safe_regex Futu Strict r" + and mr: "to_mregex r = (mr, \s)" + and mrs: "mrs = sorted_list_of_set (LPDs mr)" + and qtables: "list_all2 (\\ rel. qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) i \) rel) \s rels" + and rel: "qtable n (Formula.fv_regex r) (mem_restr R) (\v. (\j. i \ j \ j < i + length (fst st) \ mem (\ \ j - \ \ i) I \ + Regex.match (Formula.sat \ V (map the v)) r i j)) rel" + and entry: "entry = (\ \ i, rels, rel)" + and nt: "nt = \ \ (i + length (fst st))" + shows "wf_matchF_invar \ V n R I r (update_matchF_step I mr mrs nt entry st) i" +proof - + have from_mregex: "from_mregex mr \s = r" + using safe mr using from_mregex_eq by blast + { fix ms + assume "ms \ LPDs mr" + then have "fv_regex (from_mregex ms \s) = fv_regex r" + "safe_regex Futu Strict (from_mregex ms \s)" "ok (length \s) ms" "LPD ms \ LPDs mr" + using safe LPDs_safe LPDs_safe_fv_regex mr from_mregex_to_mregex LPDs_ok to_mregex_ok LPDs_trans + by fastforce+ + } note * = this + { fix aux X ms + assume "st = (aux, X)" "ms \ LPDs mr" + with wf mr have "qtable n (fv_regex r) (mem_restr R) + (\v. Regex.match (Formula.sat \ V (map the v)) (from_mregex ms \s) i (i + length aux)) + (l\ (\x. x) X rels ms)" + by (intro qtable_cong[OF qtable_l\[where \s=\s and A="fv_regex r" and + Q="\v r. Regex.match (Formula.sat \ V v) r (Suc i) (i + length aux)", OF _ _ qtables]]) + (auto simp: wf_matchF_invar_def * LPDs_trans lpd_match[of i] elim!: bspec) + } note l\ = this + have "lookup (mrtabulate mrs f) ms = f ms" if "ms \ LPDs mr" for ms and f :: "mregex \ 'a table" + using that mrs by (fastforce simp: lookup_tabulate finite_LPDs split: option.splits)+ + then show ?thesis + using wf mr mrs entry nt LPDs_trans + by (auto 0 3 simp: Let_def wf_matchF_invar_def update_matchF_step_def wf_matchF_aux_def mr * LPDs_refl + list_all2_Cons1 append_eq_Cons_conv upt_eq_Cons_conv Suc_le_eq qtables + lookup_tabulate finite_LPDs id_def l\ from_mregex less_Suc_eq + intro!: qtable_union[OF rel l\] qtable_cong[OF rel] + intro: exI[of _ "i + length _"] + split: if_splits prod.splits) +qed + +lemma wf_update_matchF_invar: + assumes pre: "wf_matchF_aux \ V n R I r aux ne (length (fst st) - 1)" + and wf: "wf_matchF_invar \ V n R I r st (ne + length aux)" + and safe: "safe_regex Futu Strict r" + and mr: "to_mregex r = (mr, \s)" + and mrs: "mrs = sorted_list_of_set (LPDs mr)" + and j: "j = ne + length aux + length (fst st) - 1" + shows "wf_matchF_invar \ V n R I r (foldr (update_matchF_step I mr mrs (\ \ j)) aux st) ne" + using pre wf unfolding j +proof (induct aux arbitrary: ne) + case (Cons entry aux) + from Cons(1)[of "Suc ne"] Cons(2,3) show ?case + unfolding foldr.simps o_apply + by (intro wf_matchF_invar_step[where rels = "fst (snd entry)" and rel = "snd (snd entry)"]) + (auto simp: safe mr mrs wf_matchF_aux_def wf_matchF_invar_def list_all2_Cons1 append_eq_Cons_conv + Suc_le_eq upt_eq_Cons_conv length_foldr_update_matchF_step add.assoc split: if_splits) +qed simp + + +lemma wf_update_matchF: + assumes pre: "wf_matchF_aux \ V n R I r aux ne 0" + and safe: "safe_regex Futu Strict r" + and mr: "to_mregex r = (mr, \s)" + and mrs: "mrs = sorted_list_of_set (LPDs mr)" + and nt: "nt = \ \ (ne + length aux)" + and qtables: "list_all2 (\\ rel. qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) (ne + length aux) \) rel) \s rels" + shows "wf_matchF_aux \ V n R I r (update_matchF n I mr mrs rels nt aux) ne 0" + unfolding update_matchF_def using wf_update_matchF_base_invar[OF safe mr mrs qtables, of I] + unfolding nt + by (intro wf_update_matchF_invar[OF _ _ safe mr mrs, unfolded wf_matchF_invar_def split_beta, THEN conjunct2, THEN conjunct1]) + (auto simp: length_update_matchF_base wf_matchF_invar_def update_matchF_base_def Let_def pre) + +lemma wf_until_aux_Cons: "wf_until_auxlist \ V n R pos \ I \ (a # aux) ne \ + wf_until_auxlist \ V n R pos \ I \ aux (Suc ne)" + unfolding wf_until_auxlist_def + by (simp add: upt_conv_Cons del: upt_Suc cong: if_cong) + +lemma wf_matchF_aux_Cons: "wf_matchF_aux \ V n R I r (entry # aux) ne i \ + wf_matchF_aux \ V n R I r aux (Suc ne) i" + unfolding wf_matchF_aux_def + by (simp add: upt_conv_Cons del: upt_Suc cong: if_cong split: prod.splits) + +lemma wf_until_aux_Cons1: "wf_until_auxlist \ V n R pos \ I \ ((t, a1, a2) # aux) ne \ t = \ \ ne" + unfolding wf_until_auxlist_def + by (simp add: upt_conv_Cons del: upt_Suc) + +lemma wf_matchF_aux_Cons1: "wf_matchF_aux \ V n R I r ((t, rels, rel) # aux) ne i \ t = \ \ ne" + unfolding wf_matchF_aux_def + by (simp add: upt_conv_Cons del: upt_Suc split: prod.splits) + +lemma wf_until_aux_Cons3: "wf_until_auxlist \ V n R pos \ I \ ((t, a1, a2) # aux) ne \ + qtable n (Formula.fv \) (mem_restr R) (\v. (\j. ne \ j \ j < Suc (ne + length aux) \ mem (\ \ j - \ \ ne) I \ + Formula.sat \ V (map the v) j \ \ (\k\{ne.. V (map the v) k \ else \ Formula.sat \ V (map the v) k \))) a2" + unfolding wf_until_auxlist_def + by (simp add: upt_conv_Cons del: upt_Suc) + +lemma wf_matchF_aux_Cons3: "wf_matchF_aux \ V n R I r ((t, rels, rel) # aux) ne i \ + qtable n (Formula.fv_regex r) (mem_restr R) (\v. (\j. ne \ j \ j < Suc (ne + length aux + i) \ mem (\ \ j - \ \ ne) I \ + Regex.match (Formula.sat \ V (map the v)) r ne j)) rel" + unfolding wf_matchF_aux_def + by (simp add: upt_conv_Cons del: upt_Suc split: prod.splits) + +lemma upt_append: "a \ b \ b \ c \ [a.. ja'" "jb \ jb'" + shows "wf_mbuf2 i ja' jb' P Q (mbuf2_add xs ys buf)" + using assms unfolding wf_mbuf2_def + by (auto 0 3 simp: list_all2_append2 upt_append dest: list_all2_lengthD + intro: exI[where x="[i..j j'. [j..) js js'" + shows "wf_mbufn i js' Ps (mbufn_add xss buf)" + unfolding wf_mbufn_def list_all3_conv_all_nth +proof safe + show "length Ps = length js'" "length js' = length (mbufn_add xss buf)" + using assms unfolding wf_mbufn_def list_all3_conv_all_nth list_all2_conv_all_nth by auto +next + fix k assume k: "k < length Ps" + then show "i \ js' ! k" + using assms unfolding wf_mbufn_def list_all3_conv_all_nth list_all2_conv_all_nth + by (auto 0 4 dest: spec[of _ i]) + from k have " [i..i z. \x y. P i x \ Q i y \ z = f x y) [i.. xs = [] \ ys = []" + "list_all3 P xs [] zs \ xs = [] \ zs = []" + "list_all3 P [] ys zs \ ys = [] \ zs = []" + unfolding list_all3_conv_all_nth by auto + +lemma list_all3_Cons: + "list_all3 P xs ys (z # zs) \ (\x xs' y ys'. xs = x # xs' \ ys = y # ys' \ P x y z \ list_all3 P xs' ys' zs)" + "list_all3 P xs (y # ys) zs \ (\x xs' z zs'. xs = x # xs' \ zs = z # zs' \ P x y z \ list_all3 P xs' ys zs')" + "list_all3 P (x # xs) ys zs \ (\y ys' z zs'. ys = y # ys' \ zs = z # zs' \ P x y z \ list_all3 P xs ys' zs')" + unfolding list_all3_conv_all_nth + by (auto simp: length_Suc_conv Suc_length_conv nth_Cons split: nat.splits) + +lemma list_all3_mono_strong: "list_all3 P xs ys zs \ + (\x y z. x \ set xs \ y \ set ys \ z \ set zs \ P x y z \ Q x y z) \ + list_all3 Q xs ys zs" + by (induct xs ys zs rule: list_all3.induct) (auto intro: list_all3.intros) + +definition Mini where + "Mini i js = (if js = [] then i else Min (set js))" + +lemma wf_mbufn_in_set_Mini: + assumes "wf_mbufn i js Ps buf" + shows "[] \ set buf \ Mini i js = i" + unfolding in_set_conv_nth +proof (elim exE conjE) + fix k + have "i \ j" if "j \ set js" for j + using that assms unfolding wf_mbufn_def list_all3_conv_all_nth in_set_conv_nth by auto + moreover assume "k < length buf" "buf ! k = []" + ultimately show ?thesis using assms + unfolding Mini_def wf_mbufn_def list_all3_conv_all_nth + by (auto 0 4 dest!: spec[of _ k] intro: Min_eqI simp: in_set_conv_nth) +qed + +lemma wf_mbufn_notin_set: + assumes "wf_mbufn i js Ps buf" + shows "[] \ set buf \ j \ set js \ i < j" + using assms unfolding wf_mbufn_def list_all3_conv_all_nth + by (cases "i \ set js") (auto intro: le_neq_implies_less simp: in_set_conv_nth) + +lemma wf_mbufn_map_tl: + "wf_mbufn i js Ps buf \ [] \ set buf \ wf_mbufn (Suc i) js Ps (map tl buf)" + by (auto simp: wf_mbufn_def list_all3_map Suc_le_eq + dest: rel_funD[OF tl_transfer] elim!: list_all3_mono_strong le_neq_implies_less) + +lemma list_all3_list_all2I: "list_all3 (\x y z. Q x z) xs ys zs \ list_all2 Q xs zs" + by (induct xs ys zs rule: list_all3.induct) auto + +lemma mbuf2t_take_eqD: + assumes "mbuf2t_take f z buf nts = (z', buf', nts')" + and "wf_mbuf2 i ja jb P Q buf" + and "list_all2 R [i.. j" "jb \ j" + shows "wf_mbuf2 (min ja jb) ja jb P Q buf'" + and "list_all2 R [min ja jb.. set buf") + case True + from rec.prems(2) have "\j\set js. i \ j" + by (auto simp: in_set_conv_nth list_all3_conv_all_nth) + moreover from True rec.prems(2) have "i \ set js" + by (fastforce simp: in_set_conv_nth list_all3_conv_all_nth list_all2_iff) + ultimately have "Mini i js = i" + unfolding Mini_def + by (auto intro!: antisym[OF Min.coboundedI Min.boundedI]) + with rec.prems nonempty True show ?thesis by simp + next + case False + from nonempty rec.prems(2) have "Mini i js = Mini (Suc i) js" + unfolding Mini_def by auto + show ?thesis + unfolding \Mini i js = Mini (Suc i) js\ + proof (rule rec.IH) + show "\ (buf = [] \ [] \ set buf)" using nonempty False by simp + show "list_all3 (\P j xs. Suc i \ j \ list_all2 P [Suc i..k. k \ set js \ k \ j" + and "k = Mini (i + length nts) js" + shows "wf_mbufn k js Ps buf'" + and "list_all2 R [k.. []" + using that by (fastforce simp flip: length_greater_0_conv) + with 2 show ?case + using wf_mbufn_in_set_Mini[OF 2(2)] wf_mbufn_notin_set[OF 2(2)] + by (subst (asm) mbufnt_take.simps) (force simp: Mini_def wf_mbufn_def + dest!: IH(2)[rotated, OF _ wf_mbufn_map_tl[OF 2(2)] *] + split: if_splits prod.splits) +qed + +lemma mbuf2t_take_induct[consumes 5, case_names base step]: + assumes "mbuf2t_take f z buf nts = (z', buf', nts')" + and "wf_mbuf2 i ja jb P Q buf" + and "list_all2 R [i.. j" "jb \ j" + and "U i z" + and "\k x y t z. i \ k \ Suc k \ ja \ Suc k \ jb \ + P k x \ Q k y \ R k t \ U k z \ U (Suc k) (f x y t z)" + shows "U (min ja jb) z'" + using assms unfolding wf_mbuf2_def + by (induction f z buf nts arbitrary: i z' buf' nts' rule: mbuf2t_take.induct) + (auto simp add: list_all2_Cons2 upt_eq_Cons_conv less_eq_Suc_le min_absorb1 min_absorb2 + elim!: arg_cong2[of _ _ _ _ U, OF _ refl, THEN iffD1, rotated] split: prod.split) + +lemma list_all2_hdD: + assumes "list_all2 P [i.. []" + shows "P i (hd xs)" "i < j" + using assms unfolding list_all2_conv_all_nth + by (auto simp: hd_conv_nth intro: zero_less_diff[THEN iffD1] dest!: spec[of _ 0]) + +lemma mbufn_take_induct[consumes 3, case_names base step]: + assumes "mbufn_take f z buf = (z', buf')" + and "wf_mbufn i js Ps buf" + and "U i z" + and "\k xs z. i \ k \ Suc k \ Mini i js \ + list_all2 (\P x. P k x) Ps xs \ U k z \ U (Suc k) (f xs z)" + shows "U (Mini i js) z'" + using assms unfolding wf_mbufn_def +proof (induction f z buf arbitrary: i z' buf' rule: mbufn_take.induct) + case rec: (1 f z buf) + show ?case proof (cases "buf = []") + case True + with rec.prems show ?thesis unfolding Mini_def by simp + next + case nonempty: False + show ?thesis proof (cases "[] \ set buf") + case True + from rec.prems(2) have "\j\set js. i \ j" + by (auto simp: in_set_conv_nth list_all3_conv_all_nth) + moreover from True rec.prems(2) have "i \ set js" + by (fastforce simp: in_set_conv_nth list_all3_conv_all_nth list_all2_iff) + ultimately have "Mini i js = i" + unfolding Mini_def + by (auto intro!: antisym[OF Min.coboundedI Min.boundedI]) + with rec.prems nonempty True show ?thesis by simp + next + case False + with nonempty rec.prems(2) have more: "Suc i \ Mini i js" + using diff_is_0_eq not_le unfolding Mini_def + by (fastforce simp: in_set_conv_nth list_all3_conv_all_nth list_all2_iff) + then have "Mini i js = Mini (Suc i) js" unfolding Mini_def by auto + show ?thesis + unfolding \Mini i js = Mini (Suc i) js\ + proof (rule rec.IH) + show "\ (buf = [] \ [] \ set buf)" using nonempty False by simp + show "mbufn_take f (f (map hd buf) z) (map tl buf) = (z', buf')" + using nonempty False rec.prems by simp + show "list_all3 (\P j xs. Suc i \ j \ list_all2 P [Suc i..k xs z. Suc i \ k \ Suc k \ Mini (Suc i) js \ + list_all2 (\P. P k) Ps xs \ U k z \ U (Suc k) (f xs z)" + by (rule rec.prems(4)) (auto simp: Mini_def) + qed + qed + qed +qed + +lemma mbufnt_take_induct[consumes 5, case_names base step]: + assumes "mbufnt_take f z buf nts = (z', buf', nts')" + and "wf_mbufn i js Ps buf" + and "list_all2 R [i..k. k \ set js \ k \ j" + and "U i z" + and "\k xs t z. i \ k \ Suc k \ Mini j js \ + list_all2 (\P x. P k x) Ps xs \ R k t \ U k z \ U (Suc k) (f xs t z)" + shows "U (Mini (i + length nts) js) z'" + using assms +proof (induction f z buf nts arbitrary: i z' buf' nts' rule: mbufnt_take.induct) + case (1 f z buf nts) + then have *: "list_all2 R [Suc i.. []" "nts = []" + using that unfolding wf_mbufn_def using wf_mbufn_in_set_Mini[OF 1(3)] + by (fastforce simp: Mini_def list_all3_Cons neq_Nil_conv) + with 1(2-7) list_all2_hdD[OF 1(4)] show ?case + unfolding wf_mbufn_def using wf_mbufn_in_set_Mini[OF 1(3)] wf_mbufn_notin_set[OF 1(3)] + by (subst (asm) mbufnt_take.simps) + (auto simp add: Mini_def list.rel_map Suc_le_eq + elim!: arg_cong2[of _ _ _ _ U, OF _ refl, THEN iffD1, rotated] + list_all3_mono_strong[THEN list_all3_list_all2I[of _ _ js]] list_all2_hdD + dest!: 1(1)[rotated, OF _ wf_mbufn_map_tl[OF 1(3)] * _ 1(7)] split: prod.split if_splits) +qed + +lemma mbuf2_take_add': + assumes eq: "mbuf2_take f (mbuf2_add xs ys buf) = (zs, buf')" + and pre: "wf_mbuf2' \ P V j n R \ \ buf" + and rm: "rel_mapping (\) P P'" + and xs: "list_all2 (\i. qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) i \)) + [progress \ P \ j.. P' \ j'] xs" + and ys: "list_all2 (\i. qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) i \)) + [progress \ P \ j.. P' \ j'] ys" + and "j \ j'" + shows "wf_mbuf2' \ P' V j' n R \ \ buf'" + and "list_all2 (\i Z. \X Y. + qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) i \) X \ + qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) i \) Y \ + Z = f X Y) + [min (progress \ P \ j) (progress \ P \ j).. P' \ j') (progress \ P' \ j')] zs" + using pre rm unfolding wf_mbuf2'_def + by (force intro!: mbuf2_take_eqD[OF eq] wf_mbuf2_add[OF _ xs ys] progress_mono_gen[OF \j \ j'\ rm])+ + +lemma mbuf2t_take_add': + assumes eq: "mbuf2t_take f z (mbuf2_add xs ys buf) nts = (z', buf', nts')" + and bounded: "pred_mapping (\x. x \ j) P" "pred_mapping (\x. x \ j') P'" + and rm: "rel_mapping (\) P P'" + and pre_buf: "wf_mbuf2' \ P V j n R \ \ buf" + and pre_nts: "list_all2 (\i t. t = \ \ i) [min (progress \ P \ j) (progress \ P \ j)..i. qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) i \)) + [progress \ P \ j.. P' \ j'] xs" + and ys: "list_all2 (\i. qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) i \)) + [progress \ P \ j.. P' \ j'] ys" + and "j \ j'" + shows "wf_mbuf2' \ P' V j' n R \ \ buf'" + and "wf_ts \ P' j' \ \ nts'" + using pre_buf pre_nts bounded rm unfolding wf_mbuf2'_def wf_ts_def + by (auto intro!: mbuf2t_take_eqD[OF eq] wf_mbuf2_add[OF _ xs ys] progress_mono_gen[OF \j \ j'\ rm] + progress_le_gen) + +lemma ok_0_atms: "ok 0 mr \ regex.atms (from_mregex mr []) = {}" + by (induct mr) auto + +lemma ok_0_progress: "ok 0 mr \ progress_regex \ P (from_mregex mr []) j = j" + by (drule ok_0_atms) (auto simp: progress_regex_def) + +lemma atms_empty_atms: "safe_regex m g r \ atms r = {} \ regex.atms r = {}" + by (induct r rule: safe_regex_induct) (auto split: if_splits simp: cases_Neg_iff) + +lemma atms_empty_progress: "safe_regex m g r \ atms r = {} \ progress_regex \ P r j = j" + by (drule atms_empty_atms) (auto simp: progress_regex_def) + +lemma to_mregex_empty_progress: "safe_regex m g r \ to_mregex r = (mr, []) \ + progress_regex \ P r j = j" + using from_mregex_eq ok_0_progress to_mregex_ok atms_empty_atms by fastforce + +lemma progress_regex_le: "pred_mapping (\x. x \ j) P \ progress_regex \ P r j \ j" + by (auto intro!: progress_le_gen simp: Min_le_iff progress_regex_def) + +lemma Neg_acyclic: "formula.Neg x = x \ P" + by (induct x) auto + +lemma case_Neg_in_iff: "x \ (case y of formula.Neg \' \ {\'} | _ \ {}) \ y = formula.Neg x" + by (cases y) auto + +lemma atms_nonempty_progress: + "safe_regex m g r \ atms r \ {} \ (\\. progress \ P \ j) ` atms r = (\\. progress \ P \ j) ` regex.atms r" + by (frule atms_empty_atms; simp) + (auto 0 3 simp: atms_def image_iff case_Neg_in_iff elim!: disjE_Not2 dest: safe_regex_safe_formula) + +lemma to_mregex_nonempty_progress: "safe_regex m g r \ to_mregex r = (mr, \s) \ \s \ [] \ + progress_regex \ P r j = (MIN \\set \s. progress \ P \ j)" + using atms_nonempty_progress to_mregex_ok unfolding progress_regex_def by fastforce + +lemma to_mregex_progress: "safe_regex m g r \ to_mregex r = (mr, \s) \ + progress_regex \ P r j = (if \s = [] then j else (MIN \\set \s. progress \ P \ j))" + using to_mregex_nonempty_progress to_mregex_empty_progress unfolding progress_regex_def by auto + +lemma mbufnt_take_add': + assumes eq: "mbufnt_take f z (mbufn_add xss buf) nts = (z', buf', nts')" + and bounded: "pred_mapping (\x. x \ j) P" "pred_mapping (\x. x \ j') P'" + and rm: "rel_mapping (\) P P'" + and safe: "safe_regex m g r" + and mr: "to_mregex r = (mr, \s)" + and pre_buf: "wf_mbufn' \ P V j n R r buf" + and pre_nts: "list_all2 (\i t. t = \ \ i) [progress_regex \ P r j..\ i. qtable n (fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) i \)) \s) + (map2 upt (map (\\. progress \ P \ j) \s) (map (\\. progress \ P' \ j') \s)) xss" + and "j \ j'" + shows "wf_mbufn' \ P' V j' n R r buf'" + and "wf_ts_regex \ P' j' r nts'" + using pre_buf pre_nts bounded rm mr safe xss \j \ j'\ unfolding wf_mbufn'_def wf_ts_regex_def + using atms_empty_progress[of m g r] to_mregex_ok[OF mr] + by (auto 0 3 simp: list.rel_map to_mregex_empty_progress to_mregex_nonempty_progress Mini_def + intro: progress_mono_gen[OF \j \ j'\ rm] list.rel_refl_strong progress_le_gen + dest: list_all2_lengthD elim!: mbufnt_take_eqD[OF eq wf_mbufn_add]) + +lemma mbuf2t_take_add_induct'[consumes 6, case_names base step]: + assumes eq: "mbuf2t_take f z (mbuf2_add xs ys buf) nts = (z', buf', nts')" + and bounded: "pred_mapping (\x. x \ j) P" "pred_mapping (\x. x \ j') P'" + and rm: "rel_mapping (\) P P'" + and pre_buf: "wf_mbuf2' \ P V j n R \ \ buf" + and pre_nts: "list_all2 (\i t. t = \ \ i) [min (progress \ P \ j) (progress \ P \ j)..i. qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) i \)) + [progress \ P \ j.. P' \ j'] xs" + and ys: "list_all2 (\i. qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) i \)) + [progress \ P \ j.. P' \ j'] ys" + and "j \ j'" + and base: "U (min (progress \ P \ j) (progress \ P \ j)) z" + and step: "\k X Y z. min (progress \ P \ j) (progress \ P \ j) \ k \ + Suc k \ progress \ P' \ j' \ Suc k \ progress \ P' \ j' \ + qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) k \) X \ + qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) k \) Y \ + U k z \ U (Suc k) (f X Y (\ \ k) z)" + shows "U (min (progress \ P' \ j') (progress \ P' \ j')) z'" + using pre_buf pre_nts bounded rm unfolding wf_mbuf2'_def + by (blast intro!: mbuf2t_take_induct[OF eq] wf_mbuf2_add[OF _ xs ys] progress_mono_gen[OF \j \ j'\ rm] + progress_le_gen base step) + +lemma mbufnt_take_add_induct'[consumes 6, case_names base step]: + assumes eq: "mbufnt_take f z (mbufn_add xss buf) nts = (z', buf', nts')" + and bounded: "pred_mapping (\x. x \ j) P" "pred_mapping (\x. x \ j') P'" + and rm: "rel_mapping (\) P P'" + and safe: "safe_regex m g r" + and mr: "to_mregex r = (mr, \s)" + and pre_buf: "wf_mbufn' \ P V j n R r buf" + and pre_nts: "list_all2 (\i t. t = \ \ i) [progress_regex \ P r j..\ i. qtable n (fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) i \)) \s) + (map2 upt (map (\\. progress \ P \ j) \s) (map (\\. progress \ P' \ j') \s)) xss" + and "j \ j'" + and base: "U (progress_regex \ P r j) z" + and step: "\k Xs z. progress_regex \ P r j \ k \ Suc k \ progress_regex \ P' r j' \ + list_all2 (\\. qtable n (Formula.fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) k \)) \s Xs \ + U k z \ U (Suc k) (f Xs (\ \ k) z)" + shows "U (progress_regex \ P' r j') z'" + using pre_buf pre_nts bounded rm \j \ j'\ to_mregex_progress[OF safe mr, of \ P' j'] to_mregex_empty_progress[OF safe, of mr \ P j] base + unfolding wf_mbufn'_def mr prod.case + by (fastforce dest!: mbufnt_take_induct[OF eq wf_mbufn_add[OF _ xss] pre_nts, of U] + simp: list.rel_map le_imp_diff_is_add ac_simps Mini_def + intro: progress_mono_gen[OF \j \ j'\ rm] list.rel_refl_strong progress_le_gen + intro!: base step dest: list_all2_lengthD split: if_splits) + +lemma progress_Until_le: "progress \ P (Formula.Until \ I \) j \ min (progress \ P \ j) (progress \ P \ j)" + by (cases "right I") (auto simp: trans_le_add1 intro!: cInf_lower) + +lemma progress_MatchF_le: "progress \ P (Formula.MatchF I r) j \ progress_regex \ P r j" + by (cases "right I") (auto simp: trans_le_add1 progress_regex_def intro!: cInf_lower) + +lemma list_all2_upt_Cons: "P a x \ list_all2 P [Suc a.. Suc a \ b \ + list_all2 P [a.. list_all2 P [b.. + a \ b \ b \ c \ list_all2 P [a..x. R x x) xs ys" + by (auto simp: list_all3_conv_all_nth list_all2_conv_all_nth) + +lemma map_split_map: "map_split f (map g xs) = map_split (f o g) xs" + by (induct xs) auto + +lemma map_split_alt: "map_split f xs = (map (fst o f) xs, map (snd o f) xs)" + by (induct xs) (auto split: prod.splits) + +lemma fv_formula_of_constraint: "fv (formula_of_constraint (t1, p, c, t2)) = fv_trm t1 \ fv_trm t2" + by (induction "(t1, p, c, t2)" rule: formula_of_constraint.induct) simp_all + +lemma (in maux) wf_mformula_wf_set: "wf_mformula \ j P V n R \ \' \ wf_set n (Formula.fv \')" + unfolding wf_set_def +proof (induction rule: wf_mformula.induct) + case (AndRel P V n R \ \' \' conf) + then show ?case by (auto simp: fv_formula_of_constraint dest!: subsetD) +next + case (Ands P V n R l l_pos l_neg l' buf A_pos A_neg) + from Ands.IH have "\\'\set (l_pos @ map remove_neg l_neg). \x\fv \'. x < n" + by (simp add: list_all2_conv_all_nth all_set_conv_all_nth[of "_ @ _"] del: set_append) + then have "\\'\set (l_pos @ l_neg). \x\fv \'. x < n" + by (auto dest: bspec[where x="remove_neg _"]) + then show ?case using Ands.hyps(2) by auto +next + case (Agg P V b n R \ \' y f g0 \) + then have "Formula.fvi_trm b f \ Formula.fvi b \'" + by (auto simp: fvi_trm_iff_fv_trm[where b=b] fvi_iff_fv[where b=b]) + with Agg show ?case by (auto 0 3 simp: Un_absorb2 fvi_iff_fv[where b=b]) +next + case (MatchP r P V n R \s mr mrs buf nts I aux) + then obtain \s' where conv: "to_mregex r = (mr, \s')" by blast + with MatchP have "\\'\set \s'. \x\fv \'. x < n" + by (simp add: list_all2_conv_all_nth all_set_conv_all_nth[of \s']) + with conv show ?case + by (simp add: to_mregex_ok[THEN conjunct1] fv_regex_alt[OF \safe_regex _ _ r\]) +next + case (MatchF r P V n R \s mr mrs buf nts I aux) + then obtain \s' where conv: "to_mregex r = (mr, \s')" by blast + with MatchF have "\\'\set \s'. \x\fv \'. x < n" + by (simp add: list_all2_conv_all_nth all_set_conv_all_nth[of \s']) + with conv show ?case + by (simp add: to_mregex_ok[THEN conjunct1] fv_regex_alt[OF \safe_regex _ _ r\]) +qed (auto simp: fvi_Suc split: if_splits) + +lemma qtable_mmulti_join: + assumes pos: "list_all3 (\A Qi X. qtable n A P Qi X \ wf_set n A) A_pos Q_pos L_pos" + and neg: "list_all3 (\A Qi X. qtable n A P Qi X \ wf_set n A) A_neg Q_neg L_neg" + and C_eq: "C = \(set A_pos)" and L_eq: "L = L_pos @ L_neg" + and "A_pos \ []" and fv_subset: "\(set A_neg) \ \(set A_pos)" + and restrict_pos: "\x. wf_tuple n C x \ P x \ list_all (\A. P (restrict A x)) A_pos" + and restrict_neg: "\x. wf_tuple n C x \ P x \ list_all (\A. P (restrict A x)) A_neg" + and Qs: "\x. wf_tuple n C x \ P x \ Q x \ + list_all2 (\A Qi. Qi (restrict A x)) A_pos Q_pos \ + list_all2 (\A Qi. \ Qi (restrict A x)) A_neg Q_neg" + shows "qtable n C P Q (mmulti_join n A_pos A_neg L)" +proof (rule qtableI) + from pos have 1: "list_all2 (\A X. table n A X \ wf_set n A) A_pos L_pos" + by (simp add: list_all3_conv_all_nth list_all2_conv_all_nth qtable_def) + moreover from neg have "list_all2 (\A X. table n A X \ wf_set n A) A_neg L_neg" + by (simp add: list_all3_conv_all_nth list_all2_conv_all_nth qtable_def) + ultimately have L: "list_all2 (\A X. table n A X \ wf_set n A) (A_pos @ A_neg) (L_pos @ L_neg)" + by (rule list_all2_appendI) + note in_join_iff = mmulti_join_correct[OF \A_pos \ []\ L] + from 1 have take_eq: "take (length A_pos) (L_pos @ L_neg) = L_pos" + by (auto dest!: list_all2_lengthD) + from 1 have drop_eq: "drop (length A_pos) (L_pos @ L_neg) = L_neg" + by (auto dest!: list_all2_lengthD) + + note mmulti_join.simps[simp del] + show "table n C (mmulti_join n A_pos A_neg L)" + unfolding C_eq L_eq table_def by (simp add: in_join_iff) + show "Q x" if "x \ mmulti_join n A_pos A_neg L" "wf_tuple n C x" "P x" for x + using that(2,3) + proof (rule Qs[THEN iffD2, OF _ _ conjI]) + have pos': "list_all2 (\A. (\) (restrict A x)) A_pos L_pos" + and neg': "list_all2 (\A. (\) (restrict A x)) A_neg L_neg" + using that(1) unfolding L_eq in_join_iff take_eq drop_eq by simp_all + show "list_all2 (\A Qi. Qi (restrict A x)) A_pos Q_pos" + using pos pos' restrict_pos that(2,3) + by (simp add: list_all3_conv_all_nth list_all2_conv_all_nth list_all_length qtable_def) + have fv_subset': "\i. i < length A_neg \ A_neg ! i \ C" + using fv_subset unfolding C_eq by (auto simp: Sup_le_iff) + show "list_all2 (\A Qi. \ Qi (restrict A x)) A_neg Q_neg" + using neg neg' restrict_neg that(2,3) + by (auto simp: list_all3_conv_all_nth list_all2_conv_all_nth list_all_length qtable_def + wf_tuple_restrict_simple[OF _ fv_subset']) + qed + show "x \ mmulti_join n A_pos A_neg L" if "wf_tuple n C x" "P x" "Q x" for x + unfolding L_eq in_join_iff take_eq drop_eq + proof (intro conjI) + from that have pos': "list_all2 (\A Qi. Qi (restrict A x)) A_pos Q_pos" + and neg': "list_all2 (\A Qi. \ Qi (restrict A x)) A_neg Q_neg" + using Qs[THEN iffD1] by auto + show "wf_tuple n (\A\set A_pos. A) x" + using \wf_tuple n C x\ unfolding C_eq by simp + show "list_all2 (\A. (\) (restrict A x)) A_pos L_pos" + using pos pos' restrict_pos that(1,2) + by (simp add: list_all3_conv_all_nth list_all2_conv_all_nth list_all_length qtable_def + C_eq wf_tuple_restrict_simple[OF _ Sup_upper]) + show "list_all2 (\A. (\) (restrict A x)) A_neg L_neg" + using neg neg' restrict_neg that(1,2) + by (auto simp: list_all3_conv_all_nth list_all2_conv_all_nth list_all_length qtable_def) + qed +qed + +lemma nth_filter: "i < length (filter P xs) \ + (\i'. i' < length xs \ P (xs ! i') \ Q (xs ! i')) \ Q (filter P xs ! i)" + by (metis (lifting) in_set_conv_nth set_filter mem_Collect_eq) + +lemma nth_partition: "i < length xs \ + (\i'. i' < length (filter P xs) \ Q (filter P xs ! i')) \ + (\i'. i' < length (filter (Not \ P) xs) \ Q (filter (Not \ P) xs ! i')) \ Q (xs ! i)" + by (metis (no_types, lifting) in_set_conv_nth set_filter mem_Collect_eq comp_apply) + +lemma qtable_bin_join: + assumes "qtable n A P Q1 X" "qtable n B P Q2 Y" "\ b \ B \ A" "C = A \ B" + "\x. wf_tuple n C x \ P x \ P (restrict A x) \ P (restrict B x)" + "\x. b \ wf_tuple n C x \ P x \ Q x \ Q1 (restrict A x) \ Q2 (restrict B x)" + "\x. \ b \ wf_tuple n C x \ P x \ Q x \ Q1 (restrict A x) \ \ Q2 (restrict B x)" + shows "qtable n C P Q (bin_join n A X b B Y)" + using qtable_join[OF assms] bin_join_table[of n A X B Y b] assms(1,2) + by (auto simp add: qtable_def) + +lemma restrict_update: "y \ A \ y < length x \ restrict A (x[y:=z]) = restrict A x" + unfolding restrict_def by (auto simp add: nth_list_update) + +lemma qtable_assign: + assumes "qtable n A P Q X" + "y < n" "insert y A = A'" "y \ A" + "\x'. wf_tuple n A' x' \ P x' \ P (restrict A x')" + "\x. wf_tuple n A x \ P x \ Q x \ Q' (x[y:=Some (f x)])" + "\x'. wf_tuple n A' x' \ P x' \ Q' x' \ Q (restrict A x') \ x' ! y = Some (f (restrict A x'))" + shows "qtable n A' P Q' ((\x. x[y:=Some (f x)]) ` X)" (is "qtable _ _ _ _ ?Y") +proof (rule qtableI) + from assms(1) have "table n A X" unfolding qtable_def by simp + then show "table n A' ?Y" + unfolding table_def wf_tuple_def using assms(2,3) + by (auto simp: nth_list_update) +next + fix x' + assume "x' \ ?Y" "wf_tuple n A' x'" "P x'" + then obtain x where "x \ X" and x'_eq: "x' = x[y:=Some (f x)]" by blast + then have "wf_tuple n A x" + using assms(1) unfolding qtable_def table_def by blast + then have "y < length x" using assms(2) by (simp add: wf_tuple_def) + with \wf_tuple n A x\ have "restrict A x' = x" + unfolding x'_eq by (simp add: restrict_update[OF assms(4)] restrict_idle) + with \wf_tuple n A' x'\ \P x'\ have "P x" + using assms(5) by blast + with \wf_tuple n A x\ \x \ X\ have "Q x" + using assms(1) by (elim in_qtableE) + with \wf_tuple n A x\ \P x\ show "Q' x'" + unfolding x'_eq by (rule assms(6)) +next + fix x' + assume "wf_tuple n A' x'" "P x'" "Q' x'" + then have "wf_tuple n A (restrict A x')" + using assms(3) by (auto intro!: wf_tuple_restrict_simple) + moreover have "P (restrict A x')" + using \wf_tuple n A' x'\ \P x'\ by (rule assms(5)) + moreover have "Q (restrict A x')" and y: "x' ! y = Some (f (restrict A x'))" + using \wf_tuple n A' x'\ \P x'\ \Q' x'\ by (auto dest!: assms(7)) + ultimately have "restrict A x' \ X" by (intro in_qtableI[OF assms(1)]) + moreover have "x' = (restrict A x')[y:=Some (f (restrict A x'))]" + using y assms(2,3) \wf_tuple n A (restrict A x')\ \wf_tuple n A' x'\ + by (auto simp: list_eq_iff_nth_eq wf_tuple_def nth_list_update nth_restrict) + ultimately show "x' \ ?Y" by simp +qed + +lemma sat_the_update: "y \ fv \ \ Formula.sat \ V (map the (x[y:=z])) i \ = Formula.sat \ V (map the x) i \" + by (rule sat_fv_cong) (metis map_update nth_list_update_neq) + +lemma progress_constraint: "progress \ P (formula_of_constraint c) j = j" + by (induction rule: formula_of_constraint.induct) simp_all + +lemma qtable_filter: + assumes "qtable n A P Q X" + "\x. wf_tuple n A x \ P x \ Q x \ R x \ Q' x" + shows "qtable n A P Q' (Set.filter R X)" (is "qtable _ _ _ _ ?Y") +proof (rule qtableI) + from assms(1) have "table n A X" + unfolding qtable_def by simp + then show "table n A ?Y" + unfolding table_def wf_tuple_def by simp +next + fix x + assume "x \ ?Y" "wf_tuple n A x" "P x" + with assms show "Q' x" by (auto elim!: in_qtableE) +next + fix x + assume "wf_tuple n A x" "P x" "Q' x" + with assms show "x \ Set.filter R X" by (auto intro!: in_qtableI) +qed + +lemma eval_constraint_sat_eq: "wf_tuple n A x \ fv_trm t1 \ A \ fv_trm t2 \ A \ + \i\A. i < n \ eval_constraint (t1, p, c, t2) x = + Formula.sat \ V (map the x) i (formula_of_constraint (t1, p, c, t2))" + by (induction "(t1, p, c, t2)" rule: formula_of_constraint.induct) + (simp_all add: meval_trm_eval_trm) + +declare progress_le_gen[simp] + +definition "wf_envs \ j P P' V db = + (dom V = dom P \ + Mapping.keys db = dom P \ {p. p \ fst ` \ \ j} \ + rel_mapping (\) P P' \ + pred_mapping (\i. i \ j) P \ + pred_mapping (\i. i \ Suc j) P' \ + (\p \ Mapping.keys db - dom P. the (Mapping.lookup db p) = [{ts. (p, ts) \ \ \ j}]) \ + (\p \ dom P. list_all2 (\i X. X = the (V p) i) [the (P p).. event_data list) set \ Formula.database" is + "\X p. (if p \ fst ` X then Some [{ts. (p, ts) \ X}] else None)" . + +lemma wf_envs_mk_db: "wf_envs \ j Map.empty Map.empty Map.empty (mk_db (\ \ j))" + unfolding wf_envs_def mk_db_def + by transfer (force split: if_splits simp: image_iff rel_mapping_alt) + +lemma wf_envs_update: + assumes wf_envs: "wf_envs \ j P P' V db" + and m_eq: "m = Formula.nfv \" + and in_fv: "{0 ..< m} \ fv \" + and b_le_m: "b \ m" + and xs: "list_all2 (\i. qtable m (Formula.fv \) (mem_restr UNIV) (\v. Formula.sat \ V (map the v) i \)) + [progress \ P \ j.. P' \ (Suc j)] xs" + shows "wf_envs \ j (P(p \ progress \ P \ j)) (P'(p \ progress \ P' \ (Suc j))) + (V(p \ \i. {v. length v = m - b \ (\zs. length zs = b \ Formula.sat \ V (zs @ v) i \)})) + (Mapping.update p (map (image (drop b o map the)) xs) db)" + unfolding wf_envs_def +proof (intro conjI ballI, goal_cases) + case 3 + from assms show ?case + by (auto simp: wf_envs_def pred_mapping_alt progress_le progress_mono_gen + intro!: rel_mapping_map_upd) +next + case (6 p') + with assms show ?case by (cases "p' \ dom P") (auto simp: wf_envs_def lookup_update') +next + case (7 p') + from xs have "list_all2 (\x y. (\x. drop b (map the x)) ` y = + {v. length v = m - b \ (\zs. length zs = b \ Formula.sat \ V (zs @ v) x \)}) + [progress \ P \ j.. P' \ (Suc j)] xs" + proof (rule list.rel_mono_strong, safe) + fix i X + assume qtable: "qtable m (fv \) (mem_restr UNIV) (\v. Formula.sat \ V (map the v) i \) X" + { + fix v + assume "v \ X" + then show "length (drop b (map the v)) = m - b" and + "\zs. length zs = b \ Formula.sat \ V (zs @ drop b (map the v)) i \" + using qtable b_le_m + by (auto simp: wf_tuple_def elim!: in_qtableE intro!: exI[of _ "take b (map the v)"]) + } + { + fix zs v + assume "length v = m - length zs" and "Formula.sat \ V (zs @ v) i \" and "b = length zs" + then show "v \ (\x. drop (length zs) (map the x)) ` X" + using in_fv b_le_m + by (auto 0 3 simp: wf_tuple_def nth_append + intro!: image_eqI[where x="map Some (zs @ v)"] in_qtableI[OF qtable]) + } + qed + moreover have "list_all2 (\i X. X = the (V p') i) [the (P p').. p'" + proof - + from that 7 have "p' \ dom P" by simp + with wf_envs show ?thesis by (simp add: wf_envs_def) + qed + ultimately show ?case + by (simp add: list.rel_map image_iff lookup_update') +qed (use assms in \auto simp: wf_envs_def\) + +lemma wf_envs_P_simps[simp]: + "wf_envs \ j P P' V db \ pred_mapping (\i. i \ j) P" + "wf_envs \ j P P' V db \ pred_mapping (\i. i \ Suc j) P'" + "wf_envs \ j P P' V db \ rel_mapping (\) P P'" + unfolding wf_envs_def by auto + +lemma wf_envs_progress_le[simp]: + "wf_envs \ j P P' V db \ progress \ P \ j \ j" + "wf_envs \ j P P' V db \ progress \ P' \ (Suc j) \ Suc j" + unfolding wf_envs_def by auto + +lemma wf_envs_progress_regex_le[simp]: + "wf_envs \ j P P' V db \ progress_regex \ P r j \ j" + "wf_envs \ j P P' V db \ progress_regex \ P' r (Suc j) \ Suc j" + unfolding wf_envs_def by (auto simp: progress_regex_le) + +lemma wf_envs_progress_mono[simp]: + "wf_envs \ j P P' V db \ a \ b \ progress \ P \ a \ progress \ P' \ b" + unfolding wf_envs_def + by (auto simp: progress_mono_gen) + +lemma qtable_wf_tuple_cong: "qtable n A P Q X \ A = B \ (\v. wf_tuple n A v \ P v \ Q v = Q' v) \ qtable n B P Q' X" + unfolding qtable_def table_def by blast + +lemma (in maux) meval: + assumes "wf_mformula \ j P V n R \ \'" "wf_envs \ j P P' V db" + shows "case meval n (\ \ j) db \ of (xs, \\<^sub>n) \ wf_mformula \ (Suc j) P' V n R \\<^sub>n \' \ + list_all2 (\i. qtable n (Formula.fv \') (mem_restr R) (\v. Formula.sat \ V (map the v) i \')) + [progress \ P \' j.. P' \' (Suc j)] xs" + using assms +proof (induction \ arbitrary: db P P' V n R \') + case (MRel rel) + then show ?case + by (cases rule: wf_mformula.cases) + (auto simp add: ball_Un intro: wf_mformula.intros table_eq_rel eq_rel_eval_trm + in_eq_rel qtable_empty qtable_unit_table intro!: qtableI) +next + case (MPred e ts) + then show ?case + proof (cases "e \ dom P") + case True + with MPred(2) have "e \ Mapping.keys db" "e \ dom P'" "e \ dom V" + "list_all2 (\i X. X = the (V e) i) [the (P e).. dom P'" "e \ dom V" + unfolding wf_envs_def rel_mapping_alt by auto + moreover + from False MPred(2) have *: "e \ fst ` \ \ j \ e \ Mapping.keys db" + unfolding wf_envs_def by auto + from False MPred(2) have + "e \ Mapping.keys db \ Mapping.lookup db e = Some [{ts. (e, ts) \ \ \ j}]" + unfolding wf_envs_def keys_dom_lookup by (metis Diff_iff domD option.sel) + with * have "(case Mapping.lookup db e of None \ [{}] | Some xs \ xs) = [{ts. (e, ts) \ \ \ j}]" + by (cases "e \ fst ` \ \ j") (auto simp: image_iff keys_dom_lookup split: option.splits) + ultimately show ?thesis + by (cases rule: wf_mformula.cases) + (fastforce intro!: wf_mformula.Pred qtableI bexI[where P="\x. _ = tabulate x 0 n", OF refl] + elim!: list.rel_mono_strong bexI[rotated] dest: ex_match + simp: list.rel_map table_def match_wf_tuple in_these_eq match_eval_trm image_iff list.map_comp) + qed +next + case (MLet p m b \1 \2) + from MLet.prems(1) obtain \1' \2' where Let: "\' = Formula.Let p b \1' \2'" and + 1: "wf_mformula \ j P V m UNIV \1 \1'" and + fv: "m = Formula.nfv \1'" "{0.. fv \1'" "b \ m" and + 2: "wf_mformula \ j (P(p \ progress \ P \1' j)) + (V(p \ \i. {v. length v = m - b \ (\zs. length zs = b \ Formula.sat \ V (zs @ v) i \1')})) + n R \2 \2'" + by (cases rule: wf_mformula.cases) auto + obtain xs \1_new where e1: "meval m (\ \ j) db \1 = (xs, \1_new)" and + wf1: "wf_mformula \ (Suc j) P' V m UNIV \1_new \1'" and + res1: "list_all2 (\i. qtable m (fv \1') (mem_restr UNIV) (\v. Formula.sat \ V (map the v) i \1')) + [progress \ P \1' j.. P' \1' (Suc j)] xs" + using MLet(1)[OF 1(1) MLet.prems(2)] by (auto simp: eqTrueI[OF mem_restr_UNIV, abs_def]) + from MLet(2)[OF 2 wf_envs_update[OF MLet.prems(2) fv res1]] wf1 e1 fv + show ?case unfolding Let + by (auto simp: fun_upd_def intro!: wf_mformula.Let) +next + case (MAnd A_\ \ pos A_\ \ buf) + from MAnd.prems show ?case + by (cases rule: wf_mformula.cases) + (auto simp: sat_the_restrict simp del: bin_join.simps + dest!: MAnd.IH split: if_splits prod.splits intro!: wf_mformula.And qtable_bin_join + elim: mbuf2_take_add'(1) list.rel_mono_strong[OF mbuf2_take_add'(2)]) +next + case (MAndAssign \ conf) + from MAndAssign.prems obtain \'' x t \'' where + wf_envs: "wf_envs \ j P P' V db" and + \'_eq: "\' = formula.And \'' \''" and + wf_\: "wf_mformula \ j P V n R \ \''" and + "x < n" and + "x \ fv \''" and + fv_t_subset: "fv_trm t \ fv \''" and + conf: "(x, t) = conf" and + \''_eqs: "\'' = formula.Eq (trm.Var x) t \ \'' = formula.Eq t (trm.Var x)" + by (cases rule: wf_mformula.cases) + from wf_\ wf_envs obtain xs \\<^sub>n where + meval_eq: "meval n (\ \ j) db \ = (xs, \\<^sub>n)" and + wf_\\<^sub>n: "wf_mformula \ (Suc j) P' V n R \\<^sub>n \''" and + xs: "list_all2 (\i. qtable n (fv \'') (mem_restr R) (\v. Formula.sat \ V (map the v) i \'')) + [progress \ P \'' j.. P' \'' (Suc j)] xs" + by (auto dest!: MAndAssign.IH) + have progress_eqs: + "progress \ P \' j = progress \ P \'' j" + "progress \ P' \' (Suc j) = progress \ P' \'' (Suc j)" + using \''_eqs wf_envs_progress_le[OF wf_envs] by (auto simp: \'_eq) + + show ?case proof (simp add: meval_eq, intro conjI) + show "wf_mformula \ (Suc j) P' V n R (MAndAssign \\<^sub>n conf) \'" + unfolding \'_eq + by (rule wf_mformula.AndAssign) fact+ + next + show "list_all2 (\i. qtable n (fv \') (mem_restr R) (\v. Formula.sat \ V (map the v) i \')) + [progress \ P \' j.. P' \' (Suc j)] (map ((`) (eval_assignment conf)) xs)" + unfolding list.rel_map progress_eqs conf[symmetric] eval_assignment.simps + using xs + proof (rule list.rel_mono_strong) + fix i X + assume qtable: "qtable n (fv \'') (mem_restr R) (\v. Formula.sat \ V (map the v) i \'') X" + then show "qtable n (fv \') (mem_restr R) (\v. Formula.sat \ V (map the v) i \') + ((\y. y[x := Some (meval_trm t y)]) ` X)" + proof (rule qtable_assign) + show "x < n" by fact + show "insert x (fv \'') = fv \'" + using \''_eqs fv_t_subset by (auto simp: \'_eq) + show "x \ fv \''" by fact + next + fix v + assume wf_v: "wf_tuple n (fv \') v" and "mem_restr R v" + then show "mem_restr R (restrict (fv \'') v)" by simp + + assume sat: "Formula.sat \ V (map the v) i \'" + then have A: "Formula.sat \ V (map the (restrict (fv \'') v)) i \''" (is ?A) + by (simp add: \'_eq sat_the_restrict) + have "map the v ! x = Formula.eval_trm (map the v) t" + using sat \''_eqs by (auto simp: \'_eq) + also have "... = Formula.eval_trm (map the (restrict (fv \'') v)) t" + using fv_t_subset by (auto simp: map_the_restrict intro!: eval_trm_fv_cong) + finally have "map the v ! x = meval_trm t (restrict (fv \'') v)" + using meval_trm_eval_trm[of n "fv \''" "restrict (fv \'') v" t] + fv_t_subset wf_v wf_mformula_wf_set[unfolded wf_set_def, OF wf_\] + by (fastforce simp: \'_eq intro!: wf_tuple_restrict) + then have B: "v ! x = Some (meval_trm t (restrict (fv \'') v))" (is ?B) + using \''_eqs wf_v \x < n\ by (auto simp: wf_tuple_def \'_eq) + from A B show "?A \ ?B" .. + next + fix v + assume wf_v: "wf_tuple n (fv \'') v" and "mem_restr R v" + and sat: "Formula.sat \ V (map the v) i \''" + let ?v = "v[x := Some (meval_trm t v)]" + from sat have A: "Formula.sat \ V (map the ?v) i \''" + using \x \ fv \''\ by (simp add: sat_the_update) + have "y \ fv_trm t \ x \ y" for y + using fv_t_subset \x \ fv \''\ by auto + then have B: "Formula.sat \ V (map the ?v) i \''" + using \''_eqs meval_trm_eval_trm[of n "fv \''" v t] \x < n\ + fv_t_subset wf_v wf_mformula_wf_set[unfolded wf_set_def, OF wf_\] + by (auto simp: wf_tuple_def map_update intro!: eval_trm_fv_cong) + from A B show "Formula.sat \ V (map the ?v) i \'" + by (simp add: \'_eq) + qed + qed + qed +next + case (MAndRel \ conf) + from MAndRel.prems show ?case + by (cases rule: wf_mformula.cases) + (auto simp: progress_constraint progress_le list.rel_map fv_formula_of_constraint + Un_absorb2 wf_mformula_wf_set[unfolded wf_set_def] split: prod.splits + dest!: MAndRel.IH[where db=db and P=P and P'=P'] eval_constraint_sat_eq[THEN iffD2] + intro!: wf_mformula.AndRel + elim!: list.rel_mono_strong qtable_filter eval_constraint_sat_eq[THEN iffD1]) +next + case (MAnds A_pos A_neg l buf) + note mbufn_take.simps[simp del] mbufn_add.simps[simp del] mmulti_join.simps[simp del] + + from MAnds.prems obtain pos neg l' where + wf_l: "list_all2 (wf_mformula \ j P V n R) l (pos @ map remove_neg neg)" and + wf_buf: "wf_mbufn (progress \ P (formula.Ands l') j) (map (\\. progress \ P \ j) (pos @ map remove_neg neg)) + (map (\\ i. qtable n (fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) i \)) (pos @ map remove_neg neg)) buf" and + posneg: "(pos, neg) = partition safe_formula l'" and + "pos \ []" and + safe_neg: "list_all safe_formula (map remove_neg neg)" and + A_eq: "A_pos = map fv pos" "A_neg = map fv neg" and + fv_subset: "\ (set A_neg) \ \ (set A_pos)" and + "\' = Formula.Ands l'" + by (cases rule: wf_mformula.cases) simp + have progress_eq: "progress \ P' (formula.Ands l') (Suc j) = + Mini (progress \ P (formula.Ands l') j) (map (\\. progress \ P' \ (Suc j)) (pos @ map remove_neg neg))" + using \pos \ []\ posneg + by (auto simp: Mini_def image_Un[symmetric] Collect_disj_eq[symmetric] intro!: arg_cong[where f=Min]) + + have join_ok: "qtable n (\ (fv ` set l')) (mem_restr R) + (\v. list_all (Formula.sat \ V (map the v) k) l') + (mmulti_join n A_pos A_neg L)" + if args_ok: "list_all2 (\x. qtable n (fv x) (mem_restr R) (\v. Formula.sat \ V (map the v) k x)) + (pos @ map remove_neg neg) L" + for k L + proof (rule qtable_mmulti_join) + let ?ok = "\A Qi X. qtable n A (mem_restr R) Qi X \ wf_set n A" + let ?L_pos = "take (length A_pos) L" + let ?L_neg = "drop (length A_pos) L" + have 1: "length pos \ length L" + using args_ok by (auto dest!: list_all2_lengthD) + show "list_all3 ?ok A_pos (map (\\ v. Formula.sat \ V (map the v) k \) pos) ?L_pos" + using args_ok wf_l unfolding A_eq + by (auto simp add: list_all3_conv_all_nth list_all2_conv_all_nth nth_append + split: if_splits intro!: wf_mformula_wf_set[of \ j P V n R] + dest: order.strict_trans2[OF _ 1]) + from args_ok have prems_neg: "list_all2 (\\. qtable n (fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) k (remove_neg \))) neg ?L_neg" + by (auto simp: A_eq list_all2_append1 list.rel_map) + show "list_all3 ?ok A_neg (map (\\ v. Formula.sat \ V (map the v) k (remove_neg \)) neg) ?L_neg" + using prems_neg wf_l unfolding A_eq + by (auto simp add: list_all3_conv_all_nth list_all2_conv_all_nth list_all_length nth_append less_diff_conv + split: if_splits intro!: wf_mformula_wf_set[of \ j P V n R _ "remove_neg _", simplified]) + show "\(fv ` set l') = \(set A_pos)" + using fv_subset posneg unfolding A_eq by auto + show "L = take (length A_pos) L @ drop (length A_pos) L" by simp + show "A_pos \ []" using \pos \ []\ A_eq by simp + + fix x :: "event_data tuple" + assume "wf_tuple n (\ (fv ` set l')) x" and "mem_restr R x" + then show "list_all (\A. mem_restr R (restrict A x)) A_pos" + and "list_all (\A. mem_restr R (restrict A x)) A_neg" + by (simp_all add: list.pred_set) + + have "list_all Formula.is_Neg neg" + using posneg safe_neg + by (auto 0 3 simp add: list.pred_map elim!: list.pred_mono_strong + intro: formula.exhaust[of \ "Formula.is_Neg \" for \]) + then have "list_all (\\. Formula.sat \ V (map the v) i (remove_neg \) \ + \ Formula.sat \ V (map the v) i \) neg" for v i + by (fastforce simp: Formula.is_Neg_def elim!: list.pred_mono_strong) + then show "list_all (Formula.sat \ V (map the x) k) l' = + (list_all2 (\A Qi. Qi (restrict A x)) A_pos + (map (\\ v. Formula.sat \ V (map the v) k \) pos) \ + list_all2 (\A Qi. \ Qi (restrict A x)) A_neg + (map (\\ v. Formula.sat \ V (map the v) k + (remove_neg \)) + neg))" + using posneg + by (auto simp add: A_eq list_all2_conv_all_nth list_all_length sat_the_restrict + elim: nth_filter nth_partition[where P=safe_formula and Q="Formula.sat _ _ _ _"]) + qed fact + + from MAnds.prems(2) show ?case + unfolding \\' = Formula.Ands l'\ + by (auto 0 3 simp add: list.rel_map progress_eq map2_map_map list_all3_map + list_all3_list_all2_conv list.pred_map + simp del: set_append map_append progress_simps split: prod.splits + intro!: wf_mformula.Ands[OF _ _ posneg \pos \ []\ safe_neg A_eq fv_subset] + list.rel_mono_strong[OF wf_l] wf_mbufn_add[OF wf_buf] + list.rel_flip[THEN iffD1, OF list.rel_mono_strong, OF wf_l] + list.rel_refl join_ok[unfolded list.pred_set] + dest!: MAnds.IH[OF _ _ MAnds.prems(2), rotated] + elim!: wf_mbufn_take list_all2_appendI + elim: mbufn_take_induct[OF _ wf_mbufn_add[OF wf_buf]]) +next + case (MOr \ \ buf) + from MOr.prems show ?case + by (cases rule: wf_mformula.cases) + (auto dest!: MOr.IH split: if_splits prod.splits intro!: wf_mformula.Or qtable_union + elim: mbuf2_take_add'(1) list.rel_mono_strong[OF mbuf2_take_add'(2)]) +next + case (MNeg \) + have *: "qtable n {} (mem_restr R) (\v. P v) X \ + \ qtable n {} (mem_restr R) (\v. \ P v) empty_table \ x \ X \ False" for P x X + using nullary_qtable_cases qtable_unit_empty_table by fastforce + from MNeg.prems show ?case + by (cases rule: wf_mformula.cases) + (auto 0 4 intro!: wf_mformula.Neg dest!: MNeg.IH + simp add: list.rel_map + dest: nullary_qtable_cases qtable_unit_empty_table intro!: qtable_empty_unit_table + elim!: list.rel_mono_strong elim: *) +next + case (MExists \) + from MExists.prems show ?case + by (cases rule: wf_mformula.cases) + (force simp: list.rel_map fvi_Suc sat_fv_cong nth_Cons' + intro!: wf_mformula.Exists dest!: MExists.IH qtable_project_fv + elim!: list.rel_mono_strong table_fvi_tl qtable_cong sat_fv_cong[THEN iffD1, rotated -1] + split: if_splits)+ +next + case (MAgg g0 y \ b f \) + from MAgg.prems show ?case + using wf_mformula_wf_set[OF MAgg.prems(1), unfolded wf_set_def] + by (cases rule: wf_mformula.cases) + (auto 0 3 simp add: list.rel_map simp del: sat.simps fvi.simps split: prod.split + intro!: wf_mformula.Agg qtable_eval_agg dest!: MAgg.IH elim!: list.rel_mono_strong) +next + case (MPrev I \ first buf nts) + from MPrev.prems show ?case + proof (cases rule: wf_mformula.cases) + case (Prev \) + let ?xs = "fst (meval n (\ \ j) db \)" + let ?\ = "snd (meval n (\ \ j) db \)" + let ?ls = "fst (mprev_next I (buf @ ?xs) (nts @ [\ \ j]))" + let ?rs = "fst (snd (mprev_next I (buf @ ?xs) (nts @ [\ \ j])))" + let ?ts = "snd (snd (mprev_next I (buf @ ?xs) (nts @ [\ \ j])))" + let ?P = "\i X. qtable n (fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) i \) X" + let ?min = "min (progress \ P' \ (Suc j)) (Suc j - 1)" + from Prev MPrev.IH[OF _ MPrev.prems(2), of n R \] have IH: "wf_mformula \ (Suc j) P' V n R ?\ \" and + "list_all2 ?P [progress \ P \ j.. P' \ (Suc j)] ?xs" by auto + with Prev(4,5) MPrev.prems(2) have "list_all2 (\i X. if mem (\ \ (Suc i) - \ \ i) I then ?P i X else X = empty_table) + [min (progress \ P \ j) (j - 1).. + list_all2 ?P [?min.. P' \ (Suc j)] ?rs \ + list_all2 (\i t. t = \ \ i) [?min.. P \ j)) j = Suc (min (progress \ P \ j) (j-1))" if "j > 0" + using that by auto + ultimately show ?thesis using Prev(1,3) MPrev.prems(2) IH + by (auto simp: map_Suc_upt[symmetric] upt_Suc[of 0] list.rel_map qtable_empty_iff + simp del: upt_Suc elim!: wf_mformula.Prev list.rel_mono_strong + split: prod.split if_split_asm) + qed +next + case (MNext I \ first nts) + from MNext.prems show ?case + proof (cases rule: wf_mformula.cases) + case (Next \) + + have min[simp]: + "min (progress \ P \ j - Suc 0) (j - Suc 0) = progress \ P \ j - Suc 0" + "min (progress \ P' \ (Suc j) - Suc 0) j = progress \ P' \ (Suc j) - Suc 0" + using wf_envs_progress_le[OF MNext.prems(2), of \] by auto + + let ?xs = "fst (meval n (\ \ j) db \)" + let ?ys = "case (?xs, first) of (_ # xs, True) \ xs | _ \ ?xs" + let ?\ = "snd (meval n (\ \ j) db \)" + let ?ls = "fst (mprev_next I ?ys (nts @ [\ \ j]))" + let ?rs = "fst (snd (mprev_next I ?ys (nts @ [\ \ j])))" + let ?ts = "snd (snd (mprev_next I ?ys (nts @ [\ \ j])))" + let ?P = "\i X. qtable n (fv \) (mem_restr R) (\v. Formula.sat \ V (map the v) i \) X" + let ?min = "min (progress \ P' \ (Suc j) - 1) (Suc j - 1)" + from Next MNext.IH[OF _ MNext.prems(2), of n R \] have IH: "wf_mformula \ (Suc j) P' V n R ?\ \" + "list_all2 ?P [progress \ P \ j.. P' \ (Suc j)] ?xs" by auto + with Next have "list_all2 (\i X. if mem (\ \ (Suc i) - \ \ i) I then ?P (Suc i) X else X = empty_table) + [progress \ P \ j - 1.. + list_all2 ?P [Suc ?min.. P' \ (Suc j)] ?rs \ + list_all2 (\i t. t = \ \ i) [?min.. P \ j < progress \ P' \ (Suc j)" + using that wf_envs_progress_le[OF MNext.prems(2), of \] + by (intro mnext) (auto simp: list_all2_Cons2 upt_eq_Cons_conv + intro!: list_all2_upt_append list_all2_appendI split: list.splits) + then show ?thesis using wf_envs_progress_le[OF MNext.prems(2), of \] + wf_envs_progress_mono[OF MNext.prems(2), of j "Suc j" \, simplified] Next IH + by (cases "progress \ P' \ (Suc j) > progress \ P \ j") + (auto 0 3 simp: qtable_empty_iff le_Suc_eq le_diff_conv + elim!: wf_mformula.Next list.rel_mono_strong list_all2_appendI + split: prod.split list.splits if_split_asm) (* slow 5 sec*) + qed +next + case (MSince args \ \ buf nts aux) + note sat.simps[simp del] + from MSince.prems obtain \'' \''' \'' I where Since_eq: "\' = Formula.Since \''' I \''" + and pos: "if args_pos args then \''' = \'' else \''' = Formula.Neg \''" + and pos_eq: "safe_formula \''' = args_pos args" + and \: "wf_mformula \ j P V n R \ \''" + and \: "wf_mformula \ j P V n R \ \''" + and fvi_subset: "Formula.fv \'' \ Formula.fv \''" + and buf: "wf_mbuf2' \ P V j n R \'' \'' buf" + and nts: "wf_ts \ P j \'' \'' nts" + and aux: "wf_since_aux \ V R args \'' \'' aux (progress \ P (Formula.Since \''' I \'') j)" + and args_ivl: "args_ivl args = I" + and args_n: "args_n args = n" + and args_L: "args_L args = Formula.fv \''" + and args_R: "args_R args = Formula.fv \''" + by (cases rule: wf_mformula.cases) (auto) + have \''': "Formula.fv \''' = Formula.fv \''" "progress \ P \''' j = progress \ P \'' j" + "progress \ P' \''' j = progress \ P' \'' j" for j + using pos by (simp_all split: if_splits) + from MSince.prems(2) have nts_snoc: "list_all2 (\i t. t = \ \ i) + [min (progress \ P \'' j) (progress \ P \'' j).. \ j])" + using nts unfolding wf_ts_def + by (auto simp add: wf_envs_progress_le[THEN min.coboundedI1] intro: list_all2_appendI) + have update: "wf_since_aux \ V R args \'' \'' (snd (zs, aux')) (progress \ P' (Formula.Since \''' I \'') (Suc j)) \ + list_all2 (\i. qtable n (Formula.fv \''' \ Formula.fv \'') (mem_restr R) + (\v. Formula.sat \ V (map the v) i (Formula.Since \''' I \''))) + [progress \ P (Formula.Since \''' I \'') j.. P' (Formula.Since \''' I \'') (Suc j)] (fst (zs, aux'))" + if eval_\: "fst (meval n (\ \ j) db \) = xs" + and eval_\: "fst (meval n (\ \ j) db \) = ys" + and eq: "mbuf2t_take (\r1 r2 t (zs, aux). + case update_since args r1 r2 t aux of (z, x) \ (zs @ [z], x)) + ([], aux) (mbuf2_add xs ys buf) (nts @ [\ \ j]) = ((zs, aux'), buf', nts')" + for xs ys zs aux' buf' nts' + unfolding progress_simps \''' + proof (rule mbuf2t_take_add_induct'[where j=j and j'="Suc j" and z'="(zs, aux')", + OF eq wf_envs_P_simps[OF MSince.prems(2)] buf nts_snoc], + goal_cases xs ys _ base step) + case xs + then show ?case + using MSince.IH(1)[OF \ MSince.prems(2)] eval_\ by auto + next + case ys + then show ?case + using MSince.IH(2)[OF \ MSince.prems(2)] eval_\ by auto + next + case base + then show ?case + using aux by (simp add: \''') + next + case (step k X Y z) + then show ?case + using fvi_subset pos + by (auto 0 3 simp: args_ivl args_n args_L args_R Un_absorb1 + elim!: update_since(1) list_all2_appendI dest!: update_since(2) + split: prod.split if_splits) + qed simp + with MSince.IH(1)[OF \ MSince.prems(2)] MSince.IH(2)[OF \ MSince.prems(2)] show ?case + by (auto 0 3 simp: Since_eq split: prod.split + intro: wf_mformula.Since[OF _ _ pos pos_eq args_ivl args_n args_L args_R fvi_subset] + elim: mbuf2t_take_add'(1)[OF _ wf_envs_P_simps[OF MSince.prems(2)] buf nts_snoc] + mbuf2t_take_add'(2)[OF _ wf_envs_P_simps[OF MSince.prems(2)] buf nts_snoc]) +next + case (MUntil args \ \ buf nts aux) + note sat.simps[simp del] progress_simps[simp del] + from MUntil.prems obtain \'' \''' \'' I where Until_eq: "\' = Formula.Until \''' I \''" + and pos: "if args_pos args then \''' = \'' else \''' = Formula.Neg \''" + and pos_eq: "safe_formula \''' = args_pos args" + and \: "wf_mformula \ j P V n R \ \''" + and \: "wf_mformula \ j P V n R \ \''" + and fvi_subset: "Formula.fv \'' \ Formula.fv \''" + and buf: "wf_mbuf2' \ P V j n R \'' \'' buf" + and nts: "wf_ts \ P j \'' \'' nts" + and aux: "wf_until_aux \ V R args \'' \'' aux (progress \ P (Formula.Until \''' I \'') j)" + and args_ivl: "args_ivl args = I" + and args_n: "args_n args = n" + and args_L: "args_L args = Formula.fv \''" + and args_R: "args_R args = Formula.fv \''" + and length_aux: "progress \ P (Formula.Until \''' I \'') j + length_muaux args aux = + min (progress \ P \'' j) (progress \ P \'' j)" + by (cases rule: wf_mformula.cases) (auto) + define pos where args_pos: "pos = args_pos args" + have \''': "progress \ P \''' j = progress \ P \'' j" "progress \ P' \''' j = progress \ P' \'' j" for j + using pos by (simp_all add: progress.simps split: if_splits) + from MUntil.prems(2) have nts_snoc: "list_all2 (\i t. t = \ \ i) + [min (progress \ P \'' j) (progress \ P \'' j).. \ j])" + using nts unfolding wf_ts_def + by (auto simp add: wf_envs_progress_le[THEN min.coboundedI1] intro: list_all2_appendI) + { + fix xs ys zs aux' aux'' buf' nts' + assume eval_\: "fst (meval n (\ \ j) db \) = xs" + and eval_\: "fst (meval n (\ \ j) db \) = ys" + and eq1: "mbuf2t_take (add_new_muaux args) aux (mbuf2_add xs ys buf) (nts @ [\ \ j]) = + (aux', buf', nts')" + and eq2: "eval_muaux args (case nts' of [] \ \ \ j | nt # _ \ nt) aux' = (zs, aux'')" + define ne where "ne \ progress \ P (Formula.Until \''' I \'') j" + have update1: "wf_until_aux \ V R args \'' \'' aux' (progress \ P (Formula.Until \''' I \'') j) \ + ne + length_muaux args aux' = min (progress \ P' \''' (Suc j)) (progress \ P' \'' (Suc j))" + using MUntil.IH(1)[OF \ MUntil.prems(2)] eval_\ MUntil.IH(2)[OF \ MUntil.prems(2)] + eval_\ nts_snoc nts_snoc length_aux aux fvi_subset + unfolding \''' + by (elim mbuf2t_take_add_induct'[where j'="Suc j", OF eq1 wf_envs_P_simps[OF MUntil.prems(2)] buf]) + (auto simp: args_n args_L args_R ne_def wf_update_until) + then obtain cur auxlist' where valid_aux': "valid_muaux args cur aux' auxlist'" and + cur: "cur = (if ne + length auxlist' = 0 then 0 else \ \ (ne + length auxlist' - 1))" and + wf_auxlist': "wf_until_auxlist \ V n R pos \'' I \'' auxlist' (progress \ P (Formula.Until \''' I \'') j)" + unfolding wf_until_aux_def ne_def args_ivl args_n args_pos by auto + have length_aux': "length_muaux args aux' = length auxlist'" + using valid_length_muaux[OF valid_aux'] . + have nts': "wf_ts \ P' (Suc j) \'' \'' nts'" + using MUntil.IH(1)[OF \ MUntil.prems(2)] eval_\ MUntil.IH(2)[OF \ MUntil.prems(2)] + MUntil.prems(2) eval_\ nts_snoc + unfolding wf_ts_def + by (intro mbuf2t_take_eqD(2)[OF eq1]) (auto intro: wf_mbuf2_add buf[unfolded wf_mbuf2'_def]) + define zs'' where "zs'' = fst (eval_until I (case nts' of [] \ \ \ j | nt # x \ nt) auxlist')" + define auxlist'' where "auxlist'' = snd (eval_until I (case nts' of [] \ \ \ j | nt # x \ nt) auxlist')" + have current_w_le: "cur \ (case nts' of [] \ \ \ j | nt # x \ nt)" + proof (cases nts') + case Nil + have p_le: "min (progress \ P' \''' (Suc j)) (progress \ P' \'' (Suc j)) - 1 \ j" + using wf_envs_progress_le[OF MUntil.prems(2)] + by (auto simp: min_def le_diff_conv) + then show ?thesis + unfolding cur conjunct2[OF update1, unfolded length_aux'] + using Nil by auto + next + case (Cons nt x) + have progress_\''': "progress \ P' \'' (Suc j) = progress \ P' \''' (Suc j)" + using pos by (auto simp add: progress.simps split: if_splits) + have "nt = \ \ (min (progress \ P' \'' (Suc j)) (progress \ P' \'' (Suc j)))" + using nts'[unfolded wf_ts_def Cons] + unfolding list_all2_Cons2 upt_eq_Cons_conv by auto + then show ?thesis + unfolding cur conjunct2[OF update1, unfolded length_aux'] Cons progress_\''' + by (auto split: if_splits list.splits intro!: \_mono) + qed + have valid_aux'': "valid_muaux args cur aux'' auxlist''" + using valid_eval_muaux[OF valid_aux' current_w_le eq2, of zs'' auxlist''] + by (auto simp add: args_ivl zs''_def auxlist''_def) + have length_aux'': "length_muaux args aux'' = length auxlist''" + using valid_length_muaux[OF valid_aux''] . + have eq2': "eval_until I (case nts' of [] \ \ \ j | nt # _ \ nt) auxlist' = (zs, auxlist'')" + using valid_eval_muaux[OF valid_aux' current_w_le eq2, of zs'' auxlist''] + by (auto simp add: args_ivl zs''_def auxlist''_def) + have length_aux'_aux'': "length_muaux args aux' = length zs + length_muaux args aux''" + using eval_until_length[OF eq2'] unfolding length_aux' length_aux'' . + have "i \ progress \ P' (Formula.Until \''' I \'') (Suc j) \ + wf_until_auxlist \ V n R pos \'' I \'' auxlist' i \ + i + length auxlist' = min (progress \ P' \''' (Suc j)) (progress \ P' \'' (Suc j)) \ + wf_until_auxlist \ V n R pos \'' I \'' auxlist'' (progress \ P' (Formula.Until \''' I \'') (Suc j)) \ + i + length zs = progress \ P' (Formula.Until \''' I \'') (Suc j) \ + i + length zs + length auxlist'' = min (progress \ P' \''' (Suc j)) (progress \ P' \'' (Suc j)) \ + list_all2 (\i. qtable n (Formula.fv \'') (mem_restr R) + (\v. Formula.sat \ V (map the v) i (Formula.Until (if pos then \'' else Formula.Neg \'') I \''))) + [i.. V n R pos \'' I \'' aux' (Suc i)" + by (rule wf_until_aux_Cons) + from Cons.prems(2) have 1: "t = \ \ i" + unfolding \a = (t, a1, a2)\ by (rule wf_until_aux_Cons1) + from Cons.prems(2) have 3: "qtable n (Formula.fv \'') (mem_restr R) (\v. + (\j\i. j < Suc (i + length aux') \ mem (\ \ j - \ \ i) I \ Formula.sat \ V (map the v) j \'' \ + (\k\{i.. V (map the v) k \'' else \ Formula.sat \ V (map the v) k \''))) a2" + unfolding \a = (t, a1, a2)\ by (rule wf_until_aux_Cons3) + from Cons.prems(3) have Suc_i_aux': "Suc i + length aux' = + min (progress \ P' \''' (Suc j)) (progress \ P' \'' (Suc j))" + by simp + have "i \ progress \ P' (Formula.Until \''' I \'') (Suc j)" + if "enat (case nts' of [] \ \ \ j | nt # x \ nt) \ enat t + right I" + using that nts' unfolding wf_ts_def progress.simps + by (auto simp add: 1 list_all2_Cons2 upt_eq_Cons_conv \''' + intro!: cInf_lower \_mono elim!: order.trans[rotated] simp del: upt_Suc split: if_splits list.splits) + moreover + have "Suc i \ progress \ P' (Formula.Until \''' I \'') (Suc j)" + if "enat t + right I < enat (case nts' of [] \ \ \ j | nt # x \ nt)" + proof - + from that obtain m where m: "right I = enat m" by (cases "right I") auto + have \_min: "\ \ (min j k) = min (\ \ j) (\ \ k)" for k + by (simp add: min_of_mono monoI) + have le_progress_iff[simp]: "(Suc j) \ progress \ P' \ (Suc j) \ progress \ P' \ (Suc j) = (Suc j)" for \ + using wf_envs_progress_le[OF MUntil.prems(2), of \] by auto + have min_Suc[simp]: "min j (Suc j) = j" by auto + let ?X = "{i. \k. k < Suc j \ k \min (progress \ P' \''' (Suc j)) (progress \ P' \'' (Suc j)) \ enat (\ \ k) \ enat (\ \ i) + right I}" + let ?min = "min j (min (progress \ P' \'' (Suc j)) (progress \ P' \'' (Suc j)))" + have "\ \ ?min \ \ \ j" + by (rule \_mono) auto + from m have "?X \ {}" + by (auto dest!: \_mono[of _ "progress \ P' \'' (Suc j)" \] + simp: not_le not_less \''' intro!: exI[of _ "progress \ P' \'' (Suc j)"]) + from m show ?thesis + using that nts' unfolding wf_ts_def progress.simps + by (intro cInf_greatest[OF \?X \ {}\]) + (auto simp: 1 \''' not_le not_less list_all2_Cons2 upt_eq_Cons_conv less_Suc_eq + simp del: upt_Suc split: list.splits if_splits + dest!: spec[of _ "?min"] less_le_trans[of "\ \ i + m" "\ \ _" "\ \ _ + m"] less_\D) + qed + moreover have *: "k < progress \ P' \ (Suc j)" if + "enat (\ \ i) + right I < enat (case nts' of [] \ \ \ j | nt # x \ nt)" + "enat (\ \ k - \ \ i) \ right I" "\ = \'' \ \ = \''" for k \ + proof - + from that(1,2) obtain m where "right I = enat m" + "\ \ i + m < (case nts' of [] \ \ \ j | nt # x \ nt)" "\ \ k - \ \ i \ m" + by (cases "right I") auto + with that(3) nts' progress_le[of \ \'' "Suc j"] progress_le[of \ \'' "Suc j"] + show ?thesis + unfolding wf_ts_def le_diff_conv + by (auto simp: not_le list_all2_Cons2 upt_eq_Cons_conv less_Suc_eq add.commute + simp del: upt_Suc split: list.splits if_splits dest!: le_less_trans[of "\ \ k"] less_\D) + qed + ultimately show ?case using Cons.prems Suc_i_aux'[simplified] + unfolding \a = (t, a1, a2)\ + by (auto simp: \''' 1 sat.simps upt_conv_Cons dest!: Cons.IH[OF _ aux' Suc_i_aux'] + simp del: upt_Suc split: if_splits prod.splits intro!: iff_exI qtable_cong[OF 3 refl]) + qed + thm this + note wf_aux'' = this[OF wf_envs_progress_mono[OF MUntil.prems(2) le_SucI[OF order_refl]] + wf_auxlist' conjunct2[OF update1, unfolded ne_def length_aux']] + have "progress \ P (formula.Until \''' I \'') j + length auxlist' = + progress \ P' (formula.Until \''' I \'') (Suc j) + length auxlist''" + using wf_aux'' valid_aux'' length_aux'_aux'' + by (auto simp add: ne_def length_aux' length_aux'') + then have "cur = + (if progress \ P' (formula.Until \''' I \'') (Suc j) + length auxlist'' = 0 then 0 + else \ \ (progress \ P' (formula.Until \''' I \'') (Suc j) + length auxlist'' - 1))" + unfolding cur ne_def by auto + then have "wf_until_aux \ V R args \'' \'' aux'' (progress \ P' (formula.Until \''' I \'') (Suc j)) \ + progress \ P (formula.Until \''' I \'') j + length zs = progress \ P' (formula.Until \''' I \'') (Suc j) \ + progress \ P (formula.Until \''' I \'') j + length zs + length_muaux args aux'' = min (progress \ P' \''' (Suc j)) (progress \ P' \'' (Suc j)) \ + list_all2 (\i. qtable n (fv \'') (mem_restr R) (\v. Formula.sat \ V (map the v) i (formula.Until (if pos then \'' else formula.Neg \'') I \''))) + [progress \ P (formula.Until \''' I \'') j.. P (formula.Until \''' I \'') j + length zs] zs" + using wf_aux'' valid_aux'' fvi_subset + unfolding wf_until_aux_def length_aux'' args_ivl args_n args_pos by (auto simp only: length_aux'') + } + note update = this + from MUntil.IH(1)[OF \ MUntil.prems(2)] MUntil.IH(2)[OF \ MUntil.prems(2)] pos pos_eq fvi_subset show ?case + by (auto 0 4 simp: args_ivl args_n args_pos Until_eq \''' progress.simps(6) split: prod.split if_splits + dest!: update[OF refl refl, rotated] + intro!: wf_mformula.Until[OF _ _ _ _ args_ivl args_n args_L args_R fvi_subset] + elim!: list.rel_mono_strong qtable_cong + elim: mbuf2t_take_add'(1)[OF _ wf_envs_P_simps[OF MUntil.prems(2)] buf nts_snoc] + mbuf2t_take_add'(2)[OF _ wf_envs_P_simps[OF MUntil.prems(2)] buf nts_snoc]) +next + case (MMatchP I mr mrs \s buf nts aux) + note sat.simps[simp del] mbufnt_take.simps[simp del] mbufn_add.simps[simp del] + from MMatchP.prems obtain r \s where eq: "\' = Formula.MatchP I r" + and safe: "safe_regex Past Strict r" + and mr: "to_mregex r = (mr, \s)" + and mrs: "mrs = sorted_list_of_set (RPDs mr)" + and \s: "list_all2 (wf_mformula \ j P V n R) \s \s" + and buf: "wf_mbufn' \ P V j n R r buf" + and nts: "wf_ts_regex \ P j r nts" + and aux: "wf_matchP_aux \ V n R I r aux (progress \ P (Formula.MatchP I r) j)" + by (cases rule: wf_mformula.cases) (auto) + have nts_snoc: "list_all2 (\i t. t = \ \ i) [progress_regex \ P r j.. \ j])" + using nts unfolding wf_ts_regex_def + by (auto simp add: wf_envs_progress_regex_le[OF MMatchP.prems(2)] intro: list_all2_appendI) + have update: "wf_matchP_aux \ V n R I r (snd (zs, aux')) (progress \ P' (Formula.MatchP I r) (Suc j)) \ + list_all2 (\i. qtable n (Formula.fv_regex r) (mem_restr R) + (\v. Formula.sat \ V (map the v) i (Formula.MatchP I r))) + [progress \ P (Formula.MatchP I r) j.. P' (Formula.MatchP I r) (Suc j)] (fst (zs, aux'))" + if eval: "map (fst o meval n (\ \ j) db) \s = xss" + and eq: "mbufnt_take (\rels t (zs, aux). + case update_matchP n I mr mrs rels t aux of (z, x) \ (zs @ [z], x)) + ([], aux) (mbufn_add xss buf) (nts @ [\ \ j]) = ((zs, aux'), buf', nts')" + for xss zs aux' buf' nts' + unfolding progress_simps + proof (rule mbufnt_take_add_induct'[where j'="Suc j" and z'="(zs, aux')", OF eq wf_envs_P_simps[OF MMatchP.prems(2)] safe mr buf nts_snoc], + goal_cases xss _ base step) + case xss + then show ?case + using eval \s + by (auto simp: list_all3_map map2_map_map list_all3_list_all2_conv list.rel_map + list.rel_flip[symmetric, of _ \s \s] dest!: MMatchP.IH(1)[OF _ _ MMatchP.prems(2)] + elim!: list.rel_mono_strong split: prod.splits) + next + case base + then show ?case + using aux by auto + next + case (step k Xs z) + then show ?case + by (auto simp: Un_absorb1 mrs safe mr elim!: update_matchP(1) list_all2_appendI + dest!: update_matchP(2) split: prod.split) + qed simp + then show ?case using \s + by (auto simp: eq mr mrs safe map_split_alt list.rel_flip[symmetric, of _ \s \s] + list_all3_map map2_map_map list_all3_list_all2_conv list.rel_map intro!: wf_mformula.intros + elim!: list.rel_mono_strong mbufnt_take_add'(1)[OF _ wf_envs_P_simps[OF MMatchP.prems(2)] safe mr buf nts_snoc] + mbufnt_take_add'(2)[OF _ wf_envs_P_simps[OF MMatchP.prems(2)] safe mr buf nts_snoc] + dest!: MMatchP.IH[OF _ _ MMatchP.prems(2)] split: prod.splits) +next + case (MMatchF I mr mrs \s buf nts aux) + note sat.simps[simp del] mbufnt_take.simps[simp del] mbufn_add.simps[simp del] progress_simps[simp del] + from MMatchF.prems obtain r \s where eq: "\' = Formula.MatchF I r" + and safe: "safe_regex Futu Strict r" + and mr: "to_mregex r = (mr, \s)" + and mrs: "mrs = sorted_list_of_set (LPDs mr)" + and \s: "list_all2 (wf_mformula \ j P V n R) \s \s" + and buf: "wf_mbufn' \ P V j n R r buf" + and nts: "wf_ts_regex \ P j r nts" + and aux: "wf_matchF_aux \ V n R I r aux (progress \ P (Formula.MatchF I r) j) 0" + and length_aux: "progress \ P (Formula.MatchF I r) j + length aux = progress_regex \ P r j" + by (cases rule: wf_mformula.cases) (auto) + have nts_snoc: "list_all2 (\i t. t = \ \ i) + [progress_regex \ P r j.. \ j])" + using nts unfolding wf_ts_regex_def + by (auto simp add: wf_envs_progress_regex_le[OF MMatchF.prems(2)] intro: list_all2_appendI) + { + fix xss zs aux' aux'' buf' nts' + assume eval: "map (fst o meval n (\ \ j) db) \s = xss" + and eq1: "mbufnt_take (update_matchF n I mr mrs) aux (mbufn_add xss buf) (nts @ [\ \ j]) = + (aux', buf', nts')" + and eq2: "eval_matchF I mr (case nts' of [] \ \ \ j | nt # _ \ nt) aux' = (zs, aux'')" + have update1: "wf_matchF_aux \ V n R I r aux' (progress \ P (Formula.MatchF I r) j) 0 \ + progress \ P (Formula.MatchF I r) j + length aux' = progress_regex \ P' r (Suc j)" + using eval nts_snoc nts_snoc length_aux aux \s + by (elim mbufnt_take_add_induct'[where j'="Suc j", OF eq1 wf_envs_P_simps[OF MMatchF.prems(2)] safe mr buf]) + (auto simp: length_update_matchF + list_all3_map map2_map_map list_all3_list_all2_conv list.rel_map list.rel_flip[symmetric, of _ \s \s] + dest!: MMatchF.IH[OF _ _ MMatchF.prems(2)] + elim: wf_update_matchF[OF _ safe mr mrs] elim!: list.rel_mono_strong) + from MMatchF.prems(2) have nts': "wf_ts_regex \ P' (Suc j) r nts'" + using eval eval nts_snoc \s + unfolding wf_ts_regex_def + by (intro mbufnt_take_eqD(2)[OF eq1 wf_mbufn_add[where js'="map (\\. progress \ P' \ (Suc j)) \s", + OF buf[unfolded wf_mbufn'_def mr prod.case]]]) + (auto simp: to_mregex_progress[OF safe mr] Mini_def + list_all3_map map2_map_map list_all3_list_all2_conv list.rel_map list.rel_flip[symmetric, of _ \s \s] + list_all2_Cons1 elim!: list.rel_mono_strong intro!: list.rel_refl_strong + dest!: MMatchF.IH[OF _ _ MMatchF.prems(2)]) + have "i \ progress \ P' (Formula.MatchF I r) (Suc j) \ + wf_matchF_aux \ V n R I r aux' i 0 \ + i + length aux' = progress_regex \ P' r (Suc j) \ + wf_matchF_aux \ V n R I r aux'' (progress \ P' (Formula.MatchF I r) (Suc j)) 0 \ + i + length zs = progress \ P' (Formula.MatchF I r) (Suc j) \ + i + length zs + length aux'' = progress_regex \ P' r (Suc j) \ + list_all2 (\i. qtable n (Formula.fv_regex r) (mem_restr R) + (\v. Formula.sat \ V (map the v) i (Formula.MatchF I r))) + [i.. V n R I r aux' (Suc i) 0" + by (rule wf_matchF_aux_Cons) + from Cons.prems(2) have 1: "t = \ \ i" + unfolding \a = (t, rels, rel)\ by (rule wf_matchF_aux_Cons1) + from Cons.prems(2) have 3: "qtable n (Formula.fv_regex r) (mem_restr R) (\v. + (\j\i. j < Suc (i + length aux') \ mem (\ \ j - \ \ i) I \ Regex.match (Formula.sat \ V (map the v)) r i j)) rel" + unfolding \a = (t, rels, rel)\ using wf_matchF_aux_Cons3 by force + from Cons.prems(3) have Suc_i_aux': "Suc i + length aux' = progress_regex \ P' r (Suc j)" + by simp + have "i \ progress \ P' (Formula.MatchF I r) (Suc j)" + if "enat (case nts' of [] \ \ \ j | nt # x \ nt) \ enat t + right I" + using that nts' unfolding wf_ts_regex_def progress_simps + by (auto simp add: 1 list_all2_Cons2 upt_eq_Cons_conv + intro!: cInf_lower \_mono elim!: order.trans[rotated] simp del: upt_Suc split: if_splits list.splits) + moreover + have "Suc i \ progress \ P' (Formula.MatchF I r) (Suc j)" + if "enat t + right I < enat (case nts' of [] \ \ \ j | nt # x \ nt)" + proof - + from that obtain m where m: "right I = enat m" by (cases "right I") auto + have \_min: "\ \ (min j k) = min (\ \ j) (\ \ k)" for k + by (simp add: min_of_mono monoI) + have le_progress_iff[simp]: "Suc j \ progress \ P' \ (Suc j) \ progress \ P' \ (Suc j) = (Suc j)" for \ + using wf_envs_progress_le[OF MMatchF.prems(2), of \] by auto + have min_Suc[simp]: "min j (Suc j) = j" by auto + let ?X = "{i. \k. k < Suc j \ k \ progress_regex \ P' r (Suc j) \ enat (\ \ k) \ enat (\ \ i) + right I}" + let ?min = "min j (progress_regex \ P' r (Suc j))" + have "\ \ ?min \ \ \ j" + by (rule \_mono) auto + from m have "?X \ {}" + by (auto dest!: less_\D add_lessD1 simp: not_le not_less) + from m show ?thesis + using that nts' wf_envs_progress_regex_le[OF MMatchF.prems(2), of r] + unfolding wf_ts_regex_def progress_simps + by (intro cInf_greatest[OF \?X \ {}\]) + (auto simp: 1 not_le not_less list_all2_Cons2 upt_eq_Cons_conv less_Suc_eq + simp del: upt_Suc split: list.splits if_splits + dest!: spec[of _ "?min"] less_le_trans[of "\ \ i + m" "\ \ _" "\ \ _ + m"] less_\D) + qed + moreover have *: "k < progress_regex \ P' r (Suc j)" if + "enat (\ \ i) + right I < enat (case nts' of [] \ \ \ j | nt # x \ nt)" + "enat (\ \ k - \ \ i) \ right I" for k + proof - + from that(1,2) obtain m where "right I = enat m" + "\ \ i + m < (case nts' of [] \ \ \ j | nt # x \ nt)" "\ \ k - \ \ i \ m" + by (cases "right I") auto + with nts' wf_envs_progress_regex_le[OF MMatchF.prems(2), of r] + show ?thesis + unfolding wf_ts_regex_def le_diff_conv + by (auto simp: not_le list_all2_Cons2 upt_eq_Cons_conv less_Suc_eq add.commute + simp del: upt_Suc split: list.splits if_splits dest!: le_less_trans[of "\ \ k"] less_\D) + qed + ultimately show ?case using Cons.prems Suc_i_aux'[simplified] + unfolding \a = (t, rels, rel)\ + by (auto simp: 1 sat.simps upt_conv_Cons dest!: Cons.IH[OF _ aux' Suc_i_aux'] + simp del: upt_Suc split: if_splits prod.splits intro!: iff_exI qtable_cong[OF 3 refl]) + + qed + note this[OF progress_mono_gen[OF le_SucI, OF order.refl] conjunct1[OF update1] conjunct2[OF update1]] + } + note update = this[OF refl, rotated] + with MMatchF.prems(2) show ?case using \s + by (auto simp: eq mr mrs safe map_split_alt list.rel_flip[symmetric, of _ \s \s] + list_all3_map map2_map_map list_all3_list_all2_conv list.rel_map intro!: wf_mformula.intros + elim!: list.rel_mono_strong mbufnt_take_add'(1)[OF _ wf_envs_P_simps[OF MMatchF.prems(2)] safe mr buf nts_snoc] + mbufnt_take_add'(2)[OF _ wf_envs_P_simps[OF MMatchF.prems(2)] safe mr buf nts_snoc] + dest!: MMatchF.IH[OF _ _ MMatchF.prems(2)] update split: prod.splits) +qed + + +subsubsection \Monitor step\ + +lemma (in maux) wf_mstate_mstep: "wf_mstate \ \ R st \ last_ts \ \ snd tdb \ + wf_mstate \ (psnoc \ tdb) R (snd (mstep (map_prod mk_db id tdb) st))" + unfolding wf_mstate_def mstep_def Let_def + by (fastforce simp add: progress_mono le_imp_diff_is_add split: prod.splits + elim!: prefix_of_psnocE dest: meval[OF _ wf_envs_mk_db] list_all2_lengthD) + +definition "flatten_verdicts Vs = (\ (set (map (\(i, X). (\v. (i, v)) ` X) Vs)))" + +lemma flatten_verdicts_append[simp]: + "flatten_verdicts (Vs @ Us) = flatten_verdicts Vs \ flatten_verdicts Us" + by (induct Vs) (auto simp: flatten_verdicts_def) + +lemma (in maux) mstep_output_iff: + assumes "wf_mstate \ \ R st" "last_ts \ \ snd tdb" "prefix_of (psnoc \ tdb) \" "mem_restr R v" + shows "(i, v) \ flatten_verdicts (fst (mstep (map_prod mk_db id tdb) st)) \ + progress \ Map.empty \ (plen \) \ i \ i < progress \ Map.empty \ (Suc (plen \)) \ + wf_tuple (Formula.nfv \) (Formula.fv \) v \ Formula.sat \ Map.empty (map the v) i \" +proof - + from prefix_of_psnocE[OF assms(3,2)] have "prefix_of \ \" + "\ \ (plen \) = fst tdb" "\ \ (plen \) = snd tdb" by auto + moreover from assms(1) \prefix_of \ \\ have "mstate_n st = Formula.nfv \" + "mstate_i st = progress \ Map.empty \ (plen \)" "wf_mformula \ (plen \) Map.empty Map.empty (mstate_n st) R (mstate_m st) \" + unfolding wf_mstate_def by blast+ + moreover from meval[OF \wf_mformula \ (plen \) Map.empty Map.empty (mstate_n st) R (mstate_m st) \\ wf_envs_mk_db] obtain Vs st' where + "meval (mstate_n st) (\ \ (plen \)) (mk_db (\ \ (plen \))) (mstate_m st) = (Vs, st')" + "wf_mformula \ (Suc (plen \)) Map.empty Map.empty (mstate_n st) R st' \" + "list_all2 (\i. qtable (mstate_n st) (fv \) (mem_restr R) (\v. Formula.sat \ Map.empty (map the v) i \)) + [progress \ Map.empty \ (plen \).. Map.empty \ (Suc (plen \))] Vs" by blast + moreover from this assms(4) have "qtable (mstate_n st) (fv \) (mem_restr R) + (\v. Formula.sat \ Map.empty (map the v) i \) (Vs ! (i - progress \ Map.empty \ (plen \)))" + if "progress \ Map.empty \ (plen \) \ i" "i < progress \ Map.empty \ (Suc (plen \))" + using that by (auto simp: list_all2_conv_all_nth + dest!: spec[of _ "(i - progress \ Map.empty \ (plen \))"]) + ultimately show ?thesis + using assms(4) unfolding mstep_def Let_def flatten_verdicts_def + by (auto simp: in_set_enumerate_eq list_all2_conv_all_nth progress_mono le_imp_diff_is_add + elim!: in_qtableE in_qtableI intro!: bexI[of _ "(i, Vs ! (i - progress \ Map.empty \ (plen \)))"]) +qed + + +subsubsection \Monitor function\ + +context maux +begin + +definition minit_safe where + "minit_safe \ = (if mmonitorable_exec \ then minit \ else undefined)" + +lemma minit_safe_minit: "mmonitorable \ \ minit_safe \ = minit \" + unfolding minit_safe_def monitorable_formula_code by simp + +lemma mstep_mverdicts: + assumes wf: "wf_mstate \ \ R st" + and le[simp]: "last_ts \ \ snd tdb" + and restrict: "mem_restr R v" + shows "(i, v) \ flatten_verdicts (fst (mstep (map_prod mk_db id tdb) st)) \ + (i, v) \ mverdicts \ (psnoc \ tdb) - mverdicts \ \" +proof - + obtain \ where p2: "prefix_of (psnoc \ tdb) \" + using ex_prefix_of by blast + with le have p1: "prefix_of \ \" by (blast elim!: prefix_of_psnocE) + show ?thesis + unfolding verimon.verdicts_def + by (auto 0 3 simp: p2 progress_prefix_conv[OF _ p1] sat_prefix_conv[OF _ p1] not_less + dest: mstep_output_iff[OF wf le p2 restrict, THEN iffD1] spec[of _ \] + mstep_output_iff[OF wf le _ restrict, THEN iffD1] verimon.progress_sat_cong[OF p1] + intro: mstep_output_iff[OF wf le p2 restrict, THEN iffD2] p1) +qed + +primrec msteps0 where + "msteps0 [] st = ([], st)" +| "msteps0 (tdb # \) st = + (let (V', st') = mstep (map_prod mk_db id tdb) st; (V'', st'') = msteps0 \ st' in (V' @ V'', st''))" + +primrec msteps0_stateless where + "msteps0_stateless [] st = []" +| "msteps0_stateless (tdb # \) st = (let (V', st') = mstep (map_prod mk_db id tdb) st in V' @ msteps0_stateless \ st')" + +lemma msteps0_msteps0_stateless: "fst (msteps0 w st) = msteps0_stateless w st" + by (induct w arbitrary: st) (auto simp: split_beta) + +lift_definition msteps :: "Formula.prefix \ ('msaux, 'muaux) mstate \ (nat \ event_data table) list \ ('msaux, 'muaux) mstate" + is msteps0 . + +lift_definition msteps_stateless :: "Formula.prefix \ ('msaux, 'muaux) mstate \ (nat \ event_data table) list" + is msteps0_stateless . + +lemma msteps_msteps_stateless: "fst (msteps w st) = msteps_stateless w st" + by transfer (rule msteps0_msteps0_stateless) + +lemma msteps0_snoc: "msteps0 (\ @ [tdb]) st = + (let (V', st') = msteps0 \ st; (V'', st'') = mstep (map_prod mk_db id tdb) st' in (V' @ V'', st''))" + by (induct \ arbitrary: st) (auto split: prod.splits) + +lemma msteps_psnoc: "last_ts \ \ snd tdb \ msteps (psnoc \ tdb) st = + (let (V', st') = msteps \ st; (V'', st'') = mstep (map_prod mk_db id tdb) st' in (V' @ V'', st''))" + by transfer' (auto simp: msteps0_snoc split: list.splits prod.splits if_splits) + +definition monitor where + "monitor \ \ = msteps_stateless \ (minit_safe \)" + +lemma Suc_length_conv_snoc: "(Suc n = length xs) = (\y ys. xs = ys @ [y] \ length ys = n)" + by (cases xs rule: rev_cases) auto + +lemma wf_mstate_msteps: "wf_mstate \ \ R st \ mem_restr R v \ \ \ \' \ + X = msteps (pdrop (plen \) \') st \ wf_mstate \ \' R (snd X) \ + ((i, v) \ flatten_verdicts (fst X)) = ((i, v) \ mverdicts \ \' - mverdicts \ \)" +proof (induct "plen \' - plen \" arbitrary: X st \ \') + case 0 + from 0(1,4,5) have "\ = \'" "X = ([], st)" + by (transfer; auto)+ + with 0(2) show ?case unfolding flatten_verdicts_def by simp +next + case (Suc x) + from Suc(2,5) obtain \'' tdb where "x = plen \'' - plen \" "\ \ \''" + "\' = psnoc \'' tdb" "pdrop (plen \) (psnoc \'' tdb) = psnoc (pdrop (plen \) \'') tdb" + "last_ts (pdrop (plen \) \'') \ snd tdb" "last_ts \'' \ snd tdb" + "\'' \ psnoc \'' tdb" + proof (atomize_elim, transfer, elim exE, goal_cases prefix) + case (prefix _ _ \' _ \_tdb) + then show ?case + proof (cases \_tdb rule: rev_cases) + case (snoc \ tdb) + with prefix show ?thesis + by (intro bexI[of _ "\' @ \"] exI[of _ tdb]) + (force simp: sorted_append append_eq_Cons_conv split: list.splits if_splits)+ + qed simp + qed + with Suc(1)[OF this(1) Suc.prems(1,2) this(2) refl] Suc.prems show ?case + unfolding msteps_msteps_stateless[symmetric] + by (auto simp: msteps_psnoc split_beta mstep_mverdicts + dest: verimon.verdicts_mono[THEN set_mp, rotated] intro!: wf_mstate_mstep) +qed + +lemma wf_mstate_msteps_stateless: + assumes "wf_mstate \ \ R st" "mem_restr R v" "\ \ \'" + shows "(i, v) \ flatten_verdicts (msteps_stateless (pdrop (plen \) \') st) \ (i, v) \ mverdicts \ \' - mverdicts \ \" + using wf_mstate_msteps[OF assms refl] unfolding msteps_msteps_stateless by simp + +lemma wf_mstate_msteps_stateless_UNIV: "wf_mstate \ \ UNIV st \ \ \ \' \ + flatten_verdicts (msteps_stateless (pdrop (plen \) \') st) = mverdicts \ \' - mverdicts \ \" + by (auto dest: wf_mstate_msteps_stateless[OF _ mem_restr_UNIV]) + +lemma mverdicts_Nil: "mverdicts \ pnil = {}" + unfolding verimon.verdicts_def + by (auto intro: ex_prefix_of) + +lemma wf_mstate_minit_safe: "mmonitorable \ \ wf_mstate \ pnil R (minit_safe \)" + using wf_mstate_minit minit_safe_minit mmonitorable_def by metis + +lemma monitor_mverdicts: "mmonitorable \ \ flatten_verdicts (monitor \ \) = mverdicts \ \" + unfolding monitor_def + by (subst wf_mstate_msteps_stateless_UNIV[OF wf_mstate_minit_safe, simplified]) + (auto simp: mmonitorable_def mverdicts_Nil) + +subsection \Collected correctness results\ + +text \We summarize the main results proved above. +\begin{enumerate} +\item The term @{term mverdicts} describes semantically the monitor's expected behaviour: +\begin{itemize} +\item @{thm[source] verimon.mono_monitor}: @{thm verimon.mono_monitor[no_vars]} +\item @{thm[source] verimon.sound_monitor}: @{thm verimon.sound_monitor[no_vars]} +\item @{thm[source] verimon.complete_monitor}: @{thm verimon.complete_monitor[no_vars]} +\item @{thm[source] verimon.monitor_slice}: @{thm verimon.monitor_slice[no_vars]} +\end{itemize} +\item The executable monitor's online interface @{term minit_safe} and @{term mstep} + preserves the invariant @{term wf_mstate} and produces the the verdicts according + to @{term mverdicts}: +\begin{itemize} +\item @{thm[source] wf_mstate_minit_safe}: @{thm wf_mstate_minit_safe[no_vars]} +\item @{thm[source] wf_mstate_mstep}: @{thm wf_mstate_mstep[no_vars]} +\item @{thm[source] mstep_mverdicts}: @{thm mstep_mverdicts[no_vars]} +\end{itemize} +\item The executable monitor's offline interface @{term monitor} implements @{term mverdicts}: +\begin{itemize} +\item @{thm[source] monitor_mverdicts}: @{thm monitor_mverdicts[no_vars]} +\end{itemize} +\end{enumerate} +\ + +end \ \context @{locale maux}\ + +(*<*) +end +(*>*) diff --git a/thys/MFODL_Monitor_Optimized/Monitor_Code.thy b/thys/MFODL_Monitor_Optimized/Monitor_Code.thy new file mode 100644 --- /dev/null +++ b/thys/MFODL_Monitor_Optimized/Monitor_Code.thy @@ -0,0 +1,23 @@ +(*<*) +theory Monitor_Code + imports Monitor_Impl +begin +(*>*) + +export_code convert_multiway minit_safe mstep mmonitorable_exec + checking OCaml? + +export_code + (*basic types*) + nat_of_integer integer_of_nat int_of_integer integer_of_int enat + String.explode String.implode interval mk_db + RBT_set rbt_empty rbt_insert rbt_fold + (*term, formula, and regex constructors*) + EInt Formula.Var Formula.Agg_Cnt Formula.Pred Regex.Skip Regex.Wild + (*main functions*) + convert_multiway minit_safe mstep mmonitorable_exec + in OCaml module_name Monitor file_prefix "verified" + +(*<*) +end +(*>*) \ No newline at end of file diff --git a/thys/MFODL_Monitor_Optimized/Monitor_Impl.thy b/thys/MFODL_Monitor_Optimized/Monitor_Impl.thy new file mode 100644 --- /dev/null +++ b/thys/MFODL_Monitor_Optimized/Monitor_Impl.thy @@ -0,0 +1,438 @@ +(*<*) +theory Monitor_Impl + imports Monitor + Optimized_MTL + Event_Data + "HOL-Library.Code_Target_Nat" + Containers.Containers +begin +(*>*) + +section \Instantiation of the generic algorithm and code setup\ + +lemma [code_unfold del, symmetric, code_post del]: "card \ Cardinality.card'" by simp +declare [[code drop: card]] Set_Impl.card_code[code] + +instantiation enat :: set_impl begin +definition set_impl_enat :: "(enat, set_impl) phantom" where + "set_impl_enat = phantom set_RBT" + +instance .. +end + +derive ccompare Formula.trm +derive (eq) ceq Formula.trm +derive (rbt) set_impl Formula.trm +derive (eq) ceq Monitor.mregex +derive ccompare Monitor.mregex +derive (rbt) set_impl Monitor.mregex +derive (rbt) mapping_impl Monitor.mregex +derive (no) cenum Monitor.mregex +derive (rbt) set_impl event_data +derive (rbt) mapping_impl event_data + +definition add_new_mmuaux' :: "args \ event_data table \ event_data table \ ts \ event_data mmuaux \ + event_data mmuaux" where + "add_new_mmuaux' = add_new_mmuaux" + +interpretation muaux valid_mmuaux init_mmuaux add_new_mmuaux' length_mmuaux eval_mmuaux + using valid_init_mmuaux valid_add_new_mmuaux valid_length_mmuaux valid_eval_mmuaux + unfolding add_new_mmuaux'_def + by unfold_locales assumption+ + +global_interpretation verimon_maux: maux "\_ cur (t, aux) auxlist. t = cur \ aux = auxlist" "\_. (0, [])" + "\args nt (t, auxlist). (nt, filter (\(t, rel). enat (nt - t) \ right (args_ivl args)) auxlist)" + "\args rel1 (t, auxlist). (t, map (\(t, rel). (t, join rel (args_pos args) rel1)) auxlist)" + "\args rel2 (cur, auxlist). (cur, (case auxlist of + [] => [(cur, rel2)] + | ((t, y) # ts) \ if t = cur then (t, y \ rel2) # ts else (cur, rel2) # auxlist))" + "\args (cur, auxlist). foldr (\) [rel. (t, rel) \ auxlist, left (args_ivl args) \ cur - t] {}" + "\_ cur (t, aux) auxlist. t = cur \ aux = auxlist" "\_. (0, [])" + "\args rel1 rel2 nt (t, auxlist). (nt, update_until args rel1 rel2 nt auxlist)" + "\_ (_, auxlist). length auxlist" + "\args nt (t, auxlist). (let (res, auxlist') = eval_until (args_ivl args) nt auxlist in (res, (t, auxlist')))" + by unfold_locales auto + +global_interpretation default_maux: maux valid_mmsaux "init_mmsaux :: _ \ event_data mmsaux" add_new_ts_mmsaux gc_join_mmsaux add_new_table_mmsaux result_mmsaux + valid_mmuaux "init_mmuaux :: _ \ event_data mmuaux" add_new_mmuaux' length_mmuaux eval_mmuaux + defines minit0 = "maux.minit0 (init_mmsaux :: _ \ event_data mmsaux) (init_mmuaux :: _ \ event_data mmuaux) :: _ \ Formula.formula \ _" + and minit = "maux.minit (init_mmsaux :: _ \ event_data mmsaux) (init_mmuaux :: _ \ event_data mmuaux) :: Formula.formula \ _" + and minit_safe = "maux.minit_safe (init_mmsaux :: _ \ event_data mmsaux) (init_mmuaux :: _ \ event_data mmuaux) :: Formula.formula \ _" + and update_since = "maux.update_since add_new_ts_mmsaux gc_join_mmsaux add_new_table_mmsaux (result_mmsaux :: _ \ event_data mmsaux \ event_data table)" + and meval = "maux.meval add_new_ts_mmsaux gc_join_mmsaux add_new_table_mmsaux (result_mmsaux :: _ \ event_data mmsaux \ _) add_new_mmuaux' (eval_mmuaux :: _ \ _ \ event_data mmuaux \ _)" + and mstep = "maux.mstep add_new_ts_mmsaux gc_join_mmsaux add_new_table_mmsaux (result_mmsaux :: _ \ event_data mmsaux \ _) add_new_mmuaux' (eval_mmuaux :: _ \ _ \ event_data mmuaux \ _)" + and msteps0_stateless = "maux.msteps0_stateless add_new_ts_mmsaux gc_join_mmsaux add_new_table_mmsaux (result_mmsaux :: _ \ event_data mmsaux \ _) add_new_mmuaux' (eval_mmuaux :: _ \ _ \ event_data mmuaux \ _)" + and msteps_stateless = "maux.msteps_stateless add_new_ts_mmsaux gc_join_mmsaux add_new_table_mmsaux (result_mmsaux :: _ \ event_data mmsaux \ _) add_new_mmuaux' (eval_mmuaux :: _ \ _ \ event_data mmuaux \ _)" + and monitor = "maux.monitor init_mmsaux add_new_ts_mmsaux gc_join_mmsaux add_new_table_mmsaux (result_mmsaux :: _ \ event_data mmsaux \ _) init_mmuaux add_new_mmuaux' (eval_mmuaux :: _ \ _ \ event_data mmuaux \ _)" + by unfold_locales + +lemma image_these: "f ` Option.these X = Option.these (map_option f ` X)" + by (force simp: in_these_eq Bex_def image_iff map_option_case split: option.splits) + +thm default_maux.meval.simps(2) + +lemma meval_MPred: "meval n t db (MPred e ts) = + (case Mapping.lookup db e of None \ [{}] | Some Xs \ map (\X. \v \ X. + (set_option (map_option (\f. Table.tabulate f 0 n) (match ts v)))) Xs, MPred e ts)" + by (force split: option.splits simp: Option.these_def image_iff) + +lemmas meval_code[code] = default_maux.meval.simps(1) meval_MPred default_maux.meval.simps(3-) + +definition mk_db :: "(Formula.name \ event_data list set) list \ _" where + "mk_db t = Monitor.mk_db (\n \ set (map fst t). (\v. (n, v)) ` the (map_of t n))" + +definition rbt_fold :: "_ \ event_data tuple set_rbt \ _ \ _" where + "rbt_fold = RBT_Set2.fold" + +definition rbt_empty :: "event_data list set_rbt" where + "rbt_empty = RBT_Set2.empty" + +definition rbt_insert :: "_ \ _ \ event_data list set_rbt" where + "rbt_insert = RBT_Set2.insert" + +lemma saturate_commute: + assumes "\s. r \ g s" "\s. g (insert r s) = g s" "\s. r \ s \ h s = g s" + and terminates: "mono g" "\X. X \ C \ g X \ C" "finite C" +shows "saturate g {} = saturate h {r}" +proof (cases "g {} = {r}") + case True + with assms have "g {r} = {r}" "h {r} = {r}" by auto + with True show ?thesis + by (subst (1 2) saturate_code; subst saturate_code) (simp add: Let_def) +next + case False + then show ?thesis + unfolding saturate_def while_def + using while_option_finite_subset_Some[OF terminates] assms(1-3) + by (subst while_option_commute_invariant[of "\S. S = {} \ r \ S" "\S. g S \ S" g "\S. h S \ S" "insert r" h "{}", symmetric]) + (auto 4 4 dest: while_option_stop[of "\S. g S \ S" g "{}"]) +qed + +definition "RPDs_aux = saturate (\S. S \ \ (RPD ` S))" + +lemma RPDs_aux_code[code]: + "RPDs_aux S = (let S' = S \ Set.bind S RPD in if S' \ S then S else RPDs_aux S')" + unfolding RPDs_aux_def bind_UNION + by (subst saturate_code) auto + +declare RPDs_code[code del] +lemma RPDs_code[code]: "RPDs r = RPDs_aux {r}" + unfolding RPDs_aux_def RPDs_code + by (rule saturate_commute[where C="RPDs r"]) + (auto 0 3 simp: mono_def subset_singleton_iff RPDs_refl RPDs_trans finite_RPDs) + +definition "LPDs_aux = saturate (\S. S \ \ (LPD ` S))" + +lemma LPDs_aux_code[code]: + "LPDs_aux S = (let S' = S \ Set.bind S LPD in if S' \ S then S else LPDs_aux S')" + unfolding LPDs_aux_def bind_UNION + by (subst saturate_code) auto + +declare LPDs_code[code del] +lemma LPDs_code[code]: "LPDs r = LPDs_aux {r}" + unfolding LPDs_aux_def LPDs_code + by (rule saturate_commute[where C="LPDs r"]) + (auto 0 3 simp: mono_def subset_singleton_iff LPDs_refl LPDs_trans finite_LPDs) + +lemma is_empty_table_unfold [code_unfold]: + "X = empty_table \ Set.is_empty X" + "empty_table = X \ Set.is_empty X" + "Cardinality.eq_set X empty_table \ Set.is_empty X" + "Cardinality.eq_set empty_table X \ Set.is_empty X" + "set_eq X empty_table \ Set.is_empty X" + "set_eq empty_table X \ Set.is_empty X" + "X = (set_empty impl) \ Set.is_empty X" + "(set_empty impl) = X \ Set.is_empty X" + "Cardinality.eq_set X (set_empty impl) \ Set.is_empty X" + "Cardinality.eq_set (set_empty impl) X \ Set.is_empty X" + "set_eq X (set_empty impl) \ Set.is_empty X" + "set_eq (set_empty impl) X \ Set.is_empty X" + unfolding set_eq_def set_empty_def empty_table_def Set.is_empty_def Cardinality.eq_set_def by auto + +lemma tabulate_rbt_code[code]: "Monitor.mrtabulate (xs :: mregex list) f = + (case ID CCOMPARE(mregex) of None \ Code.abort (STR ''tabulate RBT_Mapping: ccompare = None'') (\_. Monitor.mrtabulate (xs :: mregex list) f) + | _ \ RBT_Mapping (RBT_Mapping2.bulkload (List.map_filter (\k. let fk = f k in if fk = empty_table then None else Some (k, fk)) xs)))" + unfolding mrtabulate.abs_eq RBT_Mapping_def + by (auto split: option.splits) + +lemma combine_Mapping[code]: + fixes t :: "('a :: ccompare, 'b) mapping_rbt" shows + "Mapping.combine f (RBT_Mapping t) (RBT_Mapping u) = + (case ID CCOMPARE('a) of None \ Code.abort (STR ''combine RBT_Mapping: ccompare = None'') (\_. Mapping.combine f (RBT_Mapping t) (RBT_Mapping u)) + | Some _ \ RBT_Mapping (RBT_Mapping2.join (\_. f) t u))" + by (auto simp add: Mapping.combine.abs_eq Mapping_inject lookup_join split: option.split) + +lemma upd_set_empty[simp]: "upd_set m f {} = m" + by transfer auto + +lemma upd_set_insert[simp]: "upd_set m f (insert x A) = Mapping.update x (f x) (upd_set m f A)" + by (rule mapping_eqI) (auto simp: Mapping_lookup_upd_set Mapping.lookup_update') + +lemma upd_set_fold: + assumes "finite A" + shows "upd_set m f A = Finite_Set.fold (\a. Mapping.update a (f a)) m A" +proof - + interpret comp_fun_idem "\a. Mapping.update a (f a)" + by unfold_locales (transfer; auto simp: fun_eq_iff)+ + from assms show ?thesis + by (induct A arbitrary: m rule: finite.induct) auto +qed + +lift_definition upd_cfi :: "('a \ 'b) \ ('a, ('a, 'b) mapping) comp_fun_idem" + is "\f a m. Mapping.update a (f a) m" + by unfold_locales (transfer; auto simp: fun_eq_iff)+ + +lemma upd_set_code[code]: + "upd_set m f A = (if finite A then set_fold_cfi (upd_cfi f) m A else Code.abort (STR ''upd_set: infinite'') (\_. upd_set m f A))" + by (transfer fixing: m) (auto simp: upd_set_fold) + +lemma lexordp_eq_code[code]: "lexordp_eq xs ys \ (case xs of [] \ True + | x # xs \ (case ys of [] \ False + | y # ys \ if x < y then True else if x > y then False else lexordp_eq xs ys))" + by (subst lexordp_eq.simps) (auto split: list.split) + +definition "filter_set m X t = Mapping.filter (filter_cond X m t) m" + +declare [[code drop: shift_end]] +declare shift_end.simps[folded filter_set_def, code] + +lemma upd_set'_empty[simp]: "upd_set' m d f {} = m" + by (rule mapping_eqI) (auto simp add: upd_set'_lookup) + +lemma upd_set'_insert: "d = f d \ (\x. f (f x) = f x) \ upd_set' m d f (insert x A) = + (let m' = (upd_set' m d f A) in case Mapping.lookup m' x of None \ Mapping.update x d m' + | Some v \ Mapping.update x (f v) m')" + by (rule mapping_eqI) (auto simp: upd_set'_lookup Mapping.lookup_update' split: option.splits) + +lemma upd_set'_aux1: "upd_set' Mapping.empty d f {b. b = k \ (a, b) \ A} = + Mapping.update k d (upd_set' Mapping.empty d f {b. (a, b) \ A})" + by (rule mapping_eqI) (auto simp add: Let_def upd_set'_lookup Mapping.lookup_update' + Mapping.lookup_empty split: option.splits) + +lemma upd_set'_aux2: "Mapping.lookup m k = None \ upd_set' m d f {b. b = k \ (a, b) \ A} = + Mapping.update k d (upd_set' m d f {b. (a, b) \ A})" + by (rule mapping_eqI) (auto simp add: upd_set'_lookup Mapping.lookup_update' split: option.splits) + +lemma upd_set'_aux3: "Mapping.lookup m k = Some v \ upd_set' m d f {b. b = k \ (a, b) \ A} = + Mapping.update k (f v) (upd_set' m d f {b. (a, b) \ A})" + by (rule mapping_eqI) (auto simp add: upd_set'_lookup Mapping.lookup_update' split: option.splits) + +lemma upd_set'_aux4: "k \ fst ` A \ upd_set' Mapping.empty d f {b. (k, b) \ A} = Mapping.empty" + by (rule mapping_eqI) (auto simp add: upd_set'_lookup Mapping.lookup_update' Domain.DomainI fst_eq_Domain + split: option.splits) + +lemma upd_nested_empty[simp]: "upd_nested m d f {} = m" + by (rule mapping_eqI) (auto simp add: upd_nested_lookup split: option.splits) + +definition upd_nested_step :: "'c \ ('c \ 'c) \ 'a \ 'b \ ('a, ('b, 'c) mapping) mapping \ + ('a, ('b, 'c) mapping) mapping" where + "upd_nested_step d f x m = (case x of (k, k') \ + (case Mapping.lookup m k of Some m' \ + (case Mapping.lookup m' k' of Some v \ Mapping.update k (Mapping.update k' (f v) m') m + | None \ Mapping.update k (Mapping.update k' d m') m) + | None \ Mapping.update k (Mapping.update k' d Mapping.empty) m))" + +lemma upd_nested_insert: + "d = f d \ (\x. f (f x) = f x) \ upd_nested m d f (insert x A) = + upd_nested_step d f x (upd_nested m d f A)" + unfolding upd_nested_step_def + using upd_set'_aux1[of d f _ _ A] upd_set'_aux2[of _ _ d f _ A] upd_set'_aux3[of _ _ _ d f _ A] + upd_set'_aux4[of _ A d f] + by (auto simp add: Let_def upd_nested_lookup upd_set'_lookup Mapping.lookup_update' + Mapping.lookup_empty split: option.splits prod.splits if_splits intro!: mapping_eqI) + +definition upd_nested_max_tstp where + "upd_nested_max_tstp m d X = upd_nested m d (max_tstp d) X" + +lemma upd_nested_max_tstp_fold: + assumes "finite X" + shows "upd_nested_max_tstp m d X = Finite_Set.fold (upd_nested_step d (max_tstp d)) m X" +proof - + interpret comp_fun_idem "upd_nested_step d (max_tstp d)" + by (unfold_locales; rule ext) + (auto simp add: comp_def upd_nested_step_def Mapping.lookup_update' Mapping.lookup_empty + update_update max_tstp_d_d max_tstp_idem' split: option.splits) + note upd_nested_insert' = upd_nested_insert[of d "max_tstp d", + OF max_tstp_d_d[symmetric] max_tstp_idem'] + show ?thesis + using assms + by (induct X arbitrary: m rule: finite.induct) + (auto simp add: upd_nested_max_tstp_def upd_nested_insert') +qed + +lift_definition upd_nested_max_tstp_cfi :: + "ts + tp \ ('a \ 'b, ('a, ('b, ts + tp) mapping) mapping) comp_fun_idem" + is "\d. upd_nested_step d (max_tstp d)" + by (unfold_locales; rule ext) + (auto simp add: comp_def upd_nested_step_def Mapping.lookup_update' Mapping.lookup_empty + update_update max_tstp_d_d max_tstp_idem' split: option.splits) + +lemma upd_nested_max_tstp_code[code]: + "upd_nested_max_tstp m d X = (if finite X then set_fold_cfi (upd_nested_max_tstp_cfi d) m X + else Code.abort (STR ''upd_nested_max_tstp: infinite'') (\_. upd_nested_max_tstp m d X))" + by transfer (auto simp add: upd_nested_max_tstp_fold) + +declare [[code drop: add_new_mmuaux']] +declare add_new_mmuaux'_def[unfolded add_new_mmuaux.simps, folded upd_nested_max_tstp_def, code] + +lemma filter_set_empty[simp]: "filter_set m {} t = m" + unfolding filter_set_def + by transfer (auto simp: fun_eq_iff split: option.splits) + +lemma filter_set_insert[simp]: "filter_set m (insert x A) t = (let m' = filter_set m A t in + case Mapping.lookup m' x of Some u \ if t = u then Mapping.delete x m' else m' | _ \ m')" + unfolding filter_set_def + by transfer (auto simp: fun_eq_iff Let_def Map_To_Mapping.map_apply_def split: option.splits) + +lemma filter_set_fold: + assumes "finite A" + shows "filter_set m A t = Finite_Set.fold (\a m. + case Mapping.lookup m a of Some u \ if t = u then Mapping.delete a m else m | _ \ m) m A" +proof - + interpret comp_fun_idem "\a m. + case Mapping.lookup m a of Some u \ if t = u then Mapping.delete a m else m | _ \ m" + by unfold_locales + (transfer; auto simp: fun_eq_iff Map_To_Mapping.map_apply_def split: option.splits)+ + from assms show ?thesis + by (induct A arbitrary: m rule: finite.induct) (auto simp: Let_def) +qed + +lift_definition filter_cfi :: "'b \ ('a, ('a, 'b) mapping) comp_fun_idem" + is "\t a m. + case Mapping.lookup m a of Some u \ if t = u then Mapping.delete a m else m | _ \ m" + by unfold_locales + (transfer; auto simp: fun_eq_iff Map_To_Mapping.map_apply_def split: option.splits)+ + +lemma filter_set_code[code]: + "filter_set m A t = (if finite A then set_fold_cfi (filter_cfi t) m A else Code.abort (STR ''upd_set: infinite'') (\_. filter_set m A t))" + by (transfer fixing: m) (auto simp: filter_set_fold) + +lemma filter_Mapping[code]: + fixes t :: "('a :: ccompare, 'b) mapping_rbt" shows + "Mapping.filter P (RBT_Mapping t) = + (case ID CCOMPARE('a) of None \ Code.abort (STR ''filter RBT_Mapping: ccompare = None'') (\_. Mapping.filter P (RBT_Mapping t)) + | Some _ \ RBT_Mapping (RBT_Mapping2.filter (case_prod P) t))" + by (auto simp add: Mapping.filter.abs_eq Mapping_inject split: option.split) + +definition "filter_join pos X m = Mapping.filter (join_filter_cond pos X) m" + +declare [[code drop: join_mmsaux]] +declare join_mmsaux.simps[folded filter_join_def, code] + +lemma filter_join_False_empty: "filter_join False {} m = m" + unfolding filter_join_def + by transfer (auto split: option.splits) + +lemma filter_join_False_insert: "filter_join False (insert a A) m = + filter_join False A (Mapping.delete a m)" +proof - + { + fix x + have "Mapping.lookup (filter_join False (insert a A) m) x = + Mapping.lookup (filter_join False A (Mapping.delete a m)) x" + by (auto simp add: filter_join_def Mapping.lookup_filter Mapping_lookup_delete + split: option.splits) + } + then show ?thesis + by (simp add: mapping_eqI) +qed + +lemma filter_join_False: + assumes "finite A" + shows "filter_join False A m = Finite_Set.fold Mapping.delete m A" +proof - + interpret comp_fun_idem "Mapping.delete" + by (unfold_locales; transfer) (fastforce simp add: comp_def)+ + from assms show ?thesis + by (induction A arbitrary: m rule: finite.induct) + (auto simp add: filter_join_False_empty filter_join_False_insert fold_fun_left_comm) +qed + +lift_definition filter_not_in_cfi :: "('a, ('a, 'b) mapping) comp_fun_idem" is "Mapping.delete" + by (unfold_locales; transfer) (fastforce simp add: comp_def)+ + +lemma filter_join_code[code]: + "filter_join pos A m = + (if \pos \ finite A \ card A < Mapping.size m then set_fold_cfi filter_not_in_cfi m A + else Mapping.filter (join_filter_cond pos A) m)" + unfolding filter_join_def + by (transfer fixing: m) (use filter_join_False in \auto simp add: filter_join_def\) + +definition set_minus :: "'a set \ 'a set \ 'a set" where + "set_minus X Y = X - Y" + +lift_definition remove_cfi :: "('a, 'a set) comp_fun_idem" + is "\b a. a - {b}" + by unfold_locales auto + +lemma set_minus_finite: + assumes fin: "finite Y" + shows "set_minus X Y = Finite_Set.fold (\a X. X - {a}) X Y" +proof - + interpret comp_fun_idem "\a X. X - {a}" + by unfold_locales auto + from assms show ?thesis + by (induction Y arbitrary: X rule: finite.induct) (auto simp add: set_minus_def) +qed + +lemma set_minus_code[code]: "set_minus X Y = + (if finite Y \ card Y < card X then set_fold_cfi remove_cfi X Y else X - Y)" + by transfer (use set_minus_finite in \auto simp add: set_minus_def\) + +declare [[code drop: bin_join]] +declare bin_join.simps[folded set_minus_def, code] + +definition remove_Union where + "remove_Union A X B = A - (\x \ X. B x)" + +lemma remove_Union_finite: + assumes "finite X" + shows "remove_Union A X B = Finite_Set.fold (\x A. A - B x) A X" +proof - + interpret comp_fun_idem "\x A. A - B x" + by unfold_locales auto + from assms show ?thesis + by (induct X arbitrary: A rule: finite_induct) (auto simp: remove_Union_def) +qed + +lift_definition remove_Union_cfi :: "('a \ 'b set) \ ('a, 'b set) comp_fun_idem" is "\B x A. A - B x" + by unfold_locales auto + +lemma remove_Union_code[code]: "remove_Union A X B = + (if finite X then set_fold_cfi (remove_Union_cfi B) A X else A - (\x \ X. B x))" + by (transfer fixing: A X B) (use remove_Union_finite[of X A B] in \auto simp add: remove_Union_def\) + +lemma tabulate_remdups: "Mapping.tabulate xs f = Mapping.tabulate (remdups xs) f" + by (transfer fixing: xs f) (auto simp: map_of_map_restrict) + +lift_definition clearjunk :: "(char list \ event_data list set) list \ (char list, event_data list set list) alist" is + "\t. List.map_filter (\(p, X). if X = {} then None else Some (p, [X])) (AList.clearjunk t)" + unfolding map_filter_def o_def list.map_comp + by (subst map_cong[OF refl, of _ _ fst]) (auto simp: map_filter_def distinct_map_fst_filter split: if_splits) + +lemma map_filter_snd_map_filter: "List.map_filter (\(a, b). if P b then None else Some (f a b)) xs = + map (\(a, b). f a b) (filter (\x. \ P (snd x)) xs)" + by (simp add: map_filter_def prod.case_eq_if) + +lemma mk_db_code_alist: + "mk_db t = Assoc_List_Mapping (clearjunk t)" + unfolding mk_db_def Assoc_List_Mapping_def + by (transfer' fixing: t) + (auto simp: map_filter_snd_map_filter fun_eq_iff map_of_map image_iff map_of_clearjunk + map_of_filter_apply dest: weak_map_of_SomeI intro!: bexI[rotated, OF map_of_SomeD] + split: if_splits option.splits) + +lemma mk_db_code[code]: + "mk_db t = Mapping.of_alist (List.map_filter (\(p, X). if X = {} then None else Some (p, [X])) (AList.clearjunk t))" + unfolding mk_db_def + by (transfer' fixing: t) (auto simp: map_filter_snd_map_filter fun_eq_iff map_of_map image_iff + map_of_clearjunk map_of_filter_apply dest: weak_map_of_SomeI intro!: bexI[rotated, OF map_of_SomeD] + split: if_splits option.splits) + +declare [[code drop: New_max_getIJ_genericJoin New_max_getIJ_wrapperGenericJoin]] +declare New_max.genericJoin.simps[folded remove_Union_def, code] +declare New_max.wrapperGenericJoin.simps[folded remove_Union_def, code] + +(*<*) +end +(*>*) diff --git a/thys/MFODL_Monitor_Optimized/Optimized_Join.thy b/thys/MFODL_Monitor_Optimized/Optimized_Join.thy new file mode 100644 --- /dev/null +++ b/thys/MFODL_Monitor_Optimized/Optimized_Join.thy @@ -0,0 +1,618 @@ +(*<*) +theory Optimized_Join + imports "Generic_Join.Generic_Join_Correctness" +begin +(*>*) + +section \Optimized relational join\ + +subsection \Binary join\ + +definition join_mask :: "nat \ nat set \ bool list" where + "join_mask n X = map (\i. i \ X) [0.. 'a tuple \ 'a tuple" where + "proj_tuple [] [] = []" +| "proj_tuple (True # bs) (a # as) = a # proj_tuple bs as" +| "proj_tuple (False # bs) (a # as) = None # proj_tuple bs as" +| "proj_tuple (b # bs) [] = []" +| "proj_tuple [] (a # as) = []" + +lemma proj_tuple_replicate: "(\i. i \ set bs \ \i) \ length bs = length as \ + proj_tuple bs as = replicate (length bs) None" + by (induction bs as rule: proj_tuple.induct) fastforce+ + +lemma proj_tuple_join_mask_empty: "length as = n \ + proj_tuple (join_mask n {}) as = replicate n None" + using proj_tuple_replicate[of "join_mask n {}"] by (auto simp add: join_mask_def) + +lemma proj_tuple_alt: "proj_tuple bs as = map2 (\b a. if b then a else None) bs as" + by (induction bs as rule: proj_tuple.induct) auto + +lemma map2_map: "map2 f (map g [0..i. f (g i) (as ! i)) [0.. + proj_tuple (join_mask n X) as = restrict X as" + by (auto simp add: restrict_def proj_tuple_alt join_mask_def map2_map) + +lemma wf_tuple_proj_idle: + assumes wf: "wf_tuple n X as" + shows "proj_tuple (join_mask n X) as = as" + using proj_tuple_join_mask_restrict[of as n X, unfolded restrict_idle[OF wf]] wf + by (auto simp add: wf_tuple_def) + +lemma wf_tuple_change_base: + assumes wf: "wf_tuple n X as" + and mask: "join_mask n X = join_mask n Y" + shows "wf_tuple n Y as" + using wf mask by (auto simp add: wf_tuple_def join_mask_def) + +definition proj_tuple_in_join :: "bool \ bool list \ 'a tuple \ 'a table \ bool" where + "proj_tuple_in_join pos bs as t = (if pos then proj_tuple bs as \ t else proj_tuple bs as \ t)" + +abbreviation "join_cond pos t \ (\as. if pos then as \ t else as \ t)" + +abbreviation "join_filter_cond pos t \ (\as _. join_cond pos t as)" + +lemma proj_tuple_in_join_mask_idle: + assumes wf: "wf_tuple n X as" + shows "proj_tuple_in_join pos (join_mask n X) as t \ join_cond pos t as" + using wf_tuple_proj_idle[OF wf] by (auto simp add: proj_tuple_in_join_def) + +lemma join_sub: + assumes "L \ R" "table n L t1" "table n R t2" + shows "join t2 pos t1 = {as \ t2. proj_tuple_in_join pos (join_mask n L) as t1}" + using assms proj_tuple_join_mask_restrict[of _ n L] join_restrict[of t2 n R t1 L pos] + wf_tuple_length restrict_idle + by (auto simp add: table_def proj_tuple_in_join_def sup.absorb1) fastforce+ + +lemma join_sub': + assumes "R \ L" "table n L t1" "table n R t2" + shows "join t2 True t1 = {as \ t1. proj_tuple_in_join True (join_mask n R) as t2}" + using assms proj_tuple_join_mask_restrict[of _ n R] join_restrict[of t2 n R t1 L True] + wf_tuple_length restrict_idle + by (auto simp add: table_def proj_tuple_in_join_def sup.absorb1 Un_absorb1) fastforce+ + +lemma join_eq: + assumes tab: "table n R t1" "table n R t2" + shows "join t2 pos t1 = (if pos then t2 \ t1 else t2 - t1)" + using join_sub[OF _ tab, of pos] tab(2) proj_tuple_in_join_mask_idle[of n R _ pos t1] + by (auto simp add: table_def) + +lemma join_no_cols: + assumes tab: "table n {} t1" "table n R t2" + shows "join t2 pos t1 = (if (pos \ replicate n None \ t1) then t2 else {})" + using join_sub[OF _ tab, of pos] tab(2) + by (auto simp add: table_def proj_tuple_in_join_def wf_tuple_length proj_tuple_join_mask_empty) + +lemma join_empty_left: "join {} pos t = {}" + by (auto simp add: join_def) + +lemma join_empty_right: "join t pos {} = (if pos then {} else t)" + by (auto simp add: join_def) + +fun bin_join :: "nat \ nat set \ 'a table \ bool \ nat set \ 'a table \ 'a table" where + "bin_join n A t pos A' t' = + (if t = {} then {} + else if t' = {} then (if pos then {} else t) + else if A' = {} then (if (pos \ replicate n None \ t') then t else {}) + else if A' = A then (if pos then t \ t' else t - t') + else if A' \ A then {as \ t. proj_tuple_in_join pos (join_mask n A') as t'} + else if A \ A' \ pos then {as \ t'. proj_tuple_in_join pos (join_mask n A) as t} + else join t pos t')" + +lemma bin_join_table: + assumes tab: "table n A t" "table n A' t'" + shows "bin_join n A t pos A' t' = join t pos t'" + using assms join_empty_left[of pos t'] join_empty_right[of t pos] + join_no_cols[OF _ assms(1), of t' pos] join_eq[of n A t' t pos] join_sub[OF _ assms(2,1)] + join_sub'[OF _ assms(2,1)] + by auto+ + +subsection \Multi-way join\ + +fun mmulti_join' :: "(nat set list \ nat set list \ 'a table list \ 'a table)" where + "mmulti_join' A_pos A_neg L = ( + let Q = set (zip A_pos L) in + let Q_neg = set (zip A_neg (drop (length A_pos) L)) in + New_max_getIJ_wrapperGenericJoin Q Q_neg)" + +lemma mmulti_join'_correct: + assumes "A_pos \ []" + and "list_all2 (\A X. table n A X \ wf_set n A) (A_pos @ A_neg) L" + shows "z \ mmulti_join' A_pos A_neg L \ wf_tuple n (\A\set A_pos. A) z \ + list_all2 (\A X. restrict A z \ X) A_pos (take (length A_pos) L) \ + list_all2 (\A X. restrict A z \ X) A_neg (drop (length A_pos) L)" +proof - + define Q where "Q = set (zip A_pos L)" + have Q_alt: "Q = set (zip A_pos (take (length A_pos) L))" + unfolding Q_def by (fastforce simp: in_set_zip) + define Q_neg where "Q_neg = set (zip A_neg (drop (length A_pos) L))" + let ?r = "mmulti_join' A_pos A_neg L" + have "?r = New_max_getIJ_wrapperGenericJoin Q Q_neg" + unfolding Q_def Q_neg_def by (simp del: New_max.wrapperGenericJoin.simps) + moreover have "card Q \ 1" + unfolding Q_def using assms(1,2) + by (auto simp: Suc_le_eq card_gt_0_iff zip_eq_Nil_iff) + moreover have "\(A, X)\(Q \ Q_neg). table n A X \ wf_set n A" + unfolding Q_alt Q_neg_def using assms(2) by (simp add: zip_append1 list_all2_iff) + ultimately have "z \ ?r \ wf_tuple n (\(A, X)\Q. A) z \ + (\(A, X)\Q. restrict A z \ X) \ (\(A, X)\Q_neg. restrict A z \ X)" + using New_max.wrapper_correctness case_prod_beta' by blast + moreover have "(\A\set A_pos. A) = (\(A, X)\Q. A)" proof - + from assms(2) have "length A_pos \ length L" by (auto dest!: list_all2_lengthD) + then show ?thesis + unfolding Q_alt + by (auto elim: in_set_impl_in_set_zip1[rotated, where ys="take (length A_pos) L"] + dest: set_zip_leftD) + qed + moreover have "\z. (\(A, X)\Q. restrict A z \ X) \ + list_all2 (\A X. restrict A z \ X) A_pos (take (length A_pos) L)" + unfolding Q_alt using assms(2) by (auto simp add: list_all2_iff) + moreover have "\z. (\(A, X)\Q_neg. restrict A z \ X) \ + list_all2 (\A X. restrict A z \ X) A_neg (drop (length A_pos) L)" + unfolding Q_neg_def using assms(2) by (auto simp add: list_all2_iff) + ultimately show ?thesis + unfolding Q_def Q_neg_def using assms(2) by simp +qed + +lemmas restrict_nested = New_max.restrict_nested + +lemma list_all2_opt_True: + assumes "list_all2 (\A X. table n A X \ wf_set n A) ((A_zs @ A_x # A_xs @ A_y # A_ys) @ A_neg) + ((zs @ x # xs @ y # ys) @ L_neg)" + "length A_xs = length xs" "length A_ys = length ys" "length A_zs = length zs" + shows "list_all2 (\A X. table n A X \ wf_set n A) + ((A_zs @ (A_x \ A_y) # A_xs @ A_ys) @ A_neg) ((zs @ join x True y # xs @ ys) @ L_neg)" +proof - + have assms_dest: "table n A_x x" "table n A_y y" "wf_set n A_x" "wf_set n A_y" + using assms + by (auto simp del: mmulti_join'.simps simp add: list_all2_append1 dest: list_all2_lengthD) + then have tabs: "table n (A_x \ A_y) (join x True y)" "wf_set n (A_x \ A_y)" + using join_table[of n A_x x A_y y True "A_x \ A_y", OF assms_dest(1,2)] assms_dest(3,4) + by (auto simp add: wf_set_def) + then show "list_all2 (\A X. table n A X \ wf_set n A) + ((A_zs @ (A_x \ A_y) # A_xs @ A_ys) @ A_neg) ((zs @ join x True y # xs @ ys) @ L_neg)" + using assms + by (auto simp del: mmulti_join'.simps simp add: list_all2_append1 list_all2_append2 + list_all2_Cons1 list_all2_Cons2 dest: list_all2_lengthD) fastforce +qed + +lemma mmulti_join'_opt_True: + assumes "list_all2 (\A X. table n A X \ wf_set n A) ((A_zs @ A_x # A_xs @ A_y # A_ys) @ A_neg) + ((zs @ x # xs @ y # ys) @ L_neg)" + "length A_xs = length xs" "length A_ys = length ys" "length A_zs = length zs" + shows "mmulti_join' (A_zs @ A_x # A_xs @ A_y # A_ys) A_neg ((zs @ x # xs @ y # ys) @ L_neg) = + mmulti_join' (A_zs @ (A_x \ A_y) # A_xs @ A_ys) A_neg + ((zs @ join x True y # xs @ ys) @ L_neg)" +proof - + have assms_dest: "table n A_x x" "table n A_y y" "wf_set n A_x" "wf_set n A_y" + using assms + by (auto simp del: mmulti_join'.simps simp add: list_all2_append1 dest: list_all2_lengthD) + then have tabs: "table n (A_x \ A_y) (join x True y)" "wf_set n (A_x \ A_y)" + using join_table[of n A_x x A_y y True "A_x \ A_y", OF assms_dest(1,2)] assms_dest(3,4) + by (auto simp add: wf_set_def) + then have list_all2': "list_all2 (\A X. table n A X \ wf_set n A) + ((A_zs @ (A_x \ A_y) # A_xs @ A_ys) @ A_neg) ((zs @ join x True y # xs @ ys) @ L_neg)" + using assms + by (auto simp del: mmulti_join'.simps simp add: list_all2_append1 list_all2_append2 + list_all2_Cons1 list_all2_Cons2 dest: list_all2_lengthD) fastforce + have res: "\z Z. wf_tuple n Z z \ A_x \ A_y \ Z \ + restrict (A_x \ A_y) z \ join x True y \ restrict A_x z \ x \ restrict A_y z \ y" + using join_restrict[of x n A_x y A_y True] wf_tuple_restrict_simple[of n _ _ "A_x \ A_y"] + assms_dest(1,2) + by (auto simp add: table_def restrict_nested Int_absorb2) + show ?thesis + proof (rule set_eqI, rule iffI) + fix z + assume "z \ mmulti_join' (A_zs @ A_x # A_xs @ A_y # A_ys) A_neg + ((zs @ x # xs @ y # ys) @ L_neg)" + then have z_in_dest: "wf_tuple n (\(set (A_zs @ A_x # A_xs @ A_y # A_ys))) z" + "list_all2 (\A. (\) (restrict A z)) A_zs zs" + "restrict A_x z \ x" + "list_all2 (\A. (\) (restrict A z)) A_ys ys" + "restrict A_y z \ y" + "list_all2 (\A. (\) (restrict A z)) A_xs xs" + "list_all2 (\A. (\) (restrict A z)) A_neg L_neg" + using mmulti_join'_correct[OF _ assms(1), of z] + by (auto simp del: mmulti_join'.simps simp add: assms list_all2_append1 + dest: list_all2_lengthD) + then show "z \ mmulti_join' (A_zs @ (A_x \ A_y) # A_xs @ A_ys) A_neg + ((zs @ join x True y # xs @ ys) @ L_neg)" + using mmulti_join'_correct[OF _ list_all2', of z] res[OF z_in_dest(1)] + by (auto simp add: assms list_all2_appendI le_supI2 Un_assoc simp del: mmulti_join'.simps + dest: list_all2_lengthD) + next + fix z + assume "z \ mmulti_join' (A_zs @ (A_x \ A_y) # A_xs @ A_ys) A_neg + ((zs @ join x True y # xs @ ys) @ L_neg)" + then have z_in_dest: "wf_tuple n (\(set (A_zs @ A_x # A_xs @ A_y # A_ys))) z" + "list_all2 (\A. (\) (restrict A z)) A_zs zs" + "restrict (A_x \ A_y) z \ join x True y" + "list_all2 (\A. (\) (restrict A z)) A_ys ys" + "list_all2 (\A. (\) (restrict A z)) A_xs xs" + "list_all2 (\A. (\) (restrict A z)) A_neg L_neg" + using mmulti_join'_correct[OF _ list_all2', of z] + by (auto simp del: mmulti_join'.simps simp add: assms list_all2_append Un_assoc + dest: list_all2_lengthD) + then show "z \ mmulti_join' (A_zs @ A_x # A_xs @ A_y # A_ys) A_neg + ((zs @ x # xs @ y # ys) @ L_neg)" + using mmulti_join'_correct[OF _ assms(1), of z] res[OF z_in_dest(1)] + by (auto simp add: assms list_all2_appendI le_supI2 Un_assoc simp del: mmulti_join'.simps + dest: list_all2_lengthD) + qed +qed + +lemma list_all2_opt_False: + assumes "list_all2 (\A X. table n A X \ wf_set n A) + ((A_zs @ A_x # A_xs) @ (A_ws @ A_y # A_ys)) ((zs @ x # xs) @ (ws @ y # ys))" + "length A_ws = length ws" "length A_xs = length xs" + "length A_ys = length ys" "length A_zs = length zs" + "A_y \ A_x" + shows "list_all2 (\A X. table n A X \ wf_set n A) + ((A_zs @ A_x # A_xs) @ (A_ws @ A_ys)) ((zs @ join x False y # xs) @ (ws @ ys))" +proof - + have assms_dest: "table n A_x x" "table n A_y y" "wf_set n A_x" "wf_set n A_y" + using assms + by (auto simp del: mmulti_join'.simps simp add: list_all2_append dest: list_all2_lengthD) + have tabs: "table n A_x (join x False y)" + using join_table[of n A_x x A_y y False A_x, OF assms_dest(1,2) assms(6)] assms(6) by auto + then show "list_all2 (\A X. table n A X \ wf_set n A) + ((A_zs @ A_x # A_xs) @ (A_ws @ A_ys)) ((zs @ join x False y # xs) @ (ws @ ys))" + using assms assms_dest(3) + by (auto simp del: mmulti_join'.simps simp add: list_all2_append1 list_all2_append2 + list_all2_Cons1 list_all2_Cons2 dest: list_all2_lengthD) fastforce +qed + +lemma mmulti_join'_opt_False: + assumes "list_all2 (\A X. table n A X \ wf_set n A) + ((A_zs @ A_x # A_xs) @ (A_ws @ A_y # A_ys)) ((zs @ x # xs) @ (ws @ y # ys))" + "length A_ws = length ws" "length A_xs = length xs" + "length A_ys = length ys" "length A_zs = length zs" + "A_y \ A_x" + shows "mmulti_join' (A_zs @ A_x # A_xs) (A_ws @ A_y # A_ys) ((zs @ x # xs) @ (ws @ y # ys)) = + mmulti_join' (A_zs @ A_x # A_xs) (A_ws @ A_ys) ((zs @ join x False y # xs) @ (ws @ ys))" +proof - + have assms_dest: "table n A_x x" "table n A_y y" "wf_set n A_x" "wf_set n A_y" + using assms + by (auto simp del: mmulti_join'.simps simp add: list_all2_append dest: list_all2_lengthD) + have tabs: "table n A_x (join x False y)" + using join_table[of n A_x x A_y y False A_x, OF assms_dest(1,2) assms(6)] assms(6) by auto + then have list_all2': "list_all2 (\A X. table n A X \ wf_set n A) + ((A_zs @ A_x # A_xs) @ (A_ws @ A_ys)) ((zs @ join x False y # xs) @ (ws @ ys))" + using assms assms_dest(3) + by (auto simp del: mmulti_join'.simps simp add: list_all2_append1 list_all2_append2 + list_all2_Cons1 list_all2_Cons2 dest: list_all2_lengthD) fastforce + have res: "\z. restrict A_x z \ join x False y \ restrict A_x z \ x \ restrict A_y z \ y" + using join_restrict[of x n A_x y A_y False, OF _ _ assms(6)] assms_dest(1,2) assms(6) + by (auto simp add: table_def restrict_nested Int_absorb2 Un_absorb2) + show ?thesis + proof (rule set_eqI, rule iffI) + fix z + assume "z \ mmulti_join' (A_zs @ A_x # A_xs) (A_ws @ A_y # A_ys) + ((zs @ x # xs) @ ws @ y # ys)" + then have z_in_dest: "wf_tuple n (\(set (A_zs @ A_x # A_xs))) z" + "list_all2 (\A. (\) (restrict A z)) A_zs zs" + "restrict A_x z \ x" + "list_all2 (\A. (\) (restrict A z)) A_xs xs" + "list_all2 (\A. (\) (restrict A z)) A_ws ws" + "restrict A_y z \ y" + "list_all2 (\A. (\) (restrict A z)) A_ys ys" + using mmulti_join'_correct[OF _ assms(1), of z] + by (auto simp del: mmulti_join'.simps simp add: assms list_all2_append1 + dest: list_all2_lengthD) + then show "z \ mmulti_join' (A_zs @ A_x # A_xs) (A_ws @ A_ys) + ((zs @ join x False y # xs) @ ws @ ys)" + using mmulti_join'_correct[OF _ list_all2', of z] res + by (auto simp add: assms list_all2_appendI Un_assoc simp del: mmulti_join'.simps + dest: list_all2_lengthD) + next + fix z + assume "z \ mmulti_join' (A_zs @ A_x # A_xs) (A_ws @ A_ys) + ((zs @ join x False y # xs) @ ws @ ys)" + then have z_in_dest: "wf_tuple n (\(set (A_zs @ A_x # A_xs))) z" + "list_all2 (\A. (\) (restrict A z)) A_zs zs" + "restrict A_x z \ join x False y" + "list_all2 (\A. (\) (restrict A z)) A_xs xs" + "list_all2 (\A. (\) (restrict A z)) A_ws ws" + "list_all2 (\A. (\) (restrict A z)) A_ys ys" + using mmulti_join'_correct[OF _ list_all2', of z] + by (auto simp del: mmulti_join'.simps simp add: assms list_all2_append1 + dest: list_all2_lengthD) + then show "z \ mmulti_join' (A_zs @ A_x # A_xs) (A_ws @ A_y # A_ys) + ((zs @ x # xs) @ ws @ y # ys)" + using mmulti_join'_correct[OF _ assms(1), of z] res + by (auto simp add: assms list_all2_appendI Un_assoc simp del: mmulti_join'.simps + dest: list_all2_lengthD) + qed +qed + +fun find_sub_in :: "'a set \ 'a set list \ bool \ + ('a set list \ 'a set \ 'a set list) option" where + "find_sub_in X [] b = None" +| "find_sub_in X (x # xs) b = (if (x \ X \ (b \ X \ x)) then Some ([], x, xs) + else (case find_sub_in X xs b of None \ None | Some (ys, z, zs) \ Some (x # ys, z, zs)))" + +lemma find_sub_in_sound: "find_sub_in X xs b = Some (ys, z, zs) \ + xs = ys @ z # zs \ (z \ X \ (b \ X \ z))" + by (induction X xs b arbitrary: ys z zs rule: find_sub_in.induct) + (fastforce split: if_splits option.splits)+ + +fun find_sub_True :: "'a set list \ + ('a set list \ 'a set \ 'a set list \ 'a set \ 'a set list) option" where + "find_sub_True [] = None" +| "find_sub_True (x # xs) = (case find_sub_in x xs True of None \ + (case find_sub_True xs of None \ None + | Some (ys, w, ws, z, zs) \ Some (x # ys, w, ws, z, zs)) + | Some (ys, z, zs) \ Some ([], x, ys, z, zs))" + +lemma find_sub_True_sound: "find_sub_True xs = Some (ys, w, ws, z, zs) \ + xs = ys @ w # ws @ z # zs \ (z \ w \ w \ z)" + using find_sub_in_sound + by (induction xs arbitrary: ys w ws z zs rule: find_sub_True.induct) + (fastforce split: option.splits)+ + +fun find_sub_False :: "'a set list \ 'a set list \ + (('a set list \ 'a set \ 'a set list) \ ('a set list \ 'a set \ 'a set list)) option" where + "find_sub_False [] ns = None" +| "find_sub_False (x # xs) ns = (case find_sub_in x ns False of None \ + (case find_sub_False xs ns of None \ None + | Some ((rs, w, ws), (ys, z, zs)) \ Some ((x # rs, w, ws), (ys, z, zs))) + | Some (ys, z, zs) \ Some (([], x, xs), (ys, z, zs)))" + +lemma find_sub_False_sound: "find_sub_False xs ns = Some ((rs, w, ws), (ys, z, zs)) \ + xs = rs @ w # ws \ ns = ys @ z # zs \ (z \ w)" + using find_sub_in_sound + by (induction xs ns arbitrary: rs w ws ys z zs rule: find_sub_False.induct) + (fastforce split: option.splits)+ + +fun proj_list_3 :: "'a list \ ('b list \ 'b \ 'b list) \ ('a list \ 'a \ 'a list)" where + "proj_list_3 xs (ys, z, zs) = (take (length ys) xs, xs ! (length ys), + take (length zs) (drop (length ys + 1) xs))" + +lemma proj_list_3_same: + assumes "proj_list_3 xs (ys, z, zs) = (ys', z', zs')" + "length xs = length ys + 1 + length zs" + shows "xs = ys' @ z' # zs'" + using assms by (auto simp add: id_take_nth_drop) + +lemma proj_list_3_length: + assumes "proj_list_3 xs (ys, z, zs) = (ys', z', zs')" + "length xs = length ys + 1 + length zs" + shows "length ys = length ys'" "length zs = length zs'" + using assms by auto + +fun proj_list_5 :: "'a list \ + ('b list \ 'b \ 'b list \ 'b \ 'b list) \ + ('a list \ 'a \ 'a list \ 'a \ 'a list)" where + "proj_list_5 xs (ys, w, ws, z, zs) = (take (length ys) xs, xs ! (length ys), + take (length ws) (drop (length ys + 1) xs), xs ! (length ys + 1 + length ws), + drop (length ys + 1 + length ws + 1) xs)" + +lemma proj_list_5_same: + assumes "proj_list_5 xs (ys, w, ws, z, zs) = (ys', w', ws', z', zs')" + "length xs = length ys + 1 + length ws + 1 + length zs" + shows "xs = ys' @ w' # ws' @ z' # zs'" +proof - + have "xs ! length ys # take (length ws) (drop (Suc (length ys)) xs) = take (Suc (length ws)) (drop (length ys) xs)" + using assms(2) by (simp add: list_eq_iff_nth_eq nth_Cons split: nat.split) + moreover have "take (Suc (length ws)) (drop (length ys) xs) @ drop (Suc (length ys + length ws)) xs = + drop (length ys) xs" + unfolding Suc_eq_plus1 add.assoc[of _ _ 1] add.commute[of _ "length ws + 1"] + drop_drop[symmetric, of "length ws + 1"] append_take_drop_id .. + ultimately show ?thesis + using assms by (auto simp: Cons_nth_drop_Suc append_Cons[symmetric]) +qed + +lemma proj_list_5_length: + assumes "proj_list_5 xs (ys, w, ws, z, zs) = (ys', w', ws', z', zs')" + "length xs = length ys + 1 + length ws + 1 + length zs" + shows "length ys = length ys'" "length ws = length ws'" + "length zs = length zs'" + using assms by auto + +fun dominate_True :: "nat set list \ 'a table list \ + ((nat set list \ nat set \ nat set list \ nat set \ nat set list) \ + ('a table list \ 'a table \ 'a table list \ 'a table \ 'a table list)) option" where + "dominate_True A_pos L_pos = (case find_sub_True A_pos of None \ None + | Some split \ Some (split, proj_list_5 L_pos split))" + +lemma find_sub_True_proj_list_5_same: + assumes "find_sub_True xs = Some (ys, w, ws, z, zs)" "length xs = length xs'" + "proj_list_5 xs' (ys, w, ws, z, zs) = (ys', w', ws', z', zs')" + shows "xs' = ys' @ w' # ws' @ z' # zs'" +proof - + have len: "length xs' = length ys + 1 + length ws + 1 + length zs" + using find_sub_True_sound[OF assms(1)] by (auto simp add: assms(2)[symmetric]) + show ?thesis + using proj_list_5_same[OF assms(3) len] . +qed + +lemma find_sub_True_proj_list_5_length: + assumes "find_sub_True xs = Some (ys, w, ws, z, zs)" "length xs = length xs'" + "proj_list_5 xs' (ys, w, ws, z, zs) = (ys', w', ws', z', zs')" + shows "length ys = length ys'" "length ws = length ws'" + "length zs = length zs'" + using find_sub_True_sound[OF assms(1)] proj_list_5_length[OF assms(3)] assms(2) by auto + +lemma dominate_True_sound: + assumes "dominate_True A_pos L_pos = Some ((A_zs, A_x, A_xs, A_y, A_ys), (zs, x, xs, y, ys))" + "length A_pos = length L_pos" + shows "A_pos = A_zs @ A_x # A_xs @ A_y # A_ys" "L_pos = zs @ x # xs @ y # ys" + "length A_xs = length xs" "length A_ys = length ys" "length A_zs = length zs" + using assms find_sub_True_sound find_sub_True_proj_list_5_same find_sub_True_proj_list_5_length + by (auto simp del: proj_list_5.simps split: option.splits) fast+ + +fun dominate_False :: "nat set list \ 'a table list \ nat set list \ 'a table list \ + (((nat set list \ nat set \ nat set list) \ nat set list \ nat set \ nat set list) \ + (('a table list \ 'a table \ 'a table list) \ + 'a table list \ 'a table \ 'a table list)) option" where + "dominate_False A_pos L_pos A_neg L_neg = (case find_sub_False A_pos A_neg of None \ None + | Some (pos_split, neg_split) \ + Some ((pos_split, neg_split), (proj_list_3 L_pos pos_split, proj_list_3 L_neg neg_split)))" + +lemma find_sub_False_proj_list_3_same_left: + assumes "find_sub_False xs ns = Some ((rs, w, ws), (ys, z, zs))" + "length xs = length xs'" "proj_list_3 xs' (rs, w, ws) = (rs', w', ws')" + shows "xs' = rs' @ w' # ws'" +proof - + have len: "length xs' = length rs + 1 + length ws" + using find_sub_False_sound[OF assms(1)] by (auto simp add: assms(2)[symmetric]) + show ?thesis + using proj_list_3_same[OF assms(3) len] . +qed + +lemma find_sub_False_proj_list_3_length_left: + assumes "find_sub_False xs ns = Some ((rs, w, ws), (ys, z, zs))" + "length xs = length xs'" "proj_list_3 xs' (rs, w, ws) = (rs', w', ws')" + shows "length rs = length rs'" "length ws = length ws'" + using find_sub_False_sound[OF assms(1)] proj_list_3_length[OF assms(3)] assms(2) by auto + +lemma find_sub_False_proj_list_3_same_right: + assumes "find_sub_False xs ns = Some ((rs, w, ws), (ys, z, zs))" + "length ns = length ns'" "proj_list_3 ns' (ys, z, zs) = (ys', z', zs')" + shows "ns' = ys' @ z' # zs'" +proof - + have len: "length ns' = length ys + 1 + length zs" + using find_sub_False_sound[OF assms(1)] by (auto simp add: assms(2)[symmetric]) + show ?thesis + using proj_list_3_same[OF assms(3) len] . +qed + +lemma find_sub_False_proj_list_3_length_right: + assumes "find_sub_False xs ns = Some ((rs, w, ws), (ys, z, zs))" + "length ns = length ns'" "proj_list_3 ns' (ys, z, zs) = (ys', z', zs')" + shows "length ys = length ys'" "length zs = length zs'" + using find_sub_False_sound[OF assms(1)] proj_list_3_length[OF assms(3)] assms(2) by auto + +lemma dominate_False_sound: + assumes "dominate_False A_pos L_pos A_neg L_neg = + Some (((A_zs, A_x, A_xs), A_ws, A_y, A_ys), ((zs, x, xs), ws, y, ys))" + "length A_pos = length L_pos" "length A_neg = length L_neg" + shows "A_pos = (A_zs @ A_x # A_xs)" "A_neg = A_ws @ A_y # A_ys" + "L_pos = (zs @ x # xs)" "L_neg = ws @ y # ys" + "length A_ws = length ws" "length A_xs = length xs" + "length A_ys = length ys" "length A_zs = length zs" + "A_y \ A_x" + using assms find_sub_False_proj_list_3_same_left find_sub_False_proj_list_3_same_right + find_sub_False_proj_list_3_length_left find_sub_False_proj_list_3_length_right + find_sub_False_sound + by (auto simp del: proj_list_3.simps split: option.splits) fast+ + +function mmulti_join :: "(nat \ nat set list \ nat set list \ 'a table list \ 'a table)" where + "mmulti_join n A_pos A_neg L = (if length A_pos + length A_neg \ length L then {} else + let L_pos = take (length A_pos) L; L_neg = drop (length A_pos) L in + (case dominate_True A_pos L_pos of None \ + (case dominate_False A_pos L_pos A_neg L_neg of None \ mmulti_join' A_pos A_neg L + | Some (((A_zs, A_x, A_xs), A_ws, A_y, A_ys), ((zs, x, xs), ws, y, ys)) \ + mmulti_join n (A_zs @ A_x # A_xs) (A_ws @ A_ys) + ((zs @ bin_join n A_x x False A_y y # xs) @ (ws @ ys))) + | Some ((A_zs, A_x, A_xs, A_y, A_ys), (zs, x, xs, y, ys)) \ + mmulti_join n (A_zs @ (A_x \ A_y) # A_xs @ A_ys) A_neg + ((zs @ bin_join n A_x x True A_y y # xs @ ys) @ L_neg)))" + by pat_completeness auto +termination + by (relation "measure (\(n, A_pos, A_neg, L). length A_pos + length A_neg)") + (use find_sub_True_sound find_sub_False_sound in \fastforce split: option.splits\)+ + +lemma mmulti_join_link: + assumes "A_pos \ []" + and "list_all2 (\A X. table n A X \ wf_set n A) (A_pos @ A_neg) L" + shows "mmulti_join n A_pos A_neg L = mmulti_join' A_pos A_neg L" + using assms +proof (induction A_pos A_neg L rule: mmulti_join.induct) + case (1 n A_pos A_neg L) + define L_pos where "L_pos = take (length A_pos) L" + define L_neg where "L_neg = drop (length A_pos) L" + have L_def: "L = L_pos @ L_neg" + using L_pos_def L_neg_def by auto + have lens_match: "length A_pos = length L_pos" "length A_neg = length L_neg" + using L_pos_def L_neg_def 1(4)[unfolded L_def] by (auto dest: list_all2_lengthD) + then have lens_sum: "length A_pos + length A_neg = length L" + by (auto simp add: L_def) + show ?case + proof (cases "dominate_True A_pos L_pos") + case None + note dom_True = None + show ?thesis + proof (cases "dominate_False A_pos L_pos A_neg L_neg") + case None + show ?thesis + by (subst mmulti_join.simps) + (simp del: dominate_True.simps dominate_False.simps mmulti_join.simps + mmulti_join'.simps add: Let_def dom_True L_pos_def[symmetric] None + L_neg_def[symmetric] lens_sum split: option.splits) + next + case (Some a) + then obtain A_zs A_x A_xs A_ws A_y A_ys zs x xs ws y ys where + dom_False: "dominate_False A_pos L_pos A_neg L_neg = + Some (((A_zs, A_x, A_xs), A_ws, A_y, A_ys), ((zs, x, xs), ws, y, ys))" + by (cases a) auto + note list_all2 = 1(4)[unfolded L_def dominate_False_sound[OF dom_False lens_match]] + have lens: "length A_ws = length ws" "length A_xs = length xs" + "length A_ys = length ys" "length A_zs = length zs" + using dominate_False_sound[OF dom_False lens_match] by auto + have sub: "A_y \ A_x" + using dominate_False_sound[OF dom_False lens_match] by auto + have list_all2': "list_all2 (\A X. table n A X \ wf_set n A) + ((A_zs @ A_x # A_xs) @ (A_ws @ A_ys)) ((zs @ join x False y # xs) @ (ws @ ys))" + using list_all2_opt_False[OF list_all2 lens sub] . + have tabs: "table n A_x x" "table n A_y y" + using list_all2 by (auto simp add: lens list_all2_append) + have bin_join_conv: "join x False y = bin_join n A_x x False A_y y" + using bin_join_table[OF tabs, symmetric] . + have mmulti: "mmulti_join n A_pos A_neg L = mmulti_join n (A_zs @ A_x # A_xs) (A_ws @ A_ys) + ((zs @ bin_join n A_x x False A_y y # xs) @ (ws @ ys))" + by (subst mmulti_join.simps) + (simp del: dominate_True.simps dominate_False.simps mmulti_join.simps + add: Let_def dom_True L_pos_def[symmetric] L_neg_def[symmetric] dom_False lens_sum) + show ?thesis + unfolding mmulti + unfolding L_def dominate_False_sound[OF dom_False lens_match] + by (rule 1(1)[OF _ L_pos_def L_neg_def dom_True dom_False, + OF _ _ _ _ _ _ _ _ _ _ _ _ _ list_all2'[unfolded bin_join_conv], + unfolded mmulti_join'_opt_False[OF list_all2 lens sub, symmetric, + unfolded bin_join_conv]]) + (auto simp add: lens_sum) + qed + next + case (Some a) + then obtain A_zs A_x A_xs A_y A_ys zs x xs y ys where dom_True: "dominate_True A_pos L_pos = + Some ((A_zs, A_x, A_xs, A_y, A_ys), (zs, x, xs, y, ys))" + by (cases a) auto + note list_all2 = 1(4)[unfolded L_def dominate_True_sound[OF dom_True lens_match(1)]] + have lens: "length A_xs = length xs" "length A_ys = length ys" "length A_zs = length zs" + using dominate_True_sound[OF dom_True lens_match(1)] by auto + have list_all2': "list_all2 (\A X. table n A X \ wf_set n A) + ((A_zs @ (A_x \ A_y) # A_xs @ A_ys) @ A_neg) ((zs @ join x True y # xs @ ys) @ L_neg)" + using list_all2_opt_True[OF list_all2 lens] . + have tabs: "table n A_x x" "table n A_y y" + using list_all2 by (auto simp add: lens list_all2_append) + have bin_join_conv: "join x True y = bin_join n A_x x True A_y y" + using bin_join_table[OF tabs, symmetric] . + have mmulti: "mmulti_join n A_pos A_neg L = mmulti_join n (A_zs @ (A_x \ A_y) # A_xs @ A_ys) + A_neg ((zs @ bin_join n A_x x True A_y y # xs @ ys) @ L_neg)" + by (subst mmulti_join.simps) + (simp del: dominate_True.simps dominate_False.simps mmulti_join.simps + add: Let_def dom_True L_pos_def[symmetric] L_neg_def lens_sum) + show ?thesis + unfolding mmulti + unfolding L_def dominate_True_sound[OF dom_True lens_match(1)] + by (rule 1(2)[OF _ L_pos_def L_neg_def dom_True, + OF _ _ _ _ _ _ _ _ _ _ _ list_all2'[unfolded bin_join_conv], + unfolded mmulti_join'_opt_True[OF list_all2 lens, symmetric, + unfolded bin_join_conv]]) + (auto simp add: lens_sum) + qed +qed + +lemma mmulti_join_correct: + assumes "A_pos \ []" + and "list_all2 (\A X. table n A X \ wf_set n A) (A_pos @ A_neg) L" + shows "z \ mmulti_join n A_pos A_neg L \ wf_tuple n (\A\set A_pos. A) z \ + list_all2 (\A X. restrict A z \ X) A_pos (take (length A_pos) L) \ + list_all2 (\A X. restrict A z \ X) A_neg (drop (length A_pos) L)" + unfolding mmulti_join_link[OF assms] using mmulti_join'_correct[OF assms] . + +end diff --git a/thys/MFODL_Monitor_Optimized/Optimized_MTL.thy b/thys/MFODL_Monitor_Optimized/Optimized_MTL.thy new file mode 100644 --- /dev/null +++ b/thys/MFODL_Monitor_Optimized/Optimized_MTL.thy @@ -0,0 +1,3065 @@ +(*<*) +theory Optimized_MTL + imports Monitor +begin +(*>*) + +section \Efficient implementation of temporal operators\ + +subsection \Optimized queue data structure\ + +lemma less_enat_iff: "a < enat i \ (\j. a = enat j \ j < i)" + by (cases a) auto + +type_synonym 'a queue_t = "'a list \ 'a list" + +definition queue_invariant :: "'a queue_t \ bool" where + "queue_invariant q = (case q of ([], []) \ True | (fs, l # ls) \ True | _ \ False)" + +typedef 'a queue = "{q :: 'a queue_t. queue_invariant q}" + by (auto simp: queue_invariant_def split: list.splits) + +setup_lifting type_definition_queue + +lift_definition linearize :: "'a queue \ 'a list" is "(\q. case q of (fs, ls) \ fs @ rev ls)" . + +lift_definition empty_queue :: "'a queue" is "([], [])" + by (auto simp: queue_invariant_def split: list.splits) + +lemma empty_queue_rep: "linearize empty_queue = []" + by transfer (simp add: empty_queue_def linearize_def) + +lift_definition is_empty :: "'a queue \ bool" is "\q. (case q of ([], []) \ True | _ \ False)" . + +lemma linearize_t_Nil: "(case q of (fs, ls) \ fs @ rev ls) = [] \ q = ([], [])" + by (auto split: prod.splits) + +lemma is_empty_alt: "is_empty q \ linearize q = []" + by transfer (auto simp: linearize_t_Nil list.case_eq_if) + +fun prepend_queue_t :: "'a \ 'a queue_t \ 'a queue_t" where + "prepend_queue_t a ([], []) = ([], [a])" +| "prepend_queue_t a (fs, l # ls) = (a # fs, l # ls)" +| "prepend_queue_t a (f # fs, []) = undefined" + +lift_definition prepend_queue :: "'a \ 'a queue \ 'a queue" is prepend_queue_t + by (auto simp: queue_invariant_def split: list.splits elim: prepend_queue_t.elims) + +lemma prepend_queue_rep: "linearize (prepend_queue a q) = a # linearize q" + by transfer + (auto simp add: queue_invariant_def linearize_def elim: prepend_queue_t.elims split: prod.splits) + +lift_definition append_queue :: "'a \ 'a queue \ 'a queue" is + "(\a q. case q of (fs, ls) \ (fs, a # ls))" + by (auto simp: queue_invariant_def split: list.splits) + +lemma append_queue_rep: "linearize (append_queue a q) = linearize q @ [a]" + by transfer (auto simp add: linearize_def split: prod.splits) + +fun safe_last_t :: "'a queue_t \ 'a option \ 'a queue_t" where + "safe_last_t ([], []) = (None, ([], []))" +| "safe_last_t (fs, l # ls) = (Some l, (fs, l # ls))" +| "safe_last_t (f # fs, []) = undefined" + +lift_definition safe_last :: "'a queue \ 'a option \ 'a queue" is safe_last_t + by (auto simp: queue_invariant_def split: prod.splits list.splits) + +lemma safe_last_rep: "safe_last q = (\, q') \ linearize q = linearize q' \ + (case \ of None \ linearize q = [] | Some a \ linearize q \ [] \ a = last (linearize q))" + by transfer (auto simp: queue_invariant_def split: list.splits elim: safe_last_t.elims) + +fun safe_hd_t :: "'a queue_t \ 'a option \ 'a queue_t" where + "safe_hd_t ([], []) = (None, ([], []))" +| "safe_hd_t ([], [l]) = (Some l, ([], [l]))" +| "safe_hd_t ([], l # ls) = (let fs = rev ls in (Some (hd fs), (fs, [l])))" +| "safe_hd_t (f # fs, l # ls) = (Some f, (f # fs, l # ls))" +| "safe_hd_t (f # fs, []) = undefined" + +lift_definition(code_dt) safe_hd :: "'a queue \ 'a option \ 'a queue" is safe_hd_t +proof - + fix q :: "'a queue_t" + assume "queue_invariant q" + then show "pred_prod \ queue_invariant (safe_hd_t q)" + by (cases q rule: safe_hd_t.cases) (auto simp: queue_invariant_def Let_def split: list.split) +qed + +lemma safe_hd_rep: "safe_hd q = (\, q') \ linearize q = linearize q' \ + (case \ of None \ linearize q = [] | Some a \ linearize q \ [] \ a = hd (linearize q))" + by transfer + (auto simp add: queue_invariant_def Let_def hd_append split: list.splits elim: safe_hd_t.elims) + +fun replace_hd_t :: "'a \ 'a queue_t \ 'a queue_t" where + "replace_hd_t a ([], []) = ([], [])" +| "replace_hd_t a ([], [l]) = ([], [a])" +| "replace_hd_t a ([], l # ls) = (let fs = rev ls in (a # tl fs, [l]))" +| "replace_hd_t a (f # fs, l # ls) = (a # fs, l # ls)" +| "replace_hd_t a (f # fs, []) = undefined" + +lift_definition replace_hd :: "'a \ 'a queue \ 'a queue" is replace_hd_t + by (auto simp: queue_invariant_def split: list.splits elim: replace_hd_t.elims) + +lemma tl_append: "xs \ [] \ tl xs @ ys = tl (xs @ ys)" + by simp + +lemma replace_hd_rep: "linearize q = f # fs \ linearize (replace_hd a q) = a # fs" +proof (transfer fixing: f fs a) + fix q + assume "queue_invariant q" and "(case q of (fs, ls) \ fs @ rev ls) = f # fs" + then show "(case replace_hd_t a q of (fs, ls) \ fs @ rev ls) = a # fs" + by (cases "(a, q)" rule: replace_hd_t.cases) (auto simp: queue_invariant_def tl_append) +qed + +fun replace_last_t :: "'a \ 'a queue_t \ 'a queue_t" where + "replace_last_t a ([], []) = ([], [])" +| "replace_last_t a (fs, l # ls) = (fs, a # ls)" +| "replace_last_t a (fs, []) = undefined" + +lift_definition replace_last :: "'a \ 'a queue \ 'a queue" is replace_last_t + by (auto simp: queue_invariant_def split: list.splits elim: replace_last_t.elims) + +lemma replace_last_rep: "linearize q = fs @ [f] \ linearize (replace_last a q) = fs @ [a]" + by transfer (auto simp: queue_invariant_def split: list.splits prod.splits elim!: replace_last_t.elims) + +fun tl_queue_t :: "'a queue_t \ 'a queue_t" where + "tl_queue_t ([], []) = ([], [])" +| "tl_queue_t ([], [l]) = ([], [])" +| "tl_queue_t ([], l # ls) = (tl (rev ls), [l])" +| "tl_queue_t (a # as, fs) = (as, fs)" + +lift_definition tl_queue :: "'a queue \ 'a queue" is tl_queue_t + by (auto simp: queue_invariant_def split: list.splits elim!: tl_queue_t.elims) + +lemma tl_queue_rep: "\is_empty q \ linearize (tl_queue q) = tl (linearize q)" + by transfer (auto simp: tl_append split: prod.splits list.splits elim!: tl_queue_t.elims) + +lemma length_tl_queue_rep: "\is_empty q \ + length (linearize (tl_queue q)) < length (linearize q)" + by transfer (auto split: prod.splits list.splits elim: tl_queue_t.elims) + +lemma length_tl_queue_safe_hd: + assumes "safe_hd q = (Some a, q')" + shows "length (linearize (tl_queue q')) < length (linearize q)" + using safe_hd_rep[OF assms] + by (auto simp add: length_tl_queue_rep is_empty_alt) + +function dropWhile_queue :: "('a \ bool) \ 'a queue \ 'a queue" where + "dropWhile_queue f q = (case safe_hd q of (None, q') \ q' + | (Some a, q') \ if f a then dropWhile_queue f (tl_queue q') else q')" + by pat_completeness auto +termination + using length_tl_queue_safe_hd[OF sym] + by (relation "measure (\(f, q). length (linearize q))") (fastforce split: prod.splits)+ + +lemma dropWhile_hd_tl: "xs \ [] \ + dropWhile P xs = (if P (hd xs) then dropWhile P (tl xs) else xs)" + by (cases xs) auto + +lemma dropWhile_queue_rep: "linearize (dropWhile_queue f q) = dropWhile f (linearize q)" + by (induction f q rule: dropWhile_queue.induct) + (auto simp add: tl_queue_rep dropWhile_hd_tl is_empty_alt + split: prod.splits option.splits dest: safe_hd_rep) + +function takeWhile_queue :: "('a \ bool) \ 'a queue \ 'a queue" where + "takeWhile_queue f q = (case safe_hd q of (None, q') \ q' + | (Some a, q') \ if f a + then prepend_queue a (takeWhile_queue f (tl_queue q')) + else empty_queue)" + by pat_completeness auto +termination + using length_tl_queue_safe_hd[OF sym] + by (relation "measure (\(f, q). length (linearize q))") (fastforce split: prod.splits)+ + +lemma takeWhile_hd_tl: "xs \ [] \ + takeWhile P xs = (if P (hd xs) then hd xs # takeWhile P (tl xs) else [])" + by (cases xs) auto + +lemma takeWhile_queue_rep: "linearize (takeWhile_queue f q) = takeWhile f (linearize q)" + by (induction f q rule: takeWhile_queue.induct) + (auto simp add: prepend_queue_rep tl_queue_rep empty_queue_rep takeWhile_hd_tl is_empty_alt + split: prod.splits option.splits dest: safe_hd_rep) + +function takedropWhile_queue :: "('a \ bool) \ 'a queue \ 'a queue \ 'a list" where + "takedropWhile_queue f q = (case safe_hd q of (None, q') \ (q', []) + | (Some a, q') \ if f a + then (case takedropWhile_queue f (tl_queue q') of (q'', as) \ (q'', a # as)) + else (q', []))" + by pat_completeness auto +termination + using length_tl_queue_safe_hd[OF sym] + by (relation "measure (\(f, q). length (linearize q))") (fastforce split: prod.splits)+ + +lemma takedropWhile_queue_fst: "fst (takedropWhile_queue f q) = dropWhile_queue f q" +proof (induction f q rule: takedropWhile_queue.induct) + case (1 f q) + then show ?case + by (simp split: prod.splits) (auto simp add: case_prod_unfold split: option.splits) +qed + +lemma takedropWhile_queue_snd: "snd (takedropWhile_queue f q) = takeWhile f (linearize q)" +proof (induction f q rule: takedropWhile_queue.induct) + case (1 f q) + then show ?case + by (simp split: prod.splits) + (auto simp add: case_prod_unfold tl_queue_rep takeWhile_hd_tl is_empty_alt + split: option.splits dest: safe_hd_rep) +qed + +subsection \Optimized data structure for Since\ + +type_synonym 'a mmsaux = "ts \ ts \ bool list \ bool list \ + (ts \ 'a table) queue \ (ts \ 'a table) queue \ + (('a tuple, ts) mapping) \ (('a tuple, ts) mapping)" + +fun time_mmsaux :: "'a mmsaux \ ts" where + "time_mmsaux aux = (case aux of (nt, _) \ nt)" + +definition ts_tuple_rel :: "(ts \ 'a table) set \ (ts \ 'a tuple) set" where + "ts_tuple_rel ys = {(t, as). \X. as \ X \ (t, X) \ ys}" + +lemma finite_fst_ts_tuple_rel: "finite (fst ` {tas \ ts_tuple_rel (set xs). P tas})" +proof - + have "fst ` {tas \ ts_tuple_rel (set xs). P tas} \ fst ` ts_tuple_rel (set xs)" + by auto + moreover have "\ \ set (map fst xs)" + by (force simp add: ts_tuple_rel_def) + finally show ?thesis + using finite_subset by blast +qed + +lemma ts_tuple_rel_ext_Cons: "tas \ ts_tuple_rel {(nt, X)} \ + tas \ ts_tuple_rel (set ((nt, X) # tass))" + by (auto simp add: ts_tuple_rel_def) + +lemma ts_tuple_rel_ext_Cons': "tas \ ts_tuple_rel (set tass) \ + tas \ ts_tuple_rel (set ((nt, X) # tass))" + by (auto simp add: ts_tuple_rel_def) + +lemma ts_tuple_rel_intro: "as \ X \ (t, X) \ ys \ (t, as) \ ts_tuple_rel ys" + by (auto simp add: ts_tuple_rel_def) + +lemma ts_tuple_rel_dest: "(t, as) \ ts_tuple_rel ys \ \X. (t, X) \ ys \ as \ X" + by (auto simp add: ts_tuple_rel_def) + +lemma ts_tuple_rel_Un: "ts_tuple_rel (ys \ zs) = ts_tuple_rel ys \ ts_tuple_rel zs" + by (auto simp add: ts_tuple_rel_def) + +lemma ts_tuple_rel_ext: "tas \ ts_tuple_rel {(nt, X)} \ + tas \ ts_tuple_rel (set ((nt, Y \ X) # tass))" +proof - + assume assm: "tas \ ts_tuple_rel {(nt, X)}" + then obtain as where tas_def: "tas = (nt, as)" "as \ X" + by (cases tas) (auto simp add: ts_tuple_rel_def) + then have "as \ Y \ X" + by auto + then show "tas \ ts_tuple_rel (set ((nt, Y \ X) # tass))" + unfolding tas_def(1) + by (rule ts_tuple_rel_intro) auto +qed + +lemma ts_tuple_rel_ext': "tas \ ts_tuple_rel (set ((nt, X) # tass)) \ + tas \ ts_tuple_rel (set ((nt, X \ Y) # tass))" +proof - + assume assm: "tas \ ts_tuple_rel (set ((nt, X) # tass))" + then have "tas \ ts_tuple_rel {(nt, X)} \ ts_tuple_rel (set tass)" + using ts_tuple_rel_Un by force + then show "tas \ ts_tuple_rel (set ((nt, X \ Y) # tass))" + proof + assume "tas \ ts_tuple_rel {(nt, X)}" + then show ?thesis + by (auto simp: Un_commute dest!: ts_tuple_rel_ext) + next + assume "tas \ ts_tuple_rel (set tass)" + then have "tas \ ts_tuple_rel (set ((nt, X \ Y) # tass))" + by (rule ts_tuple_rel_ext_Cons') + then show ?thesis by simp + qed +qed + +lemma ts_tuple_rel_mono: "ys \ zs \ ts_tuple_rel ys \ ts_tuple_rel zs" + by (auto simp add: ts_tuple_rel_def) + +lemma ts_tuple_rel_filter: "ts_tuple_rel (set (filter (\(t, X). P t) xs)) = + {(t, X) \ ts_tuple_rel (set xs). P t}" + by (auto simp add: ts_tuple_rel_def) + +lemma ts_tuple_rel_set_filter: "x \ ts_tuple_rel (set (filter P xs)) \ + x \ ts_tuple_rel (set xs)" + by (auto simp add: ts_tuple_rel_def) + +definition valid_tuple :: "(('a tuple, ts) mapping) \ (ts \ 'a tuple) \ bool" where + "valid_tuple tuple_since = (\(t, as). case Mapping.lookup tuple_since as of None \ False + | Some t' \ t \ t')" + +definition safe_max :: "'a :: linorder set \ 'a option" where + "safe_max X = (if X = {} then None else Some (Max X))" + +lemma safe_max_empty: "safe_max X = None \ X = {}" + by (simp add: safe_max_def) + +lemma safe_max_empty_dest: "safe_max X = None \ X = {}" + by (simp add: safe_max_def split: if_splits) + +lemma safe_max_Some_intro: "x \ X \ \y. safe_max X = Some y" + using safe_max_empty by auto + +lemma safe_max_Some_dest_in: "finite X \ safe_max X = Some x \ x \ X" + using Max_in by (auto simp add: safe_max_def split: if_splits) + +lemma safe_max_Some_dest_le: "finite X \ safe_max X = Some x \ y \ X \ y \ x" + using Max_ge by (auto simp add: safe_max_def split: if_splits) + +fun valid_mmsaux :: "args \ ts \ 'a mmsaux \ 'a Monitor.msaux \ bool" where + "valid_mmsaux args cur (nt, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since) ys \ + (args_L args) \ (args_R args) \ + maskL = join_mask (args_n args) (args_L args) \ + maskR = join_mask (args_n args) (args_R args) \ + (\(t, X) \ set ys. table (args_n args) (args_R args) X) \ + table (args_n args) (args_R args) (Mapping.keys tuple_in) \ + table (args_n args) (args_R args) (Mapping.keys tuple_since) \ + (\as \ \(snd ` (set (linearize data_prev))). wf_tuple (args_n args) (args_R args) as) \ + cur = nt \ + ts_tuple_rel (set ys) = + {tas \ ts_tuple_rel (set (linearize data_prev) \ set (linearize data_in)). + valid_tuple tuple_since tas} \ + sorted (map fst (linearize data_prev)) \ + (\t \ fst ` set (linearize data_prev). t \ nt \ nt - t < left (args_ivl args)) \ + sorted (map fst (linearize data_in)) \ + (\t \ fst ` set (linearize data_in). t \ nt \ nt - t \ left (args_ivl args)) \ + (\as. Mapping.lookup tuple_in as = safe_max (fst ` + {tas \ ts_tuple_rel (set (linearize data_in)). valid_tuple tuple_since tas \ as = snd tas})) \ + (\as \ Mapping.keys tuple_since. case Mapping.lookup tuple_since as of Some t \ t \ nt)" + +lemma Mapping_lookup_filter_keys: "k \ Mapping.keys (Mapping.filter f m) \ + Mapping.lookup (Mapping.filter f m) k = Mapping.lookup m k" + by (metis default_def insert_subset keys_default keys_filter lookup_default lookup_default_filter) + +lemma Mapping_filter_keys: "(\k \ Mapping.keys m. P (Mapping.lookup m k)) \ + (\k \ Mapping.keys (Mapping.filter f m). P (Mapping.lookup (Mapping.filter f m) k))" + using Mapping_lookup_filter_keys Mapping.keys_filter by fastforce + +lemma Mapping_filter_keys_le: "(\x. P x \ P' x) \ + (\k \ Mapping.keys m. P (Mapping.lookup m k)) \ (\k \ Mapping.keys m. P' (Mapping.lookup m k))" + by auto + +lemma Mapping_keys_dest: "x \ Mapping.keys f \ \y. Mapping.lookup f x = Some y" + by (simp add: domD keys_dom_lookup) + +lemma Mapping_keys_intro: "Mapping.lookup f x \ None \ x \ Mapping.keys f" + by (simp add: domIff keys_dom_lookup) + +lemma valid_mmsaux_tuple_in_keys: "valid_mmsaux args cur + (nt, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since) ys \ + Mapping.keys tuple_in = snd ` {tas \ ts_tuple_rel (set (linearize data_in)). + valid_tuple tuple_since tas}" + by (auto intro!: Mapping_keys_intro safe_max_Some_intro + dest!: Mapping_keys_dest safe_max_Some_dest_in[OF finite_fst_ts_tuple_rel])+ + +fun init_mmsaux :: "args \ 'a mmsaux" where + "init_mmsaux args = (0, 0, join_mask (args_n args) (args_L args), + join_mask (args_n args) (args_R args), empty_queue, empty_queue, Mapping.empty, Mapping.empty)" + +lemma valid_init_mmsaux: "L \ R \ valid_mmsaux (init_args I n L R b) 0 + (init_mmsaux (init_args I n L R b)) []" + by (auto simp add: init_args_def empty_queue_rep ts_tuple_rel_def join_mask_def + Mapping.lookup_empty safe_max_def table_def) + +abbreviation "filter_cond X' ts t' \ (\as _. \ (as \ X' \ Mapping.lookup ts as = Some t'))" + +lemma dropWhile_filter: + "sorted (map fst xs) \ \t \ fst ` set xs. t \ nt \ + dropWhile (\(t, X). enat (nt - t) > c) xs = filter (\(t, X). enat (nt - t) \ c) xs" + by (induction xs) (auto 0 3 intro!: filter_id_conv[THEN iffD2, symmetric] elim: order.trans[rotated]) + +lemma dropWhile_filter': + fixes nt :: nat + shows "sorted (map fst xs) \ \t \ fst ` set xs. t \ nt \ + dropWhile (\(t, X). nt - t \ c) xs = filter (\(t, X). nt - t < c) xs" + by (induction xs) (auto 0 3 intro!: filter_id_conv[THEN iffD2, symmetric] elim: order.trans[rotated]) + +lemma dropWhile_filter'': + "sorted xs \ \t \ set xs. t \ nt \ + dropWhile (\t. enat (nt - t) > c) xs = filter (\t. enat (nt - t) \ c) xs" + by (induction xs) (auto 0 3 intro!: filter_id_conv[THEN iffD2, symmetric] elim: order.trans[rotated]) + +lemma takeWhile_filter: + "sorted (map fst xs) \ \t \ fst ` set xs. t \ nt \ + takeWhile (\(t, X). enat (nt - t) > c) xs = filter (\(t, X). enat (nt - t) > c) xs" + by (induction xs) (auto 0 3 simp: less_enat_iff intro!: filter_empty_conv[THEN iffD2, symmetric]) + +lemma takeWhile_filter': + fixes nt :: nat + shows "sorted (map fst xs) \ \t \ fst ` set xs. t \ nt \ + takeWhile (\(t, X). nt - t \ c) xs = filter (\(t, X). nt - t \ c) xs" + by (induction xs) (auto 0 3 simp: less_enat_iff intro!: filter_empty_conv[THEN iffD2, symmetric]) + +lemma takeWhile_filter'': + "sorted xs \ \t \ set xs. t \ nt \ + takeWhile (\t. enat (nt - t) > c) xs = filter (\t. enat (nt - t) > c) xs" + by (induction xs) (auto 0 3 simp: less_enat_iff intro!: filter_empty_conv[THEN iffD2, symmetric]) + +lemma fold_Mapping_filter_None: "Mapping.lookup ts as = None \ + Mapping.lookup (fold (\(t, X) ts. Mapping.filter + (filter_cond X ts t) ts) ds ts) as = None" + by (induction ds arbitrary: ts) (auto simp add: Mapping.lookup_filter) + +lemma Mapping_lookup_filter_Some_P: "Mapping.lookup (Mapping.filter P m) k = Some v \ P k v" + by (auto simp add: Mapping.lookup_filter split: option.splits if_splits) + +lemma Mapping_lookup_filter_None: "(\v. \P k v) \ + Mapping.lookup (Mapping.filter P m) k = None" + by (auto simp add: Mapping.lookup_filter split: option.splits) + +lemma Mapping_lookup_filter_Some: "(\v. P k v) \ + Mapping.lookup (Mapping.filter P m) k = Mapping.lookup m k" + by (auto simp add: Mapping.lookup_filter split: option.splits) + +lemma Mapping_lookup_filter_not_None: "Mapping.lookup (Mapping.filter P m) k \ None \ + Mapping.lookup (Mapping.filter P m) k = Mapping.lookup m k" + by (auto simp add: Mapping.lookup_filter split: option.splits) + +lemma fold_Mapping_filter_Some_None: "Mapping.lookup ts as = Some t \ + as \ X \ (t, X) \ set ds \ + Mapping.lookup (fold (\(t, X) ts. Mapping.filter (filter_cond X ts t) ts) ds ts) as = None" +proof (induction ds arbitrary: ts) + case (Cons a ds) + show ?case + proof (cases a) + case (Pair t' X') + with Cons show ?thesis + using fold_Mapping_filter_None[of "Mapping.filter (filter_cond X' ts t') ts" as ds] + Mapping_lookup_filter_not_None[of "filter_cond X' ts t'" ts as] + fold_Mapping_filter_None[OF Mapping_lookup_filter_None, of _ as ds ts] + by (cases "Mapping.lookup (Mapping.filter (filter_cond X' ts t') ts) as = None") auto + qed +qed simp + +lemma fold_Mapping_filter_Some_Some: "Mapping.lookup ts as = Some t \ + (\X. (t, X) \ set ds \ as \ X) \ + Mapping.lookup (fold (\(t, X) ts. Mapping.filter (filter_cond X ts t) ts) ds ts) as = Some t" +proof (induction ds arbitrary: ts) + case (Cons a ds) + then show ?case + proof (cases a) + case (Pair t' X') + with Cons show ?thesis + using Mapping_lookup_filter_Some[of "filter_cond X' ts t'" as ts] by auto + qed +qed simp + +fun shift_end :: "args \ ts \ 'a mmsaux \ 'a mmsaux" where + "shift_end args nt (t, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since) = + (let I = args_ivl args; + data_prev' = dropWhile_queue (\(t, X). enat (nt - t) > right I) data_prev; + (data_in, discard) = takedropWhile_queue (\(t, X). enat (nt - t) > right I) data_in; + tuple_in = fold (\(t, X) tuple_in. Mapping.filter + (filter_cond X tuple_in t) tuple_in) discard tuple_in in + (t, gc, maskL, maskR, data_prev', data_in, tuple_in, tuple_since))" + +lemma valid_shift_end_mmsaux_unfolded: + assumes valid_before: "valid_mmsaux args cur + (ot, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since) auxlist" + and nt_mono: "nt \ cur" + shows "valid_mmsaux args cur (shift_end args nt + (ot, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since)) + (filter (\(t, rel). enat (nt - t) \ right (args_ivl args)) auxlist)" +proof - + define I where "I = args_ivl args" + define data_in' where "data_in' \ + fst (takedropWhile_queue (\(t, X). enat (nt - t) > right I) data_in)" + define data_prev' where "data_prev' \ + dropWhile_queue (\(t, X). enat (nt - t) > right I) data_prev" + define discard where "discard \ + snd (takedropWhile_queue (\(t, X). enat (nt - t) > right I) data_in)" + define tuple_in' where "tuple_in' \ fold (\(t, X) tuple_in. Mapping.filter + (\as _. \(as \ X \ Mapping.lookup tuple_in as = Some t)) tuple_in) discard tuple_in" + have tuple_in_Some_None: "\as t X. Mapping.lookup tuple_in as = Some t \ + as \ X \ (t, X) \ set discard \ Mapping.lookup tuple_in' as = None" + using fold_Mapping_filter_Some_None unfolding tuple_in'_def by fastforce + have tuple_in_Some_Some: "\as t. Mapping.lookup tuple_in as = Some t \ + (\X. (t, X) \ set discard \ as \ X) \ Mapping.lookup tuple_in' as = Some t" + using fold_Mapping_filter_Some_Some unfolding tuple_in'_def by fastforce + have tuple_in_None_None: "\as. Mapping.lookup tuple_in as = None \ + Mapping.lookup tuple_in' as = None" + using fold_Mapping_filter_None unfolding tuple_in'_def by fastforce + have tuple_in'_keys: "\as. as \ Mapping.keys tuple_in' \ as \ Mapping.keys tuple_in" + using tuple_in_Some_None tuple_in_Some_Some tuple_in_None_None + by (fastforce intro: Mapping_keys_intro dest: Mapping_keys_dest) + have F1: "sorted (map fst (linearize data_in))" "\t \ fst ` set (linearize data_in). t \ nt" + using valid_before nt_mono by auto + have F2: "sorted (map fst (linearize data_prev))" "\t \ fst ` set (linearize data_prev). t \ nt" + using valid_before nt_mono by auto + have lin_data_in': "linearize data_in' = + filter (\(t, X). enat (nt - t) \ right I) (linearize data_in)" + unfolding data_in'_def[unfolded takedropWhile_queue_fst] dropWhile_queue_rep + dropWhile_filter[OF F1] .. + then have set_lin_data_in': "set (linearize data_in') \ set (linearize data_in)" + by auto + have "sorted (map fst (linearize data_in))" + using valid_before by auto + then have sorted_lin_data_in': "sorted (map fst (linearize data_in'))" + unfolding lin_data_in' using sorted_filter by auto + have discard_alt: "discard = filter (\(t, X). enat (nt - t) > right I) (linearize data_in)" + unfolding discard_def[unfolded takedropWhile_queue_snd] takeWhile_filter[OF F1] .. + have lin_data_prev': "linearize data_prev' = + filter (\(t, X). enat (nt - t) \ right I) (linearize data_prev)" + unfolding data_prev'_def[unfolded takedropWhile_queue_fst] dropWhile_queue_rep + dropWhile_filter[OF F2] .. + have "sorted (map fst (linearize data_prev))" + using valid_before by auto + then have sorted_lin_data_prev': "sorted (map fst (linearize data_prev'))" + unfolding lin_data_prev' using sorted_filter by auto + have lookup_tuple_in': "\as. Mapping.lookup tuple_in' as = safe_max (fst ` + {tas \ ts_tuple_rel (set (linearize data_in')). valid_tuple tuple_since tas \ as = snd tas})" + proof - + fix as + show "Mapping.lookup tuple_in' as = safe_max (fst ` + {tas \ ts_tuple_rel (set (linearize data_in')). valid_tuple tuple_since tas \ as = snd tas})" + proof (cases "Mapping.lookup tuple_in as") + case None + then have "{tas \ ts_tuple_rel (set (linearize data_in)). + valid_tuple tuple_since tas \ as = snd tas} = {}" + using valid_before by (auto dest!: safe_max_empty_dest) + then have "{tas \ ts_tuple_rel (set (linearize data_in')). + valid_tuple tuple_since tas \ as = snd tas} = {}" + using ts_tuple_rel_mono[OF set_lin_data_in'] by auto + then show ?thesis + unfolding tuple_in_None_None[OF None] using iffD2[OF safe_max_empty, symmetric] by blast + next + case (Some t) + show ?thesis + proof (cases "\X. (t, X) \ set discard \ as \ X") + case True + then obtain X where X_def: "(t, X) \ set discard" "as \ X" + by auto + have "enat (nt - t) > right I" + using X_def(1) unfolding discard_alt by simp + moreover have "\t'. (t', as) \ ts_tuple_rel (set (linearize data_in)) \ + valid_tuple tuple_since (t', as) \ t' \ t" + using valid_before Some safe_max_Some_dest_le[OF finite_fst_ts_tuple_rel] + by (fastforce simp add: image_iff) + ultimately have "{tas \ ts_tuple_rel (set (linearize data_in')). + valid_tuple tuple_since tas \ as = snd tas} = {}" + unfolding lin_data_in' using ts_tuple_rel_set_filter + by (auto simp add: ts_tuple_rel_def) + (meson diff_le_mono2 enat_ord_simps(2) leD le_less_trans) + then show ?thesis + unfolding tuple_in_Some_None[OF Some X_def(2,1)] + using iffD2[OF safe_max_empty, symmetric] by blast + next + case False + then have lookup_Some: "Mapping.lookup tuple_in' as = Some t" + using tuple_in_Some_Some[OF Some] by auto + have t_as: "(t, as) \ ts_tuple_rel (set (linearize data_in))" + "valid_tuple tuple_since (t, as)" + using valid_before Some by (auto dest: safe_max_Some_dest_in[OF finite_fst_ts_tuple_rel]) + then obtain X where X_def: "as \ X" "(t, X) \ set (linearize data_in)" + by (auto simp add: ts_tuple_rel_def) + have "(t, X) \ set (linearize data_in')" + using X_def False unfolding discard_alt lin_data_in' by auto + then have t_in_fst: "t \ fst ` {tas \ ts_tuple_rel (set (linearize data_in')). + valid_tuple tuple_since tas \ as = snd tas}" + using t_as(2) X_def(1) by (auto simp add: ts_tuple_rel_def image_iff) + have "\t'. (t', as) \ ts_tuple_rel (set (linearize data_in)) \ + valid_tuple tuple_since (t', as) \ t' \ t" + using valid_before Some safe_max_Some_dest_le[OF finite_fst_ts_tuple_rel] + by (fastforce simp add: image_iff) + then have "Max (fst ` {tas \ ts_tuple_rel (set (linearize data_in')). + valid_tuple tuple_since tas \ as = snd tas}) = t" + using Max_eqI[OF finite_fst_ts_tuple_rel, OF _ t_in_fst] + ts_tuple_rel_mono[OF set_lin_data_in'] by fastforce + then show ?thesis + unfolding lookup_Some using t_in_fst by (auto simp add: safe_max_def) + qed + qed + qed + have table_in: "table (args_n args) (args_R args) (Mapping.keys tuple_in')" + using tuple_in'_keys valid_before by (auto simp add: table_def) + have "ts_tuple_rel (set auxlist) = + {as \ ts_tuple_rel (set (linearize data_prev) \ set (linearize data_in)). + valid_tuple tuple_since as}" + using valid_before by auto + then have "ts_tuple_rel (set (filter (\(t, rel). enat (nt - t) \ right I) auxlist)) = + {as \ ts_tuple_rel (set (linearize data_prev') \ set (linearize data_in')). + valid_tuple tuple_since as}" + unfolding lin_data_prev' lin_data_in' ts_tuple_rel_Un ts_tuple_rel_filter by auto + then show ?thesis + using data_prev'_def data_in'_def tuple_in'_def discard_def valid_before nt_mono + sorted_lin_data_prev' sorted_lin_data_in' lin_data_prev' lin_data_in' lookup_tuple_in' + table_in unfolding I_def + by (auto simp only: valid_mmsaux.simps shift_end.simps Let_def split: prod.splits) auto + (* takes long *) +qed + +lemma valid_shift_end_mmsaux: "valid_mmsaux args cur aux auxlist \ nt \ cur \ + valid_mmsaux args cur (shift_end args nt aux) + (filter (\(t, rel). enat (nt - t) \ right (args_ivl args)) auxlist)" + using valid_shift_end_mmsaux_unfolded by (cases aux) fast + +setup_lifting type_definition_mapping + +lift_definition upd_set :: "('a, 'b) mapping \ ('a \ 'b) \ 'a set \ ('a, 'b) mapping" is + "\m f X a. if a \ X then Some (f a) else m a" . + +lemma Mapping_lookup_upd_set: "Mapping.lookup (upd_set m f X) a = + (if a \ X then Some (f a) else Mapping.lookup m a)" + by (simp add: Mapping.lookup.rep_eq upd_set.rep_eq) + +lemma Mapping_upd_set_keys: "Mapping.keys (upd_set m f X) = Mapping.keys m \ X" + by (auto simp add: Mapping_lookup_upd_set dest!: Mapping_keys_dest intro: Mapping_keys_intro) + +lift_definition upd_keys_on :: "('a, 'b) mapping \ ('a \ 'b \ 'b) \ 'a set \ + ('a, 'b) mapping" is + "\m f X a. case Mapping.lookup m a of Some b \ Some (if a \ X then f a b else b) + | None \ None" . + +lemma Mapping_lookup_upd_keys_on: "Mapping.lookup (upd_keys_on m f X) a = + (case Mapping.lookup m a of Some b \ Some (if a \ X then f a b else b) | None \ None)" + by (simp add: Mapping.lookup.rep_eq upd_keys_on.rep_eq) + +lemma Mapping_upd_keys_sub: "Mapping.keys (upd_keys_on m f X) = Mapping.keys m" + by (auto simp add: Mapping_lookup_upd_keys_on dest!: Mapping_keys_dest intro: Mapping_keys_intro + split: option.splits) + +lemma fold_append_queue_rep: "linearize (fold (\x q. append_queue x q) xs q) = linearize q @ xs" + by (induction xs arbitrary: q) (auto simp add: append_queue_rep) + +lemma Max_Un_absorb: + assumes "finite X" "X \ {}" "finite Y" "(\x y. y \ Y \ x \ X \ y \ x)" + shows "Max (X \ Y) = Max X" +proof - + have Max_X_in_X: "Max X \ X" + using Max_in[OF assms(1,2)] . + have Max_X_in_XY: "Max X \ X \ Y" + using Max_in[OF assms(1,2)] by auto + have fin: "finite (X \ Y)" + using assms(1,3) by auto + have Y_le_Max_X: "\y. y \ Y \ y \ Max X" + using assms(4)[OF _ Max_X_in_X] . + have XY_le_Max_X: "\y. y \ X \ Y \ y \ Max X" + using Max_ge[OF assms(1)] Y_le_Max_X by auto + show ?thesis + using Max_eqI[OF fin XY_le_Max_X Max_X_in_XY] by auto +qed + +lemma Mapping_lookup_fold_upd_set_idle: "{(t, X) \ set xs. as \ Z X t} = {} \ + Mapping.lookup (fold (\(t, X) m. upd_set m (\_. t) (Z X t)) xs m) as = Mapping.lookup m as" +proof (induction xs arbitrary: m) + case Nil + then show ?case by simp +next + case (Cons x xs) + obtain x1 x2 where "x = (x1, x2)" by (cases x) + have "Mapping.lookup (fold (\(t, X) m. upd_set m (\_. t) (Z X t)) xs (upd_set m (\_. x1) (Z x2 x1))) as = + Mapping.lookup (upd_set m (\_. x1) (Z x2 x1)) as" + using Cons by auto + also have "Mapping.lookup (upd_set m (\_. x1) (Z x2 x1)) as = Mapping.lookup m as" + using Cons.prems by (auto simp: \x = (x1, x2)\ Mapping_lookup_upd_set) + finally show ?case by (simp add: \x = (x1, x2)\) +qed + +lemma Mapping_lookup_fold_upd_set_max: "{(t, X) \ set xs. as \ Z X t} \ {} \ + sorted (map fst xs) \ + Mapping.lookup (fold (\(t, X) m. upd_set m (\_. t) (Z X t)) xs m) as = + Some (Max (fst ` {(t, X) \ set xs. as \ Z X t}))" +proof (induction xs arbitrary: m) + case (Cons x xs) + obtain t X where tX_def: "x = (t, X)" + by (cases x) auto + have set_fst_eq: "(fst ` {(t, X). (t, X) \ set (x # xs) \ as \ Z X t}) = + ((fst ` {(t, X). (t, X) \ set xs \ as \ Z X t}) \ + (if as \ Z X t then {t} else {}))" + using image_iff by (fastforce simp add: tX_def split: if_splits) + show ?case + proof (cases "{(t, X). (t, X) \ set xs \ as \ Z X t} \ {}") + case True + have "{(t, X). (t, X) \ set xs \ as \ Z X t} \ set xs" + by auto + then have fin: "finite (fst ` {(t, X). (t, X) \ set xs \ as \ Z X t})" + by (simp add: finite_subset) + have "Max (insert t (fst ` {(t, X). (t, X) \ set xs \ as \ Z X t})) = + Max (fst ` {(t, X). (t, X) \ set xs \ as \ Z X t})" + using Max_Un_absorb[OF fin, of "{t}"] True Cons(3) tX_def by auto + then show ?thesis + using Cons True unfolding set_fst_eq by auto + next + case False + then have empty: "{(t, X). (t, X) \ set xs \ as \ Z X t} = {}" + by auto + then have "as \ Z X t" + using Cons(2) set_fst_eq by fastforce + then show ?thesis + using Mapping_lookup_fold_upd_set_idle[OF empty] unfolding set_fst_eq empty + by (auto simp add: Mapping_lookup_upd_set tX_def) + qed +qed simp + +fun add_new_ts_mmsaux' :: "args \ ts \ 'a mmsaux \ 'a mmsaux" where + "add_new_ts_mmsaux' args nt (t, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since) = + (let I = args_ivl args; + (data_prev, move) = takedropWhile_queue (\(t, X). nt - t \ left I) data_prev; + data_in = fold (\(t, X) data_in. append_queue (t, X) data_in) move data_in; + tuple_in = fold (\(t, X) tuple_in. upd_set tuple_in (\_. t) + {as \ X. valid_tuple tuple_since (t, as)}) move tuple_in in + (nt, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since))" + +lemma Mapping_keys_fold_upd_set: "k \ Mapping.keys (fold (\(t, X) m. upd_set m (\_. t) (Z t X)) + xs m) \ k \ Mapping.keys m \ (\(t, X) \ set xs. k \ Z t X)" + by (induction xs arbitrary: m) (fastforce simp add: Mapping_upd_set_keys)+ + +lemma valid_add_new_ts_mmsaux'_unfolded: + assumes valid_before: "valid_mmsaux args cur + (ot, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since) auxlist" + and nt_mono: "nt \ cur" + shows "valid_mmsaux args nt (add_new_ts_mmsaux' args nt + (ot, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since)) auxlist" +proof - + define I where "I = args_ivl args" + define n where "n = args_n args" + define L where "L = args_L args" + define R where "R = args_R args" + define pos where "pos = args_pos args" + define data_prev' where "data_prev' \ dropWhile_queue (\(t, X). nt - t \ left I) data_prev" + define move where "move \ takeWhile (\(t, X). nt - t \ left I) (linearize data_prev)" + define data_in' where "data_in' \ fold (\(t, X) data_in. append_queue (t, X) data_in) + move data_in" + define tuple_in' where "tuple_in' \ fold (\(t, X) tuple_in. upd_set tuple_in (\_. t) + {as \ X. valid_tuple tuple_since (t, as)}) move tuple_in" + have tuple_in'_keys: "\as. as \ Mapping.keys tuple_in' \ as \ Mapping.keys tuple_in \ + (\(t, X)\set move. as \ {as \ X. valid_tuple tuple_since (t, as)})" + using Mapping_keys_fold_upd_set[of _ "\t X. {as \ X. valid_tuple tuple_since (t, as)}"] + by (auto simp add: tuple_in'_def) + have F1: "sorted (map fst (linearize data_in))" "\t \ fst ` set (linearize data_in). t \ nt" + "\t \ fst ` set (linearize data_in). t \ ot \ ot - t \ left I" + using valid_before nt_mono unfolding I_def by auto + have F2: "sorted (map fst (linearize data_prev))" "\t \ fst ` set (linearize data_prev). t \ nt" + "\t \ fst ` set (linearize data_prev). t \ ot \ ot - t < left I" + using valid_before nt_mono unfolding I_def by auto + have lin_data_prev': "linearize data_prev' = + filter (\(t, X). nt - t < left I) (linearize data_prev)" + unfolding data_prev'_def dropWhile_queue_rep dropWhile_filter'[OF F2(1,2)] .. + have move_filter: "move = filter (\(t, X). nt - t \ left I) (linearize data_prev)" + unfolding move_def takeWhile_filter'[OF F2(1,2)] .. + then have sorted_move: "sorted (map fst move)" + using sorted_filter F2 by auto + have "\t\fst ` set move. t \ ot \ ot - t < left I" + using move_filter F2(3) set_filter by auto + then have fst_set_before: "\t\fst ` set (linearize data_in). \t'\fst ` set move. t \ t'" + using F1(3) by fastforce + then have fst_ts_tuple_rel_before: "\t\fst ` ts_tuple_rel (set (linearize data_in)). + \t'\fst ` ts_tuple_rel (set move). t \ t'" + by (fastforce simp add: ts_tuple_rel_def) + have sorted_lin_data_prev': "sorted (map fst (linearize data_prev'))" + unfolding lin_data_prev' using sorted_filter F2 by auto + have lin_data_in': "linearize data_in' = linearize data_in @ move" + unfolding data_in'_def using fold_append_queue_rep by fastforce + have sorted_lin_data_in': "sorted (map fst (linearize data_in'))" + unfolding lin_data_in' using F1(1) sorted_move fst_set_before by (simp add: sorted_append) + have set_lin_prev'_in': "set (linearize data_prev') \ set (linearize data_in') = + set (linearize data_prev) \ set (linearize data_in)" + using lin_data_prev' lin_data_in' move_filter by auto + have ts_tuple_rel': "ts_tuple_rel (set auxlist) = + {tas \ ts_tuple_rel (set (linearize data_prev') \ set (linearize data_in')). + valid_tuple tuple_since tas}" + unfolding set_lin_prev'_in' using valid_before by auto + have lookup': "\as. Mapping.lookup tuple_in' as = safe_max (fst ` + {tas \ ts_tuple_rel (set (linearize data_in')). + valid_tuple tuple_since tas \ as = snd tas})" + proof - + fix as + show "Mapping.lookup tuple_in' as = safe_max (fst ` + {tas \ ts_tuple_rel (set (linearize data_in')). + valid_tuple tuple_since tas \ as = snd tas})" + proof (cases "{(t, X) \ set move. as \ X \ valid_tuple tuple_since (t, as)} = {}") + case True + have move_absorb: "{tas \ ts_tuple_rel (set (linearize data_in)). + valid_tuple tuple_since tas \ as = snd tas} = + {tas \ ts_tuple_rel (set (linearize data_in @ move)). + valid_tuple tuple_since tas \ as = snd tas}" + using True by (auto simp add: ts_tuple_rel_def) + have "Mapping.lookup tuple_in as = + safe_max (fst ` {tas \ ts_tuple_rel (set (linearize data_in)). + valid_tuple tuple_since tas \ as = snd tas})" + using valid_before by auto + then have "Mapping.lookup tuple_in as = + safe_max (fst ` {tas \ ts_tuple_rel (set (linearize data_in')). + valid_tuple tuple_since tas \ as = snd tas})" + unfolding lin_data_in' move_absorb . + then show ?thesis + using Mapping_lookup_fold_upd_set_idle[of "move" as + "\X t. {as \ X. valid_tuple tuple_since (t, as)}"] True + unfolding tuple_in'_def by auto + next + case False + have split: "fst ` {tas \ ts_tuple_rel (set (linearize data_in')). + valid_tuple tuple_since tas \ as = snd tas} = + fst ` {tas \ ts_tuple_rel (set move). valid_tuple tuple_since tas \ as = snd tas} \ + fst ` {tas \ ts_tuple_rel (set (linearize data_in)). + valid_tuple tuple_since tas \ as = snd tas}" + unfolding lin_data_in' set_append ts_tuple_rel_Un by auto + have max_eq: "Max (fst ` {tas \ ts_tuple_rel (set move). + valid_tuple tuple_since tas \ as = snd tas}) = + Max (fst ` {tas \ ts_tuple_rel (set (linearize data_in')). + valid_tuple tuple_since tas \ as = snd tas})" + unfolding split using False fst_ts_tuple_rel_before + by (fastforce simp add: ts_tuple_rel_def + intro!: Max_Un_absorb[OF finite_fst_ts_tuple_rel _ finite_fst_ts_tuple_rel, symmetric]) + have "fst ` {(t, X). (t, X) \ set move \ as \ {as \ X. valid_tuple tuple_since (t, as)}} = + fst ` {tas \ ts_tuple_rel (set move). valid_tuple tuple_since tas \ as = snd tas}" + by (auto simp add: ts_tuple_rel_def image_iff) + then have "Mapping.lookup tuple_in' as = Some (Max (fst ` {tas \ ts_tuple_rel (set move). + valid_tuple tuple_since tas \ as = snd tas}))" + using Mapping_lookup_fold_upd_set_max[of "move" as + "\X t. {as \ X. valid_tuple tuple_since (t, as)}", OF _ sorted_move] False + unfolding tuple_in'_def by (auto simp add: ts_tuple_rel_def) + then show ?thesis + unfolding max_eq using False + by (auto simp add: safe_max_def lin_data_in' ts_tuple_rel_def) + qed + qed + have table_in': "table n R (Mapping.keys tuple_in')" + proof - + { + fix as + assume assm: "as \ Mapping.keys tuple_in'" + have "wf_tuple n R as" + using tuple_in'_keys[OF assm] + proof (rule disjE) + assume "as \ Mapping.keys tuple_in" + then show "wf_tuple n R as" + using valid_before by (auto simp add: table_def n_def R_def) + next + assume "\(t, X)\set move. as \ {as \ X. valid_tuple tuple_since (t, as)}" + then obtain t X where tX_def: "(t, X) \ set move" "as \ X" + by auto + then have "as \ \(snd ` set (linearize data_prev))" + unfolding move_def using set_takeWhileD by force + then show "wf_tuple n R as" + using valid_before by (auto simp add: n_def R_def) + qed + } + then show ?thesis + by (auto simp add: table_def) + qed + have data_prev'_move: "(data_prev', move) = + takedropWhile_queue (\(t, X). nt - t \ left I) data_prev" + using takedropWhile_queue_fst takedropWhile_queue_snd data_prev'_def move_def + by (metis surjective_pairing) + moreover have "valid_mmsaux args nt (nt, gc, maskL, maskR, data_prev', data_in', + tuple_in', tuple_since) auxlist" + using lin_data_prev' sorted_lin_data_prev' lin_data_in' move_filter sorted_lin_data_in' + nt_mono valid_before ts_tuple_rel' lookup' table_in' unfolding I_def + by (auto simp only: valid_mmsaux.simps Let_def n_def R_def split: option.splits) auto + (* takes long *) + ultimately show ?thesis + by (auto simp only: add_new_ts_mmsaux'.simps Let_def data_in'_def tuple_in'_def I_def + split: prod.splits) +qed + +lemma valid_add_new_ts_mmsaux': "valid_mmsaux args cur aux auxlist \ nt \ cur \ + valid_mmsaux args nt (add_new_ts_mmsaux' args nt aux) auxlist" + using valid_add_new_ts_mmsaux'_unfolded by (cases aux) fast + +definition add_new_ts_mmsaux :: "args \ ts \ 'a mmsaux \ 'a mmsaux" where + "add_new_ts_mmsaux args nt aux = add_new_ts_mmsaux' args nt (shift_end args nt aux)" + +lemma valid_add_new_ts_mmsaux: + assumes "valid_mmsaux args cur aux auxlist" "nt \ cur" + shows "valid_mmsaux args nt (add_new_ts_mmsaux args nt aux) + (filter (\(t, rel). enat (nt - t) \ right (args_ivl args)) auxlist)" + using valid_add_new_ts_mmsaux'[OF valid_shift_end_mmsaux[OF assms] assms(2)] + unfolding add_new_ts_mmsaux_def . + +fun join_mmsaux :: "args \ 'a table \ 'a mmsaux \ 'a mmsaux" where + "join_mmsaux args X (t, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since) = + (let pos = args_pos args in + (if maskL = maskR then + (let tuple_in = Mapping.filter (join_filter_cond pos X) tuple_in; + tuple_since = Mapping.filter (join_filter_cond pos X) tuple_since in + (t, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since)) + else if (\i \ set maskL. \i) then + (let nones = replicate (length maskL) None; + take_all = (pos \ nones \ X); + tuple_in = (if take_all then tuple_in else Mapping.empty); + tuple_since = (if take_all then tuple_since else Mapping.empty) in + (t, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since)) + else + (let tuple_in = Mapping.filter (\as _. proj_tuple_in_join pos maskL as X) tuple_in; + tuple_since = Mapping.filter (\as _. proj_tuple_in_join pos maskL as X) tuple_since in + (t, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since))))" + +fun join_mmsaux_abs :: "args \ 'a table \ 'a mmsaux \ 'a mmsaux" where + "join_mmsaux_abs args X (t, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since) = + (let pos = args_pos args in + (let tuple_in = Mapping.filter (\as _. proj_tuple_in_join pos maskL as X) tuple_in; + tuple_since = Mapping.filter (\as _. proj_tuple_in_join pos maskL as X) tuple_since in + (t, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since)))" + +lemma Mapping_filter_cong: + assumes cong: "(\k v. k \ Mapping.keys m \ f k v = f' k v)" + shows "Mapping.filter f m = Mapping.filter f' m" +proof - + have "\k. Mapping.lookup (Mapping.filter f m) k = Mapping.lookup (Mapping.filter f' m) k" + using cong + by (fastforce simp add: Mapping.lookup_filter intro: Mapping_keys_intro split: option.splits) + then show ?thesis + by (simp add: mapping_eqI) +qed + +lemma join_mmsaux_abs_eq: + assumes valid_before: "valid_mmsaux args cur + (nt, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since) auxlist" + and table_left: "table (args_n args) (args_L args) X" + shows "join_mmsaux args X (nt, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since) = + join_mmsaux_abs args X (nt, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since)" +proof (cases "maskL = maskR") + case True + define n where "n = args_n args" + define L where "L = args_L args" + define pos where "pos = args_pos args" + have keys_wf_in: "\as. as \ Mapping.keys tuple_in \ wf_tuple n L as" + using wf_tuple_change_base valid_before True by (fastforce simp add: table_def n_def L_def) + have cong_in: "\as n. as \ Mapping.keys tuple_in \ + proj_tuple_in_join pos maskL as X \ join_cond pos X as" + using proj_tuple_in_join_mask_idle[OF keys_wf_in] valid_before + by (auto simp only: valid_mmsaux.simps n_def L_def pos_def) + have keys_wf_since: "\as. as \ Mapping.keys tuple_since \ wf_tuple n L as" + using wf_tuple_change_base valid_before True by (fastforce simp add: table_def n_def L_def) + have cong_since: "\as n. as \ Mapping.keys tuple_since \ + proj_tuple_in_join pos maskL as X \ join_cond pos X as" + using proj_tuple_in_join_mask_idle[OF keys_wf_since] valid_before + by (auto simp only: valid_mmsaux.simps n_def L_def pos_def) + show ?thesis + using True Mapping_filter_cong[OF cong_in, of tuple_in "\k _. k"] + Mapping_filter_cong[OF cong_since, of tuple_since "\k _. k"] + by (auto simp add: pos_def) +next + case False + define n where "n = args_n args" + define L where "L = args_L args" + define R where "R = args_R args" + define pos where "pos = args_pos args" + from False show ?thesis + proof (cases "\i \ set maskL. \i") + case True + have length_maskL: "length maskL = n" + using valid_before by (auto simp add: join_mask_def n_def) + have proj_rep: "\as. wf_tuple n R as \ proj_tuple maskL as = replicate (length maskL) None" + using True proj_tuple_replicate by (force simp add: length_maskL wf_tuple_def) + have keys_wf_in: "\as. as \ Mapping.keys tuple_in \ wf_tuple n R as" + using valid_before by (auto simp add: table_def n_def R_def) + have keys_wf_since: "\as. as \ Mapping.keys tuple_since \ wf_tuple n R as" + using valid_before by (auto simp add: table_def n_def R_def) + have "\as. Mapping.lookup (Mapping.filter (\as _. proj_tuple_in_join pos maskL as X) + tuple_in) as = Mapping.lookup (if (pos \ replicate (length maskL) None \ X) + then tuple_in else Mapping.empty) as" + using proj_rep[OF keys_wf_in] + by (auto simp add: Mapping.lookup_filter Mapping.lookup_empty proj_tuple_in_join_def + Mapping_keys_intro split: option.splits) + moreover have "\as. Mapping.lookup (Mapping.filter (\as _. proj_tuple_in_join pos maskL as X) + tuple_since) as = Mapping.lookup (if (pos \ replicate (length maskL) None \ X) + then tuple_since else Mapping.empty) as" + using proj_rep[OF keys_wf_since] + by (auto simp add: Mapping.lookup_filter Mapping.lookup_empty proj_tuple_in_join_def + Mapping_keys_intro split: option.splits) + ultimately show ?thesis + using False True by (auto simp add: mapping_eqI Let_def pos_def) + qed (auto simp add: Let_def) +qed + +lemma valid_join_mmsaux_unfolded: + assumes valid_before: "valid_mmsaux args cur + (nt, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since) auxlist" + and table_left': "table (args_n args) (args_L args) X" + shows "valid_mmsaux args cur + (join_mmsaux args X (nt, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since)) + (map (\(t, rel). (t, join rel (args_pos args) X)) auxlist)" +proof - + define n where "n = args_n args" + define L where "L = args_L args" + define R where "R = args_R args" + define pos where "pos = args_pos args" + note table_left = table_left'[unfolded n_def[symmetric] L_def[symmetric]] + define tuple_in' where "tuple_in' \ + Mapping.filter (\as _. proj_tuple_in_join pos maskL as X) tuple_in" + define tuple_since' where "tuple_since' \ + Mapping.filter (\as _. proj_tuple_in_join pos maskL as X) tuple_since" + have tuple_in_None_None: "\as. Mapping.lookup tuple_in as = None \ + Mapping.lookup tuple_in' as = None" + unfolding tuple_in'_def using Mapping_lookup_filter_not_None by fastforce + have tuple_in'_keys: "\as. as \ Mapping.keys tuple_in' \ as \ Mapping.keys tuple_in" + using tuple_in_None_None + by (fastforce intro: Mapping_keys_intro dest: Mapping_keys_dest) + have tuple_since_None_None: "\as. Mapping.lookup tuple_since as = None \ + Mapping.lookup tuple_since' as = None" + unfolding tuple_since'_def using Mapping_lookup_filter_not_None by fastforce + have tuple_since'_keys: "\as. as \ Mapping.keys tuple_since' \ as \ Mapping.keys tuple_since" + using tuple_since_None_None + by (fastforce intro: Mapping_keys_intro dest: Mapping_keys_dest) + have ts_tuple_rel': "ts_tuple_rel (set (map (\(t, rel). (t, join rel pos X)) auxlist)) = + {tas \ ts_tuple_rel (set (linearize data_prev) \ set (linearize data_in)). + valid_tuple tuple_since' tas}" + proof (rule set_eqI, rule iffI) + fix tas + assume assm: "tas \ ts_tuple_rel (set (map (\(t, rel). (t, join rel pos X)) auxlist))" + then obtain t as Z where tas_def: "tas = (t, as)" "as \ join Z pos X" "(t, Z) \ set auxlist" + "(t, join Z pos X) \ set (map (\(t, rel). (t, join rel pos X)) auxlist)" + by (fastforce simp add: ts_tuple_rel_def) + from tas_def(3) have table_Z: "table n R Z" + using valid_before by (auto simp add: n_def R_def) + have proj: "as \ Z" "proj_tuple_in_join pos maskL as X" + using tas_def(2) join_sub[OF _ table_left table_Z] valid_before + by (auto simp add: n_def L_def R_def pos_def) + then have "(t, as) \ ts_tuple_rel (set (auxlist))" + using tas_def(3) by (auto simp add: ts_tuple_rel_def) + then have tas_in: "(t, as) \ ts_tuple_rel + (set (linearize data_prev) \ set (linearize data_in))" "valid_tuple tuple_since (t, as)" + using valid_before by auto + then obtain t' where t'_def: "Mapping.lookup tuple_since as = Some t'" "t \ t'" + by (auto simp add: valid_tuple_def split: option.splits) + then have valid_tuple_since': "valid_tuple tuple_since' (t, as)" + using proj(2) + by (auto simp add: tuple_since'_def Mapping_lookup_filter_Some valid_tuple_def) + show "tas \ {tas \ ts_tuple_rel (set (linearize data_prev) \ set (linearize data_in)). + valid_tuple tuple_since' tas}" + using tas_in valid_tuple_since' unfolding tas_def(1)[symmetric] by auto + next + fix tas + assume assm: "tas \ {tas \ ts_tuple_rel + (set (linearize data_prev) \ set (linearize data_in)). valid_tuple tuple_since' tas}" + then obtain t as where tas_def: "tas = (t, as)" "valid_tuple tuple_since' (t, as)" + by (auto simp add: ts_tuple_rel_def) + from tas_def(2) have "valid_tuple tuple_since (t, as)" + unfolding tuple_since'_def using Mapping_lookup_filter_not_None + by (force simp add: valid_tuple_def split: option.splits) + then have "(t, as) \ ts_tuple_rel (set auxlist)" + using valid_before assm tas_def(1) by auto + then obtain Z where Z_def: "as \ Z" "(t, Z) \ set auxlist" + by (auto simp add: ts_tuple_rel_def) + then have table_Z: "table n R Z" + using valid_before by (auto simp add: n_def R_def) + from tas_def(2) have "proj_tuple_in_join pos maskL as X" + unfolding tuple_since'_def using Mapping_lookup_filter_Some_P + by (fastforce simp add: valid_tuple_def split: option.splits) + then have as_in_join: "as \ join Z pos X" + using join_sub[OF _ table_left table_Z] Z_def(1) valid_before + by (auto simp add: n_def L_def R_def pos_def) + then show "tas \ ts_tuple_rel (set (map (\(t, rel). (t, join rel pos X)) auxlist))" + using Z_def unfolding tas_def(1) by (auto simp add: ts_tuple_rel_def) + qed + have lookup_tuple_in': "\as. Mapping.lookup tuple_in' as = safe_max (fst ` + {tas \ ts_tuple_rel (set (linearize data_in)). valid_tuple tuple_since' tas \ as = snd tas})" + proof - + fix as + show "Mapping.lookup tuple_in' as = safe_max (fst ` + {tas \ ts_tuple_rel (set (linearize data_in)). valid_tuple tuple_since' tas \ as = snd tas})" + proof (cases "Mapping.lookup tuple_in as") + case None + then have "{tas \ ts_tuple_rel (set (linearize data_in)). + valid_tuple tuple_since tas \ as = snd tas} = {}" + using valid_before by (auto dest!: safe_max_empty_dest) + then have "{tas \ ts_tuple_rel (set (linearize data_in)). + valid_tuple tuple_since' tas \ as = snd tas} = {}" + using Mapping_lookup_filter_not_None + by (fastforce simp add: valid_tuple_def tuple_since'_def split: option.splits) + then show ?thesis + unfolding tuple_in_None_None[OF None] using iffD2[OF safe_max_empty, symmetric] by blast + next + case (Some t) + show ?thesis + proof (cases "proj_tuple_in_join pos maskL as X") + case True + then have lookup_tuple_in': "Mapping.lookup tuple_in' as = Some t" + using Some unfolding tuple_in'_def by (simp add: Mapping_lookup_filter_Some) + have "(t, as) \ ts_tuple_rel (set (linearize data_in))" "valid_tuple tuple_since (t, as)" + using valid_before Some by (auto dest: safe_max_Some_dest_in[OF finite_fst_ts_tuple_rel]) + then have t_in_fst: "t \ fst ` {tas \ ts_tuple_rel (set (linearize data_in)). + valid_tuple tuple_since' tas \ as = snd tas}" + using True by (auto simp add: image_iff valid_tuple_def tuple_since'_def + Mapping_lookup_filter_Some split: option.splits) + have "\t'. valid_tuple tuple_since' (t', as) \ valid_tuple tuple_since (t', as)" + using Mapping_lookup_filter_not_None + by (fastforce simp add: valid_tuple_def tuple_since'_def split: option.splits) + then have "\t'. (t', as) \ ts_tuple_rel (set (linearize data_in)) \ + valid_tuple tuple_since' (t', as) \ t' \ t" + using valid_before Some safe_max_Some_dest_le[OF finite_fst_ts_tuple_rel] + by (fastforce simp add: image_iff) + then have "Max (fst ` {tas \ ts_tuple_rel (set (linearize data_in)). + valid_tuple tuple_since' tas \ as = snd tas}) = t" + using Max_eqI[OF finite_fst_ts_tuple_rel[of "linearize data_in"], + OF _ t_in_fst] by fastforce + then show ?thesis + unfolding lookup_tuple_in' using t_in_fst by (auto simp add: safe_max_def) + next + case False + then have lookup_tuple': "Mapping.lookup tuple_in' as = None" + "Mapping.lookup tuple_since' as = None" + unfolding tuple_in'_def tuple_since'_def + by (auto simp add: Mapping_lookup_filter_None) + then have "\tas. \(valid_tuple tuple_since' tas \ as = snd tas)" + by (auto simp add: valid_tuple_def split: option.splits) + then show ?thesis + unfolding lookup_tuple' by (auto simp add: safe_max_def) + qed + qed + qed + have table_join': "\t ys. (t, ys) \ set auxlist \ table n R (join ys pos X)" + proof - + fix t ys + assume "(t, ys) \ set auxlist" + then have table_ys: "table n R ys" + using valid_before + by (auto simp add: n_def L_def R_def pos_def) + show "table n R (join ys pos X)" + using join_table[OF table_ys table_left, of pos R] valid_before + by (auto simp add: n_def L_def R_def pos_def) + qed + have table_in': "table n R (Mapping.keys tuple_in')" + using tuple_in'_keys valid_before + by (auto simp add: n_def L_def R_def pos_def table_def) + have table_since': "table n R (Mapping.keys tuple_since')" + using tuple_since'_keys valid_before + by (auto simp add: n_def L_def R_def pos_def table_def) + show ?thesis + unfolding join_mmsaux_abs_eq[OF valid_before table_left'] + using valid_before ts_tuple_rel' lookup_tuple_in' tuple_in'_def tuple_since'_def table_join' + Mapping_filter_keys[of tuple_since "\as. case as of Some t \ t \ nt"] + table_in' table_since' by (auto simp add: n_def L_def R_def pos_def table_def Let_def) +qed + +lemma valid_join_mmsaux: "valid_mmsaux args cur aux auxlist \ + table (args_n args) (args_L args) X \ valid_mmsaux args cur + (join_mmsaux args X aux) (map (\(t, rel). (t, join rel (args_pos args) X)) auxlist)" + using valid_join_mmsaux_unfolded by (cases aux) fast + +fun gc_mmsaux :: "'a mmsaux \ 'a mmsaux" where + "gc_mmsaux (nt, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since) = + (let all_tuples = \(snd ` (set (linearize data_prev) \ set (linearize data_in))); + tuple_since' = Mapping.filter (\as _. as \ all_tuples) tuple_since in + (nt, nt, maskL, maskR, data_prev, data_in, tuple_in, tuple_since'))" + +lemma valid_gc_mmsaux_unfolded: + assumes valid_before: "valid_mmsaux args cur (nt, gc, maskL, maskR, data_prev, data_in, + tuple_in, tuple_since) ys" + shows "valid_mmsaux args cur (gc_mmsaux (nt, gc, maskL, maskR, data_prev, data_in, + tuple_in, tuple_since)) ys" +proof - + define n where "n = args_n args" + define L where "L = args_L args" + define R where "R = args_R args" + define pos where "pos = args_pos args" + define all_tuples where "all_tuples \ \(snd ` (set (linearize data_prev) \ + set (linearize data_in)))" + define tuple_since' where "tuple_since' \ Mapping.filter (\as _. as \ all_tuples) tuple_since" + have tuple_since_None_None: "\as. Mapping.lookup tuple_since as = None \ + Mapping.lookup tuple_since' as = None" + unfolding tuple_since'_def using Mapping_lookup_filter_not_None by fastforce + have tuple_since'_keys: "\as. as \ Mapping.keys tuple_since' \ as \ Mapping.keys tuple_since" + using tuple_since_None_None + by (fastforce intro: Mapping_keys_intro dest: Mapping_keys_dest) + then have table_since': "table n R (Mapping.keys tuple_since')" + using valid_before by (auto simp add: table_def n_def R_def) + have data_cong: "\tas. tas \ ts_tuple_rel (set (linearize data_prev) \ + set (linearize data_in)) \ valid_tuple tuple_since' tas = valid_tuple tuple_since tas" + proof - + fix tas + assume assm: "tas \ ts_tuple_rel (set (linearize data_prev) \ + set (linearize data_in))" + define t where "t \ fst tas" + define as where "as \ snd tas" + have "as \ all_tuples" + using assm by (force simp add: as_def all_tuples_def ts_tuple_rel_def) + then have "Mapping.lookup tuple_since' as = Mapping.lookup tuple_since as" + by (auto simp add: tuple_since'_def Mapping.lookup_filter split: option.splits) + then show "valid_tuple tuple_since' tas = valid_tuple tuple_since tas" + by (auto simp add: valid_tuple_def as_def split: option.splits) metis + qed + then have data_in_cong: "\tas. tas \ ts_tuple_rel (set (linearize data_in)) \ + valid_tuple tuple_since' tas = valid_tuple tuple_since tas" + by (auto simp add: ts_tuple_rel_Un) + have "ts_tuple_rel (set ys) = + {tas \ ts_tuple_rel (set (linearize data_prev) \ set (linearize data_in)). + valid_tuple tuple_since' tas}" + using data_cong valid_before by auto + moreover have "(\as. Mapping.lookup tuple_in as = safe_max (fst ` + {tas \ ts_tuple_rel (set (linearize data_in)). valid_tuple tuple_since' tas \ as = snd tas}))" + using valid_before by auto (meson data_in_cong) + moreover have "(\as \ Mapping.keys tuple_since'. case Mapping.lookup tuple_since' as of + Some t \ t \ nt)" + using Mapping.keys_filter valid_before + by (auto simp add: tuple_since'_def Mapping.lookup_filter split: option.splits + intro!: Mapping_keys_intro dest: Mapping_keys_dest) + ultimately show ?thesis + using all_tuples_def tuple_since'_def valid_before table_since' + by (auto simp add: n_def R_def) +qed + +lemma valid_gc_mmsaux: "valid_mmsaux args cur aux ys \ valid_mmsaux args cur (gc_mmsaux aux) ys" + using valid_gc_mmsaux_unfolded by (cases aux) fast + +fun gc_join_mmsaux :: "args \ 'a table \ 'a mmsaux \ 'a mmsaux" where + "gc_join_mmsaux args X (t, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since) = + (if enat (t - gc) > right (args_ivl args) then join_mmsaux args X (gc_mmsaux (t, gc, maskL, maskR, + data_prev, data_in, tuple_in, tuple_since)) + else join_mmsaux args X (t, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since))" + +lemma gc_join_mmsaux_alt: "gc_join_mmsaux args rel1 aux = join_mmsaux args rel1 (gc_mmsaux aux) \ + gc_join_mmsaux args rel1 aux = join_mmsaux args rel1 aux" + by (cases aux) (auto simp only: gc_join_mmsaux.simps split: if_splits) + +lemma valid_gc_join_mmsaux: + assumes "valid_mmsaux args cur aux auxlist" "table (args_n args) (args_L args) rel1" + shows "valid_mmsaux args cur (gc_join_mmsaux args rel1 aux) + (map (\(t, rel). (t, join rel (args_pos args) rel1)) auxlist)" + using gc_join_mmsaux_alt[of args rel1 aux] + using valid_join_mmsaux[OF valid_gc_mmsaux[OF assms(1)] assms(2)] + valid_join_mmsaux[OF assms] + by auto + +fun add_new_table_mmsaux :: "args \ 'a table \ 'a mmsaux \ 'a mmsaux" where + "add_new_table_mmsaux args X (t, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since) = + (let tuple_since = upd_set tuple_since (\_. t) (X - Mapping.keys tuple_since) in + (if 0 \ left (args_ivl args) then (t, gc, maskL, maskR, data_prev, append_queue (t, X) data_in, + upd_set tuple_in (\_. t) X, tuple_since) + else (t, gc, maskL, maskR, append_queue (t, X) data_prev, data_in, tuple_in, tuple_since)))" + +lemma valid_add_new_table_mmsaux_unfolded: + assumes valid_before: "valid_mmsaux args cur + (nt, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since) auxlist" + and table_X: "table (args_n args) (args_R args) X" + shows "valid_mmsaux args cur (add_new_table_mmsaux args X + (nt, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since)) + (case auxlist of + [] => [(cur, X)] + | ((t, y) # ts) \ if t = cur then (t, y \ X) # ts else (cur, X) # auxlist)" +proof - + have cur_nt: "cur = nt" + using valid_before by auto + define I where "I = args_ivl args" + define n where "n = args_n args" + define L where "L = args_L args" + define R where "R = args_R args" + define pos where "pos = args_pos args" + define tuple_in' where "tuple_in' \ upd_set tuple_in (\_. nt) X" + define tuple_since' where "tuple_since' \ upd_set tuple_since (\_. nt) + (X - Mapping.keys tuple_since)" + define data_prev' where "data_prev' \ append_queue (nt, X) data_prev" + define data_in' where "data_in' \ append_queue (nt, X) data_in" + define auxlist' where "auxlist' \ (case auxlist of + [] => [(nt, X)] + | ((t, y) # ts) \ if t = nt then (t, y \ X) # ts else (nt, X) # auxlist)" + have table_in': "table n R (Mapping.keys tuple_in')" + using table_X valid_before + by (auto simp add: table_def tuple_in'_def Mapping_upd_set_keys n_def R_def) + have table_since': "table n R (Mapping.keys tuple_since')" + using table_X valid_before + by (auto simp add: table_def tuple_since'_def Mapping_upd_set_keys n_def R_def) + have tuple_since'_keys: "Mapping.keys tuple_since \ Mapping.keys tuple_since'" + using Mapping_upd_set_keys by (fastforce simp add: tuple_since'_def) + have lin_data_prev': "linearize data_prev' = linearize data_prev @ [(nt, X)]" + unfolding data_prev'_def append_queue_rep .. + have wf_data_prev': "\as. as \ \(snd ` (set (linearize data_prev'))) \ wf_tuple n R as" + unfolding lin_data_prev' using table_X valid_before + by (auto simp add: table_def n_def R_def) + have lin_data_in': "linearize data_in' = linearize data_in @ [(nt, X)]" + unfolding data_in'_def append_queue_rep .. + have table_auxlist': "\(t, X) \ set auxlist'. table n R X" + using table_X table_Un valid_before + by (auto simp add: auxlist'_def n_def R_def split: list.splits if_splits) + have lookup_tuple_since': "\as \ Mapping.keys tuple_since'. + case Mapping.lookup tuple_since' as of Some t \ t \ nt" + unfolding tuple_since'_def using valid_before Mapping_lookup_upd_set[of tuple_since] + by (auto dest: Mapping_keys_dest intro!: Mapping_keys_intro split: if_splits option.splits) + have ts_tuple_rel_auxlist': "ts_tuple_rel (set auxlist') = + ts_tuple_rel (set auxlist) \ ts_tuple_rel {(nt, X)}" + unfolding auxlist'_def + using ts_tuple_rel_ext ts_tuple_rel_ext' ts_tuple_rel_ext_Cons ts_tuple_rel_ext_Cons' + by (fastforce simp: ts_tuple_rel_def split: list.splits if_splits) + have valid_tuple_nt_X: "\tas. tas \ ts_tuple_rel {(nt, X)} \ valid_tuple tuple_since' tas" + using valid_before by (auto simp add: ts_tuple_rel_def valid_tuple_def tuple_since'_def + Mapping_lookup_upd_set dest: Mapping_keys_dest split: option.splits) + have valid_tuple_mono: "\tas. valid_tuple tuple_since tas \ valid_tuple tuple_since' tas" + by (auto simp add: valid_tuple_def tuple_since'_def Mapping_lookup_upd_set + intro: Mapping_keys_intro split: option.splits) + have ts_tuple_rel_auxlist': "ts_tuple_rel (set auxlist') = + {tas \ ts_tuple_rel (set (linearize data_prev) \ set (linearize data_in) \ {(nt, X)}). + valid_tuple tuple_since' tas}" + proof (rule set_eqI, rule iffI) + fix tas + assume assm: "tas \ ts_tuple_rel (set auxlist')" + show "tas \ {tas \ ts_tuple_rel (set (linearize data_prev) \ + set (linearize data_in) \ {(nt, X)}). valid_tuple tuple_since' tas}" + using assm[unfolded ts_tuple_rel_auxlist' ts_tuple_rel_Un] + proof (rule UnE) + assume assm: "tas \ ts_tuple_rel (set auxlist)" + then have "tas \ {tas \ ts_tuple_rel (set (linearize data_prev) \ + set (linearize data_in)). valid_tuple tuple_since tas}" + using valid_before by auto + then show "tas \ {tas \ ts_tuple_rel (set (linearize data_prev) \ + set (linearize data_in) \ {(nt, X)}). valid_tuple tuple_since' tas}" + using assm by (auto simp only: ts_tuple_rel_Un intro: valid_tuple_mono) + next + assume assm: "tas \ ts_tuple_rel {(nt, X)}" + show "tas \ {tas \ ts_tuple_rel (set (linearize data_prev) \ + set (linearize data_in) \ {(nt, X)}). valid_tuple tuple_since' tas}" + using assm valid_before by (auto simp add: ts_tuple_rel_Un tuple_since'_def + valid_tuple_def Mapping_lookup_upd_set ts_tuple_rel_def dest: Mapping_keys_dest + split: option.splits if_splits) + qed + next + fix tas + assume assm: "tas \ {tas \ ts_tuple_rel (set (linearize data_prev) \ + set (linearize data_in) \ {(nt, X)}). valid_tuple tuple_since' tas}" + then have "tas \ (ts_tuple_rel (set (linearize data_prev) \ + set (linearize data_in)) - ts_tuple_rel {(nt, X)}) \ ts_tuple_rel {(nt, X)}" + by (auto simp only: ts_tuple_rel_Un) + then show "tas \ ts_tuple_rel (set auxlist')" + proof (rule UnE) + assume assm': "tas \ ts_tuple_rel (set (linearize data_prev) \ + set (linearize data_in)) - ts_tuple_rel {(nt, X)}" + then have tas_in: "tas \ ts_tuple_rel (set (linearize data_prev) \ + set (linearize data_in))" + by (auto simp only: ts_tuple_rel_def) + obtain t as where tas_def: "tas = (t, as)" + by (cases tas) auto + have "t \ fst ` (set (linearize data_prev) \ set (linearize data_in))" + using assm' unfolding tas_def by (force simp add: ts_tuple_rel_def) + then have t_le_nt: "t \ nt" + using valid_before by auto + have valid_tas: "valid_tuple tuple_since' tas" + using assm by auto + have "valid_tuple tuple_since tas" + proof (cases "as \ Mapping.keys tuple_since") + case True + then show ?thesis + using valid_tas tas_def by (auto simp add: valid_tuple_def tuple_since'_def + Mapping_lookup_upd_set split: option.splits if_splits) + next + case False + then have "t = nt" "as \ X" + using valid_tas t_le_nt unfolding tas_def + by (auto simp add: valid_tuple_def tuple_since'_def Mapping_lookup_upd_set + intro: Mapping_keys_intro split: option.splits if_splits) + then have "False" + using assm' unfolding tas_def ts_tuple_rel_def by (auto simp only: ts_tuple_rel_def) + then show ?thesis + by simp + qed + then show "tas \ ts_tuple_rel (set auxlist')" + using tas_in valid_before by (auto simp add: ts_tuple_rel_auxlist') + qed (auto simp only: ts_tuple_rel_auxlist') + qed + show ?thesis + proof (cases "0 \ left I") + case True + then have add_def: "add_new_table_mmsaux args X (nt, gc, maskL, maskR, data_prev, data_in, + tuple_in, tuple_since) = (nt, gc, maskL, maskR, data_prev, data_in', + tuple_in', tuple_since')" + using data_in'_def tuple_in'_def tuple_since'_def unfolding I_def by auto + have left_I: "left I = 0" + using True by auto + have "\t \ fst ` set (linearize data_in'). t \ nt \ nt - t \ left I" + using valid_before True by (auto simp add: lin_data_in') + moreover have "\as. Mapping.lookup tuple_in' as = safe_max (fst ` + {tas \ ts_tuple_rel (set (linearize data_in')). + valid_tuple tuple_since' tas \ as = snd tas})" + proof - + fix as + show "Mapping.lookup tuple_in' as = safe_max (fst ` + {tas \ ts_tuple_rel (set (linearize data_in')). + valid_tuple tuple_since' tas \ as = snd tas})" + proof (cases "as \ X") + case True + have "valid_tuple tuple_since' (nt, as)" + using True valid_before by (auto simp add: valid_tuple_def tuple_since'_def + Mapping_lookup_upd_set dest: Mapping_keys_dest split: option.splits) + moreover have "(nt, as) \ ts_tuple_rel (insert (nt, X) (set (linearize data_in)))" + using True by (auto simp add: ts_tuple_rel_def) + ultimately have nt_in: "nt \ fst ` {tas \ ts_tuple_rel (insert (nt, X) + (set (linearize data_in))). valid_tuple tuple_since' tas \ as = snd tas}" + proof - + assume a1: "valid_tuple tuple_since' (nt, as)" + assume "(nt, as) \ ts_tuple_rel (insert (nt, X) (set (linearize data_in)))" + then have "\p. nt = fst p \ p \ ts_tuple_rel (insert (nt, X) + (set (linearize data_in))) \ valid_tuple tuple_since' p \ as = snd p" + using a1 by simp + then show "nt \ fst ` {p \ ts_tuple_rel (insert (nt, X) (set (linearize data_in))). + valid_tuple tuple_since' p \ as = snd p}" + by blast + qed + moreover have "\t. t \ fst ` {tas \ ts_tuple_rel (insert (nt, X) + (set (linearize data_in))). valid_tuple tuple_since' tas \ as = snd tas} \ t \ nt" + using valid_before by (auto split: option.splits) + (metis (no_types, lifting) eq_imp_le fst_conv insertE ts_tuple_rel_dest) + ultimately have "Max (fst ` {tas \ ts_tuple_rel (set (linearize data_in) + \ set [(nt, X)]). valid_tuple tuple_since' tas \ as = snd tas}) = nt" + using Max_eqI[OF finite_fst_ts_tuple_rel[of "linearize data_in'"], + unfolded lin_data_in' set_append] by auto + then show ?thesis + using nt_in True + by (auto simp add: tuple_in'_def Mapping_lookup_upd_set safe_max_def lin_data_in') + next + case False + have "{tas \ ts_tuple_rel (set (linearize data_in)). + valid_tuple tuple_since tas \ as = snd tas} = + {tas \ ts_tuple_rel (set (linearize data_in')). + valid_tuple tuple_since' tas \ as = snd tas}" + using False by (fastforce simp add: lin_data_in' ts_tuple_rel_def valid_tuple_def + tuple_since'_def Mapping_lookup_upd_set intro: Mapping_keys_intro + split: option.splits if_splits) + then show ?thesis + using valid_before False by (auto simp add: tuple_in'_def Mapping_lookup_upd_set) + qed + qed + ultimately show ?thesis + using assms table_auxlist' sorted_append[of "map fst (linearize data_in)"] + lookup_tuple_since' ts_tuple_rel_auxlist' table_in' table_since' + unfolding add_def auxlist'_def[symmetric] cur_nt I_def + by (auto simp only: valid_mmsaux.simps lin_data_in' n_def R_def) auto + next + case False + then have add_def: "add_new_table_mmsaux args X (nt, gc, maskL, maskR, data_prev, data_in, + tuple_in, tuple_since) = (nt, gc, maskL, maskR, data_prev', data_in, + tuple_in, tuple_since')" + using data_prev'_def tuple_since'_def unfolding I_def by auto + have left_I: "left I > 0" + using False by auto + have "\t \ fst ` set (linearize data_prev'). t \ nt \ nt - t < left I" + using valid_before False by (auto simp add: lin_data_prev' I_def) + moreover have "\as. {tas \ ts_tuple_rel (set (linearize data_in)). + valid_tuple tuple_since tas \ as = snd tas} = + {tas \ ts_tuple_rel (set (linearize data_in)). + valid_tuple tuple_since' tas \ as = snd tas}" + proof (rule set_eqI, rule iffI) + fix as tas + assume assm: "tas \ {tas \ ts_tuple_rel (set (linearize data_in)). + valid_tuple tuple_since' tas \ as = snd tas}" + then obtain t Z where Z_def: "tas = (t, as)" "as \ Z" "(t, Z) \ set (linearize data_in)" + "valid_tuple tuple_since' (t, as)" + by (auto simp add: ts_tuple_rel_def) + show "tas \ {tas \ ts_tuple_rel (set (linearize data_in)). + valid_tuple tuple_since tas \ as = snd tas}" + using assm + proof (cases "as \ Mapping.keys tuple_since") + case False + then have "t \ nt" + using Z_def(4) by (auto simp add: valid_tuple_def tuple_since'_def + Mapping_lookup_upd_set intro: Mapping_keys_intro split: option.splits if_splits) + then show ?thesis + using Z_def(3) valid_before left_I unfolding I_def by auto + qed (auto simp add: valid_tuple_def tuple_since'_def Mapping_lookup_upd_set + dest: Mapping_keys_dest split: option.splits) + qed (auto simp add: Mapping_lookup_upd_set valid_tuple_def tuple_since'_def + intro: Mapping_keys_intro split: option.splits) + ultimately show ?thesis + using assms table_auxlist' sorted_append[of "map fst (linearize data_prev)"] + False lookup_tuple_since' ts_tuple_rel_auxlist' table_in' table_since' wf_data_prev' + valid_before + unfolding add_def auxlist'_def[symmetric] cur_nt I_def + by (auto simp only: valid_mmsaux.simps lin_data_prev' n_def R_def) fastforce+ + (* takes long *) + qed +qed + +lemma valid_add_new_table_mmsaux: + assumes valid_before: "valid_mmsaux args cur aux auxlist" + and table_X: "table (args_n args) (args_R args) X" + shows "valid_mmsaux args cur (add_new_table_mmsaux args X aux) + (case auxlist of + [] => [(cur, X)] + | ((t, y) # ts) \ if t = cur then (t, y \ X) # ts else (cur, X) # auxlist)" + using valid_add_new_table_mmsaux_unfolded assms + by (cases aux) fast + +lemma foldr_ts_tuple_rel: + "as \ foldr (\) (concat (map (\(t, rel). if P t then [rel] else []) auxlist)) {} \ + (\t. (t, as) \ ts_tuple_rel (set auxlist) \ P t)" +proof (rule iffI) + assume assm: "as \ foldr (\) (concat (map (\(t, rel). if P t then [rel] else []) auxlist)) {}" + then obtain t X where tX_def: "P t" "as \ X" "(t, X) \ set auxlist" + by (auto elim!: in_foldr_UnE) + then show "\t. (t, as) \ ts_tuple_rel (set auxlist) \ P t" + by (auto simp add: ts_tuple_rel_def) +next + assume assm: "\t. (t, as) \ ts_tuple_rel (set auxlist) \ P t" + then obtain t X where tX_def: "P t" "as \ X" "(t, X) \ set auxlist" + by (auto simp add: ts_tuple_rel_def) + show "as \ foldr (\) (concat (map (\(t, rel). if P t then [rel] else []) auxlist)) {}" + using in_foldr_UnI[OF tX_def(2)] tX_def assm by (induction auxlist) force+ +qed + +lemma image_snd: "(a, b) \ X \ b \ snd ` X" + by force + +fun result_mmsaux :: "args \ 'a mmsaux \ 'a table" where + "result_mmsaux args (nt, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since) = + Mapping.keys tuple_in" + +lemma valid_result_mmsaux_unfolded: + assumes "valid_mmsaux args cur + (t, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since) auxlist" + shows "result_mmsaux args (t, gc, maskL, maskR, data_prev, data_in, tuple_in, tuple_since) = + foldr (\) [rel. (t, rel) \ auxlist, left (args_ivl args) \ cur - t] {}" + using valid_mmsaux_tuple_in_keys[OF assms] assms + by (auto simp add: image_Un ts_tuple_rel_Un foldr_ts_tuple_rel image_snd) + (fastforce intro: ts_tuple_rel_intro dest: ts_tuple_rel_dest)+ + +lemma valid_result_mmsaux: "valid_mmsaux args cur aux auxlist \ + result_mmsaux args aux = foldr (\) [rel. (t, rel) \ auxlist, left (args_ivl args) \ cur - t] {}" + using valid_result_mmsaux_unfolded by (cases aux) fast + +interpretation default_msaux: msaux valid_mmsaux init_mmsaux add_new_ts_mmsaux gc_join_mmsaux + add_new_table_mmsaux result_mmsaux + using valid_init_mmsaux valid_add_new_ts_mmsaux valid_gc_join_mmsaux valid_add_new_table_mmsaux + valid_result_mmsaux + by unfold_locales assumption+ + +subsection \Optimized data structure for Until\ + +type_synonym tp = nat + +type_synonym 'a mmuaux = "tp \ ts queue \ nat \ bool list \ bool list \ + ('a tuple, tp) mapping \ (tp, ('a tuple, ts + tp) mapping) mapping \ 'a table list \ nat" + +definition tstp_lt :: "ts + tp \ ts \ tp \ bool" where + "tstp_lt tstp ts tp = case_sum (\ts'. ts' \ ts) (\tp'. tp' < tp) tstp" + +definition tstp_le :: "ts + tp \ ts \ tp \ bool" where + "tstp_le tstp ts tp = case_sum (\ts'. ts' \ ts) (\tp'. tp' \ tp) tstp" + +definition ts_tp_lt :: "ts \ tp \ ts + tp \ bool" where + "ts_tp_lt ts tp tstp = case_sum (\ts'. ts \ ts') (\tp'. tp < tp') tstp" + +definition ts_tp_lt' :: "ts \ tp \ ts + tp \ bool" where + "ts_tp_lt' ts tp tstp = case_sum (\ts'. ts < ts') (\tp'. tp \ tp') tstp" + +definition ts_tp_le :: "ts \ tp \ ts + tp \ bool" where + "ts_tp_le ts tp tstp = case_sum (\ts'. ts \ ts') (\tp'. tp \ tp') tstp" + +fun max_tstp :: "ts + tp \ ts + tp \ ts + tp" where + "max_tstp (Inl ts) (Inl ts') = Inl (max ts ts')" +| "max_tstp (Inr tp) (Inr tp') = Inr (max tp tp')" +| "max_tstp (Inl ts) _ = Inl ts" +| "max_tstp _ (Inl ts) = Inl ts" + +lemma max_tstp_idem: "max_tstp (max_tstp x y) y = max_tstp x y" + by (cases x; cases y) auto + +lemma max_tstp_idem': "max_tstp x (max_tstp x y) = max_tstp x y" + by (cases x; cases y) auto + +lemma max_tstp_d_d: "max_tstp d d = d" + by (cases d) auto + +lemma max_cases: "(max a b = a \ P) \ (max a b = b \ P) \ P" + by (metis max_def) + +lemma max_tstpE: "isl tstp \ isl tstp' \ (max_tstp tstp tstp' = tstp \ P) \ + (max_tstp tstp tstp' = tstp' \ P) \ P" + by (cases tstp; cases tstp') (auto elim: max_cases) + +lemma max_tstp_intro: "tstp_lt tstp ts tp \ tstp_lt tstp' ts tp \ isl tstp \ isl tstp' \ + tstp_lt (max_tstp tstp tstp') ts tp" + by (auto simp add: tstp_lt_def split: sum.splits) + +lemma max_tstp_intro': "isl tstp \ isl tstp' \ + ts_tp_le ts' tp' tstp \ ts_tp_le ts' tp' (max_tstp tstp tstp')" + by (cases tstp; cases tstp') (auto simp add: ts_tp_le_def tstp_le_def split: sum.splits) + +lemma max_tstp_intro'': "isl tstp \ isl tstp' \ + ts_tp_le ts' tp' tstp' \ ts_tp_le ts' tp' (max_tstp tstp tstp')" + by (cases tstp; cases tstp') (auto simp add: ts_tp_le_def tstp_le_def split: sum.splits) + +lemma max_tstp_intro''': "isl tstp \ isl tstp' \ + ts_tp_lt' ts' tp' tstp \ ts_tp_lt' ts' tp' (max_tstp tstp tstp')" + by (cases tstp; cases tstp') (auto simp add: ts_tp_lt'_def tstp_le_def split: sum.splits) + +lemma max_tstp_intro'''': "isl tstp \ isl tstp' \ + ts_tp_lt' ts' tp' tstp' \ ts_tp_lt' ts' tp' (max_tstp tstp tstp')" + by (cases tstp; cases tstp') (auto simp add: ts_tp_lt'_def tstp_le_def split: sum.splits) + +lemma max_tstp_isl: "isl tstp \ isl tstp' \ isl (max_tstp tstp tstp') \ isl tstp" + by (cases tstp; cases tstp') auto + +definition filter_a1_map :: "bool \ tp \ ('a tuple, tp) mapping \ 'a table" where + "filter_a1_map pos tp a1_map = + {xs \ Mapping.keys a1_map. case Mapping.lookup a1_map xs of Some tp' \ + (pos \ tp' \ tp) \ (\pos \ tp \ tp')}" + +definition filter_a2_map :: "\ \ ts \ tp \ (tp, ('a tuple, ts + tp) mapping) mapping \ + 'a table" where + "filter_a2_map I ts tp a2_map = {xs. \tp' \ tp. (case Mapping.lookup a2_map tp' of Some m \ + (case Mapping.lookup m xs of Some tstp \ ts_tp_lt' ts tp tstp | _ \ False) + | _ \ False)}" + +fun triple_eq_pair :: "('a \ 'b \ 'c) \ ('a \ 'd) \ ('d \ 'b) \ ('a \ 'd \ 'c) \ bool" where + "triple_eq_pair (t, a1, a2) (ts', tp') f g \ t = ts' \ a1 = f tp' \ a2 = g ts' tp'" + +fun valid_mmuaux' :: "args \ ts \ ts \ 'a mmuaux \ 'a muaux \ bool" where + "valid_mmuaux' args cur dt (tp, tss, len, maskL, maskR, a1_map, a2_map, + done, done_length) auxlist \ + args_L args \ args_R args \ + maskL = join_mask (args_n args) (args_L args) \ + maskR = join_mask (args_n args) (args_R args) \ + len \ tp \ + length (linearize tss) = len \ sorted (linearize tss) \ + (\t \ set (linearize tss). t \ cur \ enat cur \ enat t + right (args_ivl args)) \ + table (args_n args) (args_L args) (Mapping.keys a1_map) \ + Mapping.keys a2_map = {tp - len..tp} \ + (\xs \ Mapping.keys a1_map. case Mapping.lookup a1_map xs of Some tp' \ tp' < tp) \ + (\tp' \ Mapping.keys a2_map. case Mapping.lookup a2_map tp' of Some m \ + table (args_n args) (args_R args) (Mapping.keys m) \ + (\xs \ Mapping.keys m. case Mapping.lookup m xs of Some tstp \ + tstp_lt tstp (cur - (left (args_ivl args) - 1)) tp \ (isl tstp \ left (args_ivl args) > 0))) \ + length done = done_length \ length done + len = length auxlist \ + rev done = map proj_thd (take (length done) auxlist) \ + (\x \ set (take (length done) auxlist). check_before (args_ivl args) dt x) \ + sorted (map fst auxlist) \ + list_all2 (\x y. triple_eq_pair x y (\tp'. filter_a1_map (args_pos args) tp' a1_map) + (\ts' tp'. filter_a2_map (args_ivl args) ts' tp' a2_map)) (drop (length done) auxlist) + (zip (linearize tss) [tp - len.. ts \ 'a mmuaux \ 'a muaux \ + bool" where + "valid_mmuaux args cur = valid_mmuaux' args cur cur" + +fun eval_step_mmuaux :: "'a mmuaux \ 'a mmuaux" where + "eval_step_mmuaux (tp, tss, len, maskL, maskR, a1_map, a2_map, + done, done_length) = (case safe_hd tss of (Some ts, tss') \ + (case Mapping.lookup a2_map (tp - len) of Some m \ + let m = Mapping.filter (\_ tstp. ts_tp_lt' ts (tp - len) tstp) m; + T = Mapping.keys m; + a2_map = Mapping.update (tp - len + 1) + (case Mapping.lookup a2_map (tp - len + 1) of Some m' \ + Mapping.combine (\tstp tstp'. max_tstp tstp tstp') m m') a2_map; + a2_map = Mapping.delete (tp - len) a2_map in + (tp, tl_queue tss', len - 1, maskL, maskR, a1_map, a2_map, + T # done, done_length + 1)))" + +lemma Mapping_update_keys: "Mapping.keys (Mapping.update a b m) = Mapping.keys m \ {a}" + by transfer auto + +lemma drop_is_Cons_take: "drop n xs = y # ys \ take (Suc n) xs = take n xs @ [y]" +proof (induction xs arbitrary: n) + case Nil + then show ?case by simp +next + case (Cons x xs) + then show ?case by (cases n) simp_all +qed + +lemma list_all2_weaken: "list_all2 f xs ys \ + (\x y. (x, y) \ set (zip xs ys) \ f x y \ f' x y) \ list_all2 f' xs ys" + by (induction xs ys rule: list_all2_induct) auto + +lemma Mapping_lookup_delete: "Mapping.lookup (Mapping.delete k m) k' = + (if k = k' then None else Mapping.lookup m k')" + by transfer auto + +lemma Mapping_lookup_update: "Mapping.lookup (Mapping.update k v m) k' = + (if k = k' then Some v else Mapping.lookup m k')" + by transfer auto + +lemma hd_le_set: "sorted xs \ xs \ [] \ x \ set xs \ hd xs \ x" + by (metis eq_iff list.sel(1) set_ConsD sorted.elims(2)) + +lemma Mapping_lookup_combineE: "Mapping.lookup (Mapping.combine f m m') k = Some v \ + (Mapping.lookup m k = Some v \ P) \ + (Mapping.lookup m' k = Some v \ P) \ + (\v' v''. Mapping.lookup m k = Some v' \ Mapping.lookup m' k = Some v'' \ + f v' v'' = v \ P) \ P" + unfolding Mapping.lookup_combine + by (auto simp add: combine_options_def split: option.splits) + +lemma Mapping_keys_filterI: "Mapping.lookup m k = Some v \ f k v \ + k \ Mapping.keys (Mapping.filter f m)" + by transfer (auto split: option.splits if_splits) + +lemma Mapping_keys_filterD: "k \ Mapping.keys (Mapping.filter f m) \ + \v. Mapping.lookup m k = Some v \ f k v" + by transfer (auto split: option.splits if_splits) + +fun lin_ts_mmuaux :: "'a mmuaux \ ts list" where + "lin_ts_mmuaux (tp, tss, len, maskL, maskR, a1_map, a2_map, done, done_length) = + linearize tss" + +lemma valid_eval_step_mmuaux': + assumes "valid_mmuaux' args cur dt aux auxlist" + "lin_ts_mmuaux aux = ts # tss''" "enat ts + right (args_ivl args) < dt" + shows "valid_mmuaux' args cur dt (eval_step_mmuaux aux) auxlist \ + lin_ts_mmuaux (eval_step_mmuaux aux) = tss''" +proof - + define I where "I = args_ivl args" + define n where "n = args_n args" + define L where "L = args_L args" + define R where "R = args_R args" + define pos where "pos = args_pos args" + obtain tp len tss maskL maskR a1_map a2_map "done" done_length where aux_def: + "aux = (tp, tss, len, maskL, maskR, a1_map, a2_map, done, done_length)" + by (cases aux) auto + then obtain tss' where safe_hd_eq: "safe_hd tss = (Some ts, tss')" + using assms(2) safe_hd_rep case_optionE + by (cases "safe_hd tss") fastforce + note valid_before = assms(1)[unfolded aux_def] + have lin_tss_not_Nil: "linearize tss \ []" + using safe_hd_rep[OF safe_hd_eq] by auto + have ts_hd: "ts = hd (linearize tss)" + using safe_hd_rep[OF safe_hd_eq] by auto + have lin_tss': "linearize tss' = linearize tss" + using safe_hd_rep[OF safe_hd_eq] by auto + have tss'_not_empty: "\is_empty tss'" + using is_empty_alt[of tss'] lin_tss_not_Nil unfolding lin_tss' by auto + have len_pos: "len > 0" + using lin_tss_not_Nil valid_before by auto + have a2_map_keys: "Mapping.keys a2_map = {tp - len..tp}" + using valid_before by auto + have len_tp: "len \ tp" + using valid_before by auto + have tp_minus_keys: "tp - len \ Mapping.keys a2_map" + using a2_map_keys by auto + have tp_minus_keys': "tp - len + 1 \ Mapping.keys a2_map" + using a2_map_keys len_pos len_tp by auto + obtain m where m_def: "Mapping.lookup a2_map (tp - len) = Some m" + using tp_minus_keys by (auto dest: Mapping_keys_dest) + have "table n R (Mapping.keys m)" + "(\xs \ Mapping.keys m. case Mapping.lookup m xs of Some tstp \ + tstp_lt tstp (cur - (left I - 1)) tp \ (isl tstp \ left I > 0))" + using tp_minus_keys m_def valid_before + unfolding valid_mmuaux'.simps n_def I_def R_def by fastforce+ + then have m_inst: "table n R (Mapping.keys m)" + "\xs tstp. Mapping.lookup m xs = Some tstp \ + tstp_lt tstp (cur - (left I - 1)) tp \ (isl tstp \ left I > 0)" + using Mapping_keys_intro by fastforce+ + have m_inst_isl: "\xs tstp. Mapping.lookup m xs = Some tstp \ isl tstp \ left I > 0" + using m_inst(2) by fastforce + obtain m' where m'_def: "Mapping.lookup a2_map (tp - len + 1) = Some m'" + using tp_minus_keys' by (auto dest: Mapping_keys_dest) + have "table n R (Mapping.keys m')" + "(\xs \ Mapping.keys m'. case Mapping.lookup m' xs of Some tstp \ + tstp_lt tstp (cur - (left I - 1)) tp \ (isl tstp \ left I > 0))" + using tp_minus_keys' m'_def valid_before + unfolding valid_mmuaux'.simps I_def n_def R_def by fastforce+ + then have m'_inst: "table n R (Mapping.keys m')" + "\xs tstp. Mapping.lookup m' xs = Some tstp \ + tstp_lt tstp (cur - (left I - 1)) tp \ (isl tstp \ left I > 0)" + using Mapping_keys_intro by fastforce+ + have m'_inst_isl: "\xs tstp. Mapping.lookup m' xs = Some tstp \ isl tstp \ left I > 0" + using m'_inst(2) by fastforce + define m_upd where "m_upd = Mapping.filter (\_ tstp. ts_tp_lt' ts (tp - len) tstp) m" + define T where "T = Mapping.keys m_upd" + define mc where "mc = Mapping.combine (\tstp tstp'. max_tstp tstp tstp') m_upd m'" + define a2_map' where "a2_map' = Mapping.update (tp - len + 1) mc a2_map" + define a2_map'' where "a2_map'' = Mapping.delete (tp - len) a2_map'" + have m_upd_lookup: "\xs tstp. Mapping.lookup m_upd xs = Some tstp \ + tstp_lt tstp (cur - (left I - 1)) tp \ (isl tstp \ left I > 0)" + unfolding m_upd_def Mapping.lookup_filter + using m_inst(2) by (auto split: option.splits if_splits) + have mc_lookup: "\xs tstp. Mapping.lookup mc xs = Some tstp \ + tstp_lt tstp (cur - (left I - 1)) tp \ (isl tstp \ left I > 0)" + unfolding mc_def Mapping.lookup_combine + using m_upd_lookup m'_inst(2) + by (auto simp add: combine_options_def max_tstp_isl intro: max_tstp_intro split: option.splits) + have mc_keys: "Mapping.keys mc \ Mapping.keys m \ Mapping.keys m'" + unfolding mc_def Mapping.keys_combine m_upd_def + using Mapping.keys_filter by fastforce + have tp_len_assoc: "tp - len + 1 = tp - (len - 1)" + using len_pos len_tp by auto + have a2_map''_keys: "Mapping.keys a2_map'' = {tp - (len - 1)..tp}" + unfolding a2_map''_def a2_map'_def Mapping.keys_delete Mapping_update_keys a2_map_keys + using tp_len_assoc by auto + have lin_tss_Cons: "linearize tss = ts # linearize (tl_queue tss')" + using lin_tss_not_Nil + by (auto simp add: tl_queue_rep[OF tss'_not_empty] lin_tss' ts_hd) + have tp_len_tp_unfold: "[tp - len..x. x \ {tp - (len - 1) + 1..tp} \ + Mapping.lookup a2_map'' x = Mapping.lookup a2_map x" + unfolding a2_map''_def a2_map'_def Mapping_lookup_delete Mapping_lookup_update tp_len_assoc + using len_tp by auto + have list_all2: "list_all2 (\x y. triple_eq_pair x y (\tp'. filter_a1_map pos tp' a1_map) + (\ts' tp'. filter_a2_map I ts' tp' a2_map)) + (drop (length done) auxlist) (zip (linearize tss) [tp - len.. (t, a1, a2) = + (ts, filter_a1_map pos (tp - len) a1_map, filter_a2_map I ts (tp - len) a2_map)" + and list_all2': "list_all2 (\x y. triple_eq_pair x y (\tp'. filter_a1_map pos tp' a1_map) + (\ts' tp'. filter_a2_map I ts' tp' a2_map)) tl_aux + (zip (linearize (tl_queue tss')) [tp - (len - 1)..ts' tp'. ts' \ set (linearize tss) \ + tp' \ {tp - (len - 1).. filter_a2_map I ts' tp' a2_map = + filter_a2_map I ts' tp' a2_map''" + proof (rule set_eqI, rule iffI) + fix ts' tp' xs + assume assms: "ts' \ set (linearize tss)" + "tp' \ {tp - (len - 1).. filter_a2_map I ts' tp' a2_map" + obtain tp_bef m_bef tstp where defs: "tp_bef \ tp'" "Mapping.lookup a2_map tp_bef = Some m_bef" + "Mapping.lookup m_bef xs = Some tstp" "ts_tp_lt' ts' tp' tstp" + using assms(3)[unfolded filter_a2_map_def] + by (fastforce split: option.splits) + have ts_le_ts': "ts \ ts'" + using hd_le_set[OF _ lin_tss_not_Nil assms(1)] valid_before + unfolding ts_hd by auto + have tp_bef_in: "tp_bef \ {tp - len..tp}" + using defs(2) valid_before by (auto intro!: Mapping_keys_intro) + have tp_minus_le: "tp - (len - 1) \ tp'" + using assms(2) by auto + show "xs \ filter_a2_map I ts' tp' a2_map''" + proof (cases "tp_bef \ tp - (len - 1)") + case True + show ?thesis + proof (cases "tp_bef = tp - len") + case True + have m_bef_m: "m_bef = m" + using defs(2) m_def + unfolding True by auto + have "Mapping.lookup m_upd xs = Some tstp" + using defs(3,4) assms(2) ts_le_ts' unfolding m_bef_m m_upd_def + by (auto simp add: Mapping.lookup_filter ts_tp_lt'_def intro: Mapping_keys_intro + split: sum.splits) + then have "case Mapping.lookup mc xs of None \ False | Some tstp \ + ts_tp_lt' ts' tp' tstp" + unfolding mc_def Mapping.lookup_combine + using m'_inst(2) m_upd_lookup + by (auto simp add: combine_options_def defs(4) intro!: max_tstp_intro''' + dest: Mapping_keys_dest split: option.splits) + then show ?thesis + using lookup''_tp_minus tp_minus_le defs + unfolding m_bef_m filter_a2_map_def by (auto split: option.splits) + next + case False + then have "tp_bef = tp - (len - 1)" + using True tp_bef_in by auto + then have m_bef_m: "m_bef = m'" + using defs(2) m'_def + unfolding tp_len_assoc by auto + have "case Mapping.lookup mc xs of None \ False | Some tstp \ + ts_tp_lt' ts' tp' tstp" + unfolding mc_def Mapping.lookup_combine + using m'_inst(2) m_upd_lookup defs(3)[unfolded m_bef_m] + by (auto simp add: combine_options_def defs(4) intro!: max_tstp_intro'''' + dest: Mapping_keys_dest split: option.splits) + then show ?thesis + using lookup''_tp_minus tp_minus_le defs + unfolding m_bef_m filter_a2_map_def by (auto split: option.splits) + qed + next + case False + then have "Mapping.lookup a2_map'' tp_bef = Mapping.lookup a2_map tp_bef" + using id tp_bef_in len_tp by auto + then show ?thesis + unfolding filter_a2_map_def + using defs by auto + qed + next + fix ts' tp' xs + assume assms: "ts' \ set (linearize tss)" "tp' \ {tp - (len - 1).. filter_a2_map I ts' tp' a2_map''" + obtain tp_bef m_bef tstp where defs: "tp_bef \ tp'" + "Mapping.lookup a2_map'' tp_bef = Some m_bef" + "Mapping.lookup m_bef xs = Some tstp" "ts_tp_lt' ts' tp' tstp" + using assms(3)[unfolded filter_a2_map_def] + by (fastforce split: option.splits) + have ts_le_ts': "ts \ ts'" + using hd_le_set[OF _ lin_tss_not_Nil assms(1)] valid_before + unfolding ts_hd by auto + have tp_bef_in: "tp_bef \ {tp - (len - 1)..tp}" + using defs(2) a2_map''_keys by (auto intro!: Mapping_keys_intro) + have tp_minus_le: "tp - len \ tp'" "tp - (len - 1) \ tp'" + using assms(2) by auto + show "xs \ filter_a2_map I ts' tp' a2_map" + proof (cases "tp_bef = tp - (len - 1)") + case True + have m_beg_mc: "m_bef = mc" + using defs(2) + unfolding True a2_map''_def a2_map'_def tp_len_assoc Mapping_lookup_delete + Mapping.lookup_update + by (auto split: if_splits) + show ?thesis + using defs(3)[unfolded m_beg_mc mc_def] + proof (rule Mapping_lookup_combineE) + assume lassm: "Mapping.lookup m_upd xs = Some tstp" + then show "xs \ filter_a2_map I ts' tp' a2_map" + unfolding m_upd_def Mapping.lookup_filter + using m_def tp_minus_le(1) defs + by (auto simp add: filter_a2_map_def split: option.splits if_splits) + next + assume lassm: "Mapping.lookup m' xs = Some tstp" + then show "xs \ filter_a2_map I ts' tp' a2_map" + using m'_def defs(4) tp_minus_le defs + unfolding filter_a2_map_def tp_len_assoc + by auto + next + fix v' v'' + assume lassms: "Mapping.lookup m_upd xs = Some v'" "Mapping.lookup m' xs = Some v''" + "max_tstp v' v'' = tstp" + show "xs \ filter_a2_map I ts' tp' a2_map" + proof (rule max_tstpE) + show "isl v' = isl v''" + using lassms(1,2) m_upd_lookup m'_inst(2) + by auto + next + assume "max_tstp v' v'' = v'" + then show "xs \ filter_a2_map I ts' tp' a2_map" + using lassms(1,3) m_def defs tp_minus_le(1) + unfolding tp_len_assoc m_upd_def Mapping.lookup_filter + by (auto simp add: filter_a2_map_def split: option.splits if_splits) + next + assume "max_tstp v' v'' = v''" + then show "xs \ filter_a2_map I ts' tp' a2_map" + using lassms(2,3) m'_def defs tp_minus_le(2) + unfolding tp_len_assoc + by (auto simp add: filter_a2_map_def) + qed + qed + next + case False + then have "Mapping.lookup a2_map'' tp_bef = Mapping.lookup a2_map tp_bef" + using id tp_bef_in by auto + then show ?thesis + unfolding filter_a2_map_def + using defs by auto (metis option.simps(5)) + qed + qed + have set_tl_tss': "set (linearize (tl_queue tss')) \ set (linearize tss)" + unfolding tl_queue_rep[OF tss'_not_empty] lin_tss_Cons by auto + have list_all2'': "list_all2 (\x y. triple_eq_pair x y (\tp'. filter_a1_map pos tp' a1_map) + (\ts' tp'. filter_a2_map I ts' tp' a2_map'')) tl_aux + (zip (linearize (tl_queue tss')) [tp - (len - 1)..tp' \ Mapping.keys a2_map''. case Mapping.lookup a2_map'' tp' of Some m \ + table n R (Mapping.keys m) \ (\xs \ Mapping.keys m. case Mapping.lookup m xs of Some tstp \ + tstp_lt tstp (cur - (left I - 1)) tp \ isl tstp = (0 < left I))" + proof (rule ballI) + fix tp' + assume assm: "tp' \ Mapping.keys a2_map''" + then obtain f where f_def: "Mapping.lookup a2_map'' tp' = Some f" + by (auto dest: Mapping_keys_dest) + have tp'_in: "tp' \ {tp - (len - 1)..tp}" + using assm unfolding a2_map''_keys . + then have tp'_in_keys: "tp' \ Mapping.keys a2_map" + using valid_before by auto + have "table n R (Mapping.keys f) \ + (\xs \ Mapping.keys f. case Mapping.lookup f xs of Some tstp \ + tstp_lt tstp (cur - (left I - 1)) tp \ isl tstp = (0 < left I))" + proof (cases "tp' = tp - (len - 1)") + case True + then have f_mc: "f = mc" + using f_def + unfolding a2_map''_def a2_map'_def Mapping_lookup_delete Mapping_lookup_update tp_len_assoc + by (auto split: if_splits) + have "table n R (Mapping.keys f)" + unfolding f_mc + using mc_keys m_def m'_def m_inst m'_inst + by (auto simp add: table_def) + moreover have "\xs \ Mapping.keys f. case Mapping.lookup f xs of Some tstp \ + tstp_lt tstp (cur - (left I - 1)) tp \ isl tstp = (0 < left I)" + using assm Mapping.keys_filter m_inst(2) m_inst_isl m'_inst(2) m'_inst_isl max_tstp_isl + unfolding f_mc mc_def Mapping.lookup_combine + by (auto simp add: combine_options_def m_upd_def Mapping.lookup_filter + intro!: max_tstp_intro Mapping_keys_intro dest!: Mapping_keys_dest + split: option.splits) + ultimately show ?thesis + by auto + next + case False + have "Mapping.lookup a2_map tp' = Some f" + using tp'_in id[of tp'] f_def False by auto + then show ?thesis + using tp'_in_keys valid_before + unfolding valid_mmuaux'.simps I_def n_def R_def by fastforce + qed + then show "case Mapping.lookup a2_map'' tp' of Some m \ + table n R (Mapping.keys m) \ (\xs \ Mapping.keys m. case Mapping.lookup m xs of Some tstp \ + tstp_lt tstp (cur - (left I - 1)) tp \ isl tstp = (0 < left I))" + using f_def by auto + qed + have tl_aux_def: "tl_aux = drop (length done + 1) auxlist" + using aux_split(1) by (metis Suc_eq_plus1 add_Suc drop0 drop_Suc_Cons drop_drop) + have T_eq: "T = filter_a2_map I ts (tp - len) a2_map" + proof (rule set_eqI, rule iffI) + fix xs + assume "xs \ filter_a2_map I ts (tp - len) a2_map" + then obtain tp_bef m_bef tstp where defs: "tp_bef \ tp - len" + "Mapping.lookup a2_map tp_bef = Some m_bef" + "Mapping.lookup m_bef xs = Some tstp" "ts_tp_lt' ts (tp - len) tstp" + by (fastforce simp add: filter_a2_map_def split: option.splits) + then have tp_bef_minus: "tp_bef = tp - len" + using valid_before Mapping_keys_intro by force + have m_bef_m: "m_bef = m" + using defs(2) m_def + unfolding tp_bef_minus by auto + show "xs \ T" + using defs + unfolding T_def m_upd_def m_bef_m + by (auto intro: Mapping_keys_filterI Mapping_keys_intro) + next + fix xs + assume "xs \ T" + then show "xs \ filter_a2_map I ts (tp - len) a2_map" + using m_def Mapping.keys_filter + unfolding T_def m_upd_def filter_a2_map_def + by (auto simp add: filter_a2_map_def dest!: Mapping_keys_filterD split: if_splits) + qed + have min_auxlist_done: "min (length auxlist) (length done) = length done" + using valid_before by auto + then have "\x \ set (take (length done) auxlist). check_before I dt x" + "rev done = map proj_thd (take (length done) auxlist)" + using valid_before unfolding I_def by auto + then have list_all': "(\x \ set (take (length (T # done)) auxlist). check_before I dt x)" + "rev (T # done) = map proj_thd (take (length (T # done)) auxlist)" + using drop_is_Cons_take[OF aux_split(1)] aux_split(2) assms(3) + by (auto simp add: T_eq I_def) + have eval_step_mmuaux_eq: "eval_step_mmuaux (tp, tss, len, maskL, maskR, a1_map, a2_map, + done, done_length) = (tp, tl_queue tss', len - 1, maskL, maskR, a1_map, a2_map'', + T # done, done_length + 1)" + using safe_hd_eq m_def m'_def m_upd_def T_def mc_def a2_map'_def a2_map''_def + by (auto simp add: Let_def) + have "lin_ts_mmuaux (eval_step_mmuaux aux) = tss''" + using lin_tss_Cons assms(2) unfolding aux_def eval_step_mmuaux_eq by auto + then show ?thesis + using valid_before a2_map''_keys sorted_tl list_all' lookup'' list_all2'' + unfolding eval_step_mmuaux_eq valid_mmuaux'.simps tl_aux_def aux_def I_def n_def R_def pos_def + using lin_tss_not_Nil safe_hd_eq len_pos + by (auto simp add: list.set_sel(2) lin_tss' tl_queue_rep[OF tss'_not_empty] min_auxlist_done) +qed + +lemma done_empty_valid_mmuaux'_intro: + assumes "valid_mmuaux' args cur dt + (tp, tss, len, maskL, maskR, a1_map, a2_map, done, done_length) auxlist" + shows "valid_mmuaux' args cur dt' + (tp, tss, len, maskL, maskR, a1_map, a2_map, [], 0) + (drop (length done) auxlist)" + using assms sorted_drop by (auto simp add: drop_map[symmetric]) + +lemma valid_mmuaux'_mono: + assumes "valid_mmuaux' args cur dt aux auxlist" "dt \ dt'" + shows "valid_mmuaux' args cur dt' aux auxlist" + using assms less_le_trans by (cases aux) fastforce + +lemma valid_foldl_eval_step_mmuaux': + assumes valid_before: "valid_mmuaux' args cur dt aux auxlist" + "lin_ts_mmuaux aux = tss @ tss'" + "\ts. ts \ set (take (length tss) (lin_ts_mmuaux aux)) \ enat ts + right (args_ivl args) < dt" + shows "valid_mmuaux' args cur dt (foldl (\aux _. eval_step_mmuaux aux) aux tss) auxlist \ + lin_ts_mmuaux (foldl (\aux _. eval_step_mmuaux aux) aux tss) = tss'" + using assms +proof (induction tss arbitrary: aux) + case (Cons ts tss) + have app_ass: "lin_ts_mmuaux aux = ts # (tss @ tss')" + using Cons(3) by auto + have "enat ts + right (args_ivl args) < dt" + using Cons by auto + then have valid_step: "valid_mmuaux' args cur dt (eval_step_mmuaux aux) auxlist" + "lin_ts_mmuaux (eval_step_mmuaux aux) = tss @ tss'" + using valid_eval_step_mmuaux'[OF Cons(2) app_ass] by auto + show ?case + using Cons(1)[OF valid_step] valid_step Cons(4) app_ass by auto +qed auto + +lemma sorted_dropWhile_filter: "sorted xs \ dropWhile (\t. enat t + right I < enat nt) xs = + filter (\t. \enat t + right I < enat nt) xs" +proof (induction xs) + case (Cons x xs) + then show ?case + proof (cases "enat x + right I < enat nt") + case False + then have neg: "enat x + right I \ enat nt" + by auto + have "\z. z \ set xs \ \enat z + right I < enat nt" + proof - + fix z + assume "z \ set xs" + then have "enat z + right I \ enat x + right I" + using Cons by auto + with neg have "enat z + right I \ enat nt" + using dual_order.trans by blast + then show "\enat z + right I < enat nt" + by auto + qed + with False show ?thesis + using filter_empty_conv by auto + qed auto +qed auto + +fun shift_mmuaux :: "args \ ts \ 'a mmuaux \ 'a mmuaux" where + "shift_mmuaux args nt (tp, tss, len, maskL, maskR, a1_map, a2_map, done, done_length) = + (let tss_list = linearize (takeWhile_queue (\t. enat t + right (args_ivl args) < enat nt) tss) in + foldl (\aux _. eval_step_mmuaux aux) (tp, tss, len, maskL, maskR, + a1_map, a2_map, done, done_length) tss_list)" + +lemma valid_shift_mmuaux': + assumes "valid_mmuaux' args cur cur aux auxlist" "nt \ cur" + shows "valid_mmuaux' args cur nt (shift_mmuaux args nt aux) auxlist \ + (\ts \ set (lin_ts_mmuaux (shift_mmuaux args nt aux)). \enat ts + right (args_ivl args) < nt)" +proof - + define I where "I = args_ivl args" + define pos where "pos = args_pos args" + have valid_folded: "valid_mmuaux' args cur nt aux auxlist" + using assms(1,2) valid_mmuaux'_mono unfolding valid_mmuaux_def by blast + obtain tp len tss maskL maskR a1_map a2_map "done" done_length where aux_def: + "aux = (tp, tss, len, maskL, maskR, a1_map, a2_map, done, done_length)" + by (cases aux) auto + note valid_before = valid_folded[unfolded aux_def] + define tss_list where "tss_list = + linearize (takeWhile_queue (\t. enat t + right I < enat nt) tss)" + have tss_list_takeWhile: "tss_list = takeWhile (\t. enat t + right I < enat nt) (linearize tss)" + using tss_list_def unfolding takeWhile_queue_rep . + then obtain tss_list' where tss_list'_def: "linearize tss = tss_list @ tss_list'" + "tss_list' = dropWhile (\t. enat t + right I < enat nt) (linearize tss)" + by auto + obtain tp' len' tss' maskL' maskR' a1_map' a2_map' "done'" done_length' where + foldl_aux_def: "(tp', tss', len', maskL', maskR', a1_map', a2_map', + done', done_length') = foldl (\aux _. eval_step_mmuaux aux) aux tss_list" + by (cases "foldl (\aux _. eval_step_mmuaux aux) aux tss_list") auto + have lin_tss_aux: "lin_ts_mmuaux aux = linearize tss" + unfolding aux_def by auto + have "take (length tss_list) (lin_ts_mmuaux aux) = tss_list" + unfolding lin_tss_aux using tss_list'_def(1) by auto + then have valid_foldl: "valid_mmuaux' args cur nt + (foldl (\aux _. eval_step_mmuaux aux) aux tss_list) auxlist" + "lin_ts_mmuaux (foldl (\aux _. eval_step_mmuaux aux) aux tss_list) = tss_list'" + using valid_foldl_eval_step_mmuaux'[OF valid_before[folded aux_def], unfolded lin_tss_aux, + OF tss_list'_def(1)] tss_list_takeWhile set_takeWhileD + unfolding lin_tss_aux I_def by fastforce+ + have shift_mmuaux_eq: "shift_mmuaux args nt aux = foldl (\aux _. eval_step_mmuaux aux) aux tss_list" + using tss_list_def unfolding aux_def I_def by auto + have "\ts. ts \ set tss_list' \ \enat ts + right (args_ivl args) < nt" + using sorted_dropWhile_filter tss_list'_def(2) valid_before unfolding I_def by auto + then show ?thesis + using valid_foldl(1)[unfolded shift_mmuaux_eq[symmetric]] + unfolding valid_foldl(2)[unfolded shift_mmuaux_eq[symmetric]] by auto +qed + +lift_definition upd_set' :: "('a, 'b) mapping \ 'b \ ('b \ 'b) \ 'a set \ ('a, 'b) mapping" is + "\m d f X a. (if a \ X then (case Mapping.lookup m a of Some b \ Some (f b) | None \ Some d) + else Mapping.lookup m a)" . + +lemma upd_set'_lookup: "Mapping.lookup (upd_set' m d f X) a = (if a \ X then + (case Mapping.lookup m a of Some b \ Some (f b) | None \ Some d) else Mapping.lookup m a)" + by (simp add: Mapping.lookup.rep_eq upd_set'.rep_eq) + +lemma upd_set'_keys: "Mapping.keys (upd_set' m d f X) = Mapping.keys m \ X" + by (auto simp add: upd_set'_lookup intro!: Mapping_keys_intro + dest!: Mapping_keys_dest split: option.splits) + +lift_definition upd_nested :: "('a, ('b, 'c) mapping) mapping \ + 'c \ ('c \ 'c) \ ('a \ 'b) set \ ('a, ('b, 'c) mapping) mapping" is + "\m d f X a. case Mapping.lookup m a of Some m' \ Some (upd_set' m' d f {b. (a, b) \ X}) + | None \ if a \ fst ` X then Some (upd_set' Mapping.empty d f {b. (a, b) \ X}) else None" . + +lemma upd_nested_lookup: "Mapping.lookup (upd_nested m d f X) a = + (case Mapping.lookup m a of Some m' \ Some (upd_set' m' d f {b. (a, b) \ X}) + | None \ if a \ fst ` X then Some (upd_set' Mapping.empty d f {b. (a, b) \ X}) else None)" + by (simp add: Mapping.lookup.abs_eq upd_nested.abs_eq) + +lemma upd_nested_keys: "Mapping.keys (upd_nested m d f X) = Mapping.keys m \ fst ` X" + by (auto simp add: upd_nested_lookup Domain.DomainI fst_eq_Domain intro!: Mapping_keys_intro + dest!: Mapping_keys_dest split: option.splits) + +fun add_new_mmuaux :: "args \ 'a table \ 'a table \ ts \ 'a mmuaux \ 'a mmuaux" where + "add_new_mmuaux args rel1 rel2 nt aux = + (let (tp, tss, len, maskL, maskR, a1_map, a2_map, done, done_length) = + shift_mmuaux args nt aux; + I = args_ivl args; pos = args_pos args; + new_tstp = (if left I = 0 then Inr tp else Inl (nt - (left I - 1))); + tmp = \((\as. case Mapping.lookup a1_map (proj_tuple maskL as) of None \ + (if \pos then {(tp - len, as)} else {}) + | Some tp' \ if pos then {(max (tp - len) tp', as)} + else {(max (tp - len) (tp' + 1), as)}) ` rel2) \ (if left I = 0 then {tp} \ rel2 else {}); + a2_map = Mapping.update (tp + 1) Mapping.empty + (upd_nested a2_map new_tstp (max_tstp new_tstp) tmp); + a1_map = (if pos then Mapping.filter (\as _. as \ rel1) + (upd_set a1_map (\_. tp) (rel1 - Mapping.keys a1_map)) else upd_set a1_map (\_. tp) rel1); + tss = append_queue nt tss in + (tp + 1, tss, len + 1, maskL, maskR, a1_map, a2_map, done, done_length))" + +lemma fst_case: "(\x. fst (case x of (t, a1, a2) \ (t, y t a1 a2, z t a1 a2))) = fst" + by auto + +lemma list_all2_in_setE: "list_all2 P xs ys \ x \ set xs \ (\y. y \ set ys \ P x y \ Q) \ Q" + by (fastforce simp: list_all2_iff set_zip in_set_conv_nth) + +lemma list_all2_zip: "list_all2 (\x y. triple_eq_pair x y f g) xs (zip ys zs) \ + (\y. y \ set ys \ Q y) \ x \ set xs \ Q (fst x)" + by (auto simp: in_set_zip elim!: list_all2_in_setE triple_eq_pair.elims) + +lemma list_appendE: "xs = ys @ zs \ x \ set xs \ + (x \ set ys \ P) \ (x \ set zs \ P) \ P" + by auto + +lemma take_takeWhile: "n \ length ys \ + (\y. y \ set (take n ys) \ P y) \ + (\y. y \ set (drop n ys) \ \P y) \ + take n ys = takeWhile P ys" +proof (induction ys arbitrary: n) + case Nil + then show ?case by simp +next + case (Cons y ys) + then show ?case by (cases n) simp_all +qed + +lemma valid_add_new_mmuaux: + assumes valid_before: "valid_mmuaux args cur aux auxlist" + and tabs: "table (args_n args) (args_L args) rel1" "table (args_n args) (args_R args) rel2" + and nt_mono: "nt \ cur" + shows "valid_mmuaux args nt (add_new_mmuaux args rel1 rel2 nt aux) + (update_until args rel1 rel2 nt auxlist)" +proof - + define I where "I = args_ivl args" + define n where "n = args_n args" + define L where "L = args_L args" + define R where "R = args_R args" + define pos where "pos = args_pos args" + have valid_folded: "valid_mmuaux' args cur nt aux auxlist" + using assms(1,4) valid_mmuaux'_mono unfolding valid_mmuaux_def by blast + obtain tp len tss maskL maskR a1_map a2_map "done" done_length where shift_aux_def: + "shift_mmuaux args nt aux = (tp, tss, len, maskL, maskR, a1_map, a2_map, done, done_length)" + by (cases "shift_mmuaux args nt aux") auto + have valid_shift_aux: "valid_mmuaux' args cur nt (tp, tss, len, maskL, maskR, + a1_map, a2_map, done, done_length) auxlist" + "\ts. ts \ set (linearize tss) \ \enat ts + right (args_ivl args) < enat nt" + using valid_shift_mmuaux'[OF assms(1)[unfolded valid_mmuaux_def] assms(4)] + unfolding shift_aux_def by auto + define new_tstp where "new_tstp = (if left I = 0 then Inr tp else Inl (nt - (left I - 1)))" + have new_tstp_lt_isl: "tstp_lt new_tstp (nt - (left I - 1)) (tp + 1)" + "isl new_tstp \ left I > 0" + by (auto simp add: new_tstp_def tstp_lt_def) + define tmp where "tmp = \((\as. case Mapping.lookup a1_map (proj_tuple maskL as) of None \ + (if \pos then {(tp - len, as)} else {}) + | Some tp' \ if pos then {(max (tp - len) tp', as)} + else {(max (tp - len) (tp' + 1), as)}) ` rel2) \ (if left I = 0 then {tp} \ rel2 else {})" + have a1_map_lookup: "\as tp'. Mapping.lookup a1_map as = Some tp' \ tp' < tp" + using valid_shift_aux(1) Mapping_keys_intro by force + then have fst_tmp: "\tp'. tp' \ fst ` tmp \ tp - len \ tp' \ tp' < tp + 1" + unfolding tmp_def by (auto simp add: less_SucI split: option.splits if_splits) + have snd_tmp: "\tp'. table n R (snd ` tmp)" + using tabs(2) unfolding tmp_def n_def R_def + by (auto simp add: table_def split: if_splits option.splits) + define a2_map' where "a2_map' = Mapping.update (tp + 1) Mapping.empty + (upd_nested a2_map new_tstp (max_tstp new_tstp) tmp)" + define a1_map' where "a1_map' = (if pos then Mapping.filter (\as _. as \ rel1) + (upd_set a1_map (\_. tp) (rel1 - Mapping.keys a1_map)) else upd_set a1_map (\_. tp) rel1)" + define tss' where "tss' = append_queue nt tss" + have add_new_mmuaux_eq: "add_new_mmuaux args rel1 rel2 nt aux = (tp + 1, tss', len + 1, + maskL, maskR, a1_map', a2_map', done, done_length)" + using shift_aux_def new_tstp_def tmp_def a2_map'_def a1_map'_def tss'_def + unfolding I_def pos_def + by (auto simp only: add_new_mmuaux.simps Let_def) + have update_until_eq: "update_until args rel1 rel2 nt auxlist = + (map (\x. case x of (t, a1, a2) \ (t, if pos then join a1 True rel1 else a1 \ rel1, + if mem (nt - t) I then a2 \ join rel2 pos a1 else a2)) auxlist) @ + [(nt, rel1, if left I = 0 then rel2 else empty_table)]" + unfolding update_until_def I_def pos_def by simp + have len_done_auxlist: "length done \ length auxlist" + using valid_shift_aux by auto + have auxlist_split: "auxlist = take (length done) auxlist @ drop (length done) auxlist" + using len_done_auxlist by auto + have lin_tss': "linearize tss' = linearize tss @ [nt]" + unfolding tss'_def append_queue_rep by (rule refl) + have len_lin_tss': "length (linearize tss') = len + 1" + unfolding lin_tss' using valid_shift_aux by auto + have tmp: "sorted (linearize tss)" "\t. t \ set (linearize tss) \ t \ cur" + using valid_shift_aux by auto + have sorted_lin_tss': "sorted (linearize tss')" + unfolding lin_tss' using tmp(1) le_trans[OF _ assms(4), OF tmp(2)] + by (simp add: sorted_append) + have in_lin_tss: "\t. t \ set (linearize tss) \ + t \ cur \ enat cur \ enat t + right I" + using valid_shift_aux(1) unfolding I_def by auto + then have set_lin_tss': "\t \ set (linearize tss'). t \ nt \ enat nt \ enat t + right I" + unfolding lin_tss' I_def using le_trans[OF _ assms(4)] valid_shift_aux(2) + by (auto simp add: not_less) + have a1_map'_keys: "Mapping.keys a1_map' \ Mapping.keys a1_map \ rel1" + unfolding a1_map'_def using Mapping.keys_filter Mapping_upd_set_keys + by (auto simp add: Mapping_upd_set_keys split: if_splits dest: Mapping_keys_filterD) + then have tab_a1_map'_keys: "table n L (Mapping.keys a1_map')" + using valid_shift_aux(1) tabs(1) by (auto simp add: table_def n_def L_def) + have a2_map_keys: "Mapping.keys a2_map = {tp - len..tp}" + using valid_shift_aux by auto + have a2_map'_keys: "Mapping.keys a2_map' = {tp - len..tp + 1}" + unfolding a2_map'_def Mapping.keys_update upd_nested_keys a2_map_keys using fst_tmp + by fastforce + then have a2_map'_keys': "Mapping.keys a2_map' = {tp + 1 - (len + 1)..tp + 1}" + by auto + have len_upd_until: "length done + (len + 1) = length (update_until args rel1 rel2 nt auxlist)" + using valid_shift_aux unfolding update_until_eq by auto + have set_take_auxlist: "\x. x \ set (take (length done) auxlist) \ check_before I nt x" + using valid_shift_aux unfolding I_def by auto + have list_all2_triple: "list_all2 (\x y. triple_eq_pair x y (\tp'. filter_a1_map pos tp' a1_map) + (\ts' tp'. filter_a2_map I ts' tp' a2_map)) (drop (length done) auxlist) + (zip (linearize tss) [tp - len..x. x \ set (drop (length done) auxlist) \ \check_before I nt x" + using valid_shift_aux(2)[OF list_all2_zip[OF list_all2_triple, + of "\y. y \ set (linearize tss)"]] + unfolding I_def by auto + have length_done_auxlist: "length done \ length auxlist" + using valid_shift_aux by auto + have take_auxlist_takeWhile: "take (length done) auxlist = takeWhile (check_before I nt) auxlist" + using take_takeWhile[OF length_done_auxlist set_take_auxlist set_drop_auxlist] . + have "length done = length (takeWhile (check_before I nt) auxlist)" + by (metis (no_types) add_diff_cancel_right' auxlist_split diff_diff_cancel + length_append length_done_auxlist length_drop take_auxlist_takeWhile) + then have set_take_auxlist': "\x. x \ set (take (length done) + (update_until args rel1 rel2 nt auxlist)) \ check_before I nt x" + by (metis I_def length_map map_proj_thd_update_until set_takeWhileD takeWhile_eq_take) + have rev_done: "rev done = map proj_thd (take (length done) auxlist)" + using valid_shift_aux by auto + moreover have "\ = map proj_thd (takeWhile (check_before I nt) + (update_until args rel1 rel2 nt auxlist))" + by (simp add: take_auxlist_takeWhile map_proj_thd_update_until I_def) + finally have rev_done': "rev done = map proj_thd (take (length done) + (update_until args rel1 rel2 nt auxlist))" + by (metis length_map length_rev takeWhile_eq_take) + have map_fst_auxlist_take: "\t. t \ set (map fst (take (length done) auxlist)) \ t \ nt" + using set_take_auxlist + by auto (meson add_increasing2 enat_ord_simps(1) le_cases not_less zero_le) + have map_fst_auxlist_drop: "\t. t \ set (map fst (drop (length done) auxlist)) \ t \ nt" + using in_lin_tss[OF list_all2_zip[OF list_all2_triple, of "\y. y \ set (linearize tss)"]] + assms(4) dual_order.trans by auto blast + have set_drop_auxlist_cong: "\x t a1 a2. x \ set (drop (length done) auxlist) \ + x = (t, a1, a2) \ mem (nt - t) I \ left I \ nt - t" + proof - + fix x t a1 a2 + assume "x \ set (drop (length done) auxlist)" "x = (t, a1, a2)" + then have "enat t + right I \ enat nt" + using set_drop_auxlist not_less + by auto blast + then have "right I \ enat (nt - t)" + by (cases "right I") auto + then show "mem (nt - t) I \ left I \ nt - t" + by auto + qed + have sorted_fst_auxlist: "sorted (map fst auxlist)" + using valid_shift_aux by auto + have set_map_fst_auxlist: "\t. t \ set (map fst auxlist) \ t \ nt" + using arg_cong[OF auxlist_split, of "map fst", unfolded map_append] map_fst_auxlist_take + map_fst_auxlist_drop by auto + have lookup_a1_map_keys: "\xs tp'. Mapping.lookup a1_map xs = Some tp' \ tp' < tp" + using valid_shift_aux Mapping_keys_intro by force + have lookup_a1_map_keys': "\xs \ Mapping.keys a1_map'. + case Mapping.lookup a1_map' xs of Some tp' \ tp' < tp + 1" + using lookup_a1_map_keys unfolding a1_map'_def + by (auto simp add: Mapping.lookup_filter Mapping_lookup_upd_set Mapping_upd_set_keys + split: option.splits dest: Mapping_keys_dest) fastforce+ + have sorted_upd_until: "sorted (map fst (update_until args rel1 rel2 nt auxlist))" + using sorted_fst_auxlist set_map_fst_auxlist + unfolding update_until_eq + by (auto simp add: sorted_append comp_def fst_case) + have lookup_a2_map: "\tp' m. Mapping.lookup a2_map tp' = Some m \ + table n R (Mapping.keys m) \ (\xs \ Mapping.keys m. case Mapping.lookup m xs of Some tstp \ + tstp_lt tstp (cur - (left I - 1)) tp \ (isl tstp \ left I > 0))" + using valid_shift_aux(1) Mapping_keys_intro unfolding I_def n_def R_def by force + then have lookup_a2_map': "\tp' m xs tstp. Mapping.lookup a2_map tp' = Some m \ + Mapping.lookup m xs = Some tstp \ tstp_lt tstp (nt - (left I - 1)) tp \ + isl tstp = (0 < left I)" + using Mapping_keys_intro assms(4) by (force simp add: tstp_lt_def split: sum.splits) + have lookup_a2_map'_keys: "\tp' \ Mapping.keys a2_map'. + case Mapping.lookup a2_map' tp' of Some m \ table n R (Mapping.keys m) \ + (\xs \ Mapping.keys m. case Mapping.lookup m xs of Some tstp \ + tstp_lt tstp (nt - (left I - 1)) (tp + 1) \ isl tstp = (0 < left I))" + proof (rule ballI) + fix tp' + assume tp'_assm: "tp' \ Mapping.keys a2_map'" + then obtain m' where m'_def: "Mapping.lookup a2_map' tp' = Some m'" + by (auto dest: Mapping_keys_dest) + have "table n R (Mapping.keys m') \ + (\xs \ Mapping.keys m'. case Mapping.lookup m' xs of Some tstp \ + tstp_lt tstp (nt - (left I - 1)) (tp + 1) \ isl tstp = (0 < left I))" + proof (cases "tp' = tp + 1") + case True + show ?thesis + using m'_def unfolding a2_map'_def True Mapping.lookup_update + by (auto simp add: table_def) + next + case False + then have tp'_in: "tp' \ Mapping.keys a2_map" + using tp'_assm unfolding a2_map_keys a2_map'_keys by auto + then obtain m where m_def: "Mapping.lookup a2_map tp' = Some m" + by (auto dest: Mapping_keys_dest) + have m'_alt: "m' = upd_set' m new_tstp (max_tstp new_tstp) {b. (tp', b) \ tmp}" + using m_def m'_def unfolding a2_map'_def Mapping.lookup_update_neq[OF False[symmetric]] + upd_nested_lookup + by auto + have "table n R (Mapping.keys m')" + using lookup_a2_map[OF m_def] snd_tmp unfolding m'_alt upd_set'_keys + by (auto simp add: table_def) + moreover have "\xs \ Mapping.keys m'. case Mapping.lookup m' xs of Some tstp \ + tstp_lt tstp (nt - (left I - 1)) (tp + 1) \ isl tstp = (0 < left I)" + proof (rule ballI) + fix xs + assume xs_assm: "xs \ Mapping.keys m'" + then obtain tstp where tstp_def: "Mapping.lookup m' xs = Some tstp" + by (auto dest: Mapping_keys_dest) + have "tstp_lt tstp (nt - (left I - 1)) (tp + 1) \ isl tstp = (0 < left I)" + proof (cases "Mapping.lookup m xs") + case None + then show ?thesis + using tstp_def[unfolded m'_alt upd_set'_lookup] new_tstp_lt_isl + by (auto split: if_splits) + next + case (Some tstp') + show ?thesis + proof (cases "xs \ {b. (tp', b) \ tmp}") + case True + then have tstp_eq: "tstp = max_tstp new_tstp tstp'" + using tstp_def[unfolded m'_alt upd_set'_lookup] Some + by auto + show ?thesis + using lookup_a2_map'[OF m_def Some] new_tstp_lt_isl + by (auto simp add: tstp_lt_def tstp_eq split: sum.splits) + next + case False + then show ?thesis + using tstp_def[unfolded m'_alt upd_set'_lookup] lookup_a2_map'[OF m_def Some] Some + by (auto simp add: tstp_lt_def split: sum.splits) + qed + qed + then show "case Mapping.lookup m' xs of Some tstp \ + tstp_lt tstp (nt - (left I - 1)) (tp + 1) \ isl tstp = (0 < left I)" + using tstp_def by auto + qed + ultimately show ?thesis + by auto + qed + then show "case Mapping.lookup a2_map' tp' of Some m \ table n R (Mapping.keys m) \ + (\xs \ Mapping.keys m. case Mapping.lookup m xs of Some tstp \ + tstp_lt tstp (nt - (left I - 1)) (tp + 1) \ isl tstp = (0 < left I))" + using m'_def by auto + qed + have tp_upt_Suc: "[tp + 1 - (len + 1)..x. case x of (t, a1, a2) \ (t, if pos then join a1 True rel1 else a1 \ rel1, + if mem (nt - t) I then a2 \ join rel2 pos a1 else a2)) (drop (length done) auxlist) = + map (\x. case x of (t, a1, a2) \ (t, if pos then join a1 True rel1 else a1 \ rel1, + if left I \ nt - t then a2 \ join rel2 pos a1 else a2)) (drop (length done) auxlist)" + using set_drop_auxlist_cong by auto + have "drop (length done) (update_until args rel1 rel2 nt auxlist) = + map (\x. case x of (t, a1, a2) \ (t, if pos then join a1 True rel1 else a1 \ rel1, + if mem (nt - t) I then a2 \ join rel2 pos a1 else a2)) (drop (length done) auxlist) @ + [(nt, rel1, if left I = 0 then rel2 else empty_table)]" + unfolding update_until_eq using len_done_auxlist drop_map by auto + note drop_update_until = this[unfolded map_eq] + have list_all2_old: "list_all2 (\x y. triple_eq_pair x y (\tp'. filter_a1_map pos tp' a1_map') + (\ts' tp'. filter_a2_map I ts' tp' a2_map')) + (map (\(t, a1, a2). (t, if pos then join a1 True rel1 else a1 \ rel1, + if left I \ nt - t then a2 \ join rel2 pos a1 else a2)) (drop (length done) auxlist)) + (zip (linearize tss) [tp - len.. set (drop (length done) auxlist)" + "pair \ set (zip (linearize tss) [tp - len..tp'. filter_a1_map pos tp' a1_map) + (\ts' tp'. filter_a2_map I ts' tp' a2_map)" + then have eqs: "t = ts'" "a1 = filter_a1_map pos tp' a1_map" + "a2 = filter_a2_map I ts' tp' a2_map" + unfolding tri_def pair_def by auto + have tp'_ge: "tp' \ tp - len" + using tri_pair_in(2) unfolding pair_def + by (auto elim: in_set_zipE) + have tp'_lt_tp: "tp' < tp" + using tri_pair_in(2) unfolding pair_def + by (auto elim: in_set_zipE) + have ts'_in_lin_tss: "ts' \ set (linearize tss)" + using tri_pair_in(2) unfolding pair_def + by (auto elim: in_set_zipE) + then have ts'_nt: "ts' \ nt" + using valid_shift_aux(1) assms(4) by auto + then have t_nt: "t \ nt" + unfolding eqs(1) . + have "table n L (Mapping.keys a1_map)" + using valid_shift_aux unfolding n_def L_def by auto + then have a1_tab: "table n L a1" + unfolding eqs(2) filter_a1_map_def by (auto simp add: table_def) + note tabR = tabs(2)[unfolded n_def[symmetric] R_def[symmetric]] + have join_rel2_assms: "L \ R" "maskL = join_mask n L" + using valid_shift_aux unfolding n_def L_def R_def by auto + have join_rel2_eq: "join rel2 pos a1 = {xs \ rel2. proj_tuple_in_join pos maskL xs a1}" + using join_sub[OF join_rel2_assms(1) a1_tab tabR] join_rel2_assms(2) by auto + have filter_sub_a2: "\xs m' tp'' tstp. tp'' \ tp' \ + Mapping.lookup a2_map' tp'' = Some m' \ Mapping.lookup m' xs = Some tstp \ + ts_tp_lt' ts' tp' tstp \ (tstp = new_tstp \ False) \ + xs \ filter_a2_map I ts' tp' a2_map' \ xs \ a2" + proof - + fix xs m' tp'' tstp + assume m'_def: "tp'' \ tp'" "Mapping.lookup a2_map' tp'' = Some m'" + "Mapping.lookup m' xs = Some tstp" "ts_tp_lt' ts' tp' tstp" + have tp''_neq: "tp + 1 \ tp''" + using le_less_trans[OF m'_def(1) tp'_lt_tp] by auto + assume new_tstp_False: "tstp = new_tstp \ False" + show "xs \ a2" + proof (cases "Mapping.lookup a2_map tp''") + case None + then have m'_alt: "m' = upd_set' Mapping.empty new_tstp (max_tstp new_tstp) + {b. (tp'', b) \ tmp}" + using m'_def(2)[unfolded a2_map'_def Mapping.lookup_update_neq[OF tp''_neq] + upd_nested_lookup] by (auto split: option.splits if_splits) + then show ?thesis + using new_tstp_False m'_def(3)[unfolded m'_alt upd_set'_lookup Mapping.lookup_empty] + by (auto split: if_splits) + next + case (Some m) + then have m'_alt: "m' = upd_set' m new_tstp (max_tstp new_tstp) {b. (tp'', b) \ tmp}" + using m'_def(2)[unfolded a2_map'_def Mapping.lookup_update_neq[OF tp''_neq] + upd_nested_lookup] by (auto split: option.splits if_splits) + note lookup_m = Some + show ?thesis + proof (cases "Mapping.lookup m xs") + case None + then show ?thesis + using new_tstp_False m'_def(3)[unfolded m'_alt upd_set'_lookup] + by (auto split: if_splits) + next + case (Some tstp') + have tstp_ok: "tstp = tstp' \ xs \ a2" + using eqs(3) lookup_m Some m'_def unfolding filter_a2_map_def by auto + show ?thesis + proof (cases "xs \ {b. (tp'', b) \ tmp}") + case True + then have tstp_eq: "tstp = max_tstp new_tstp tstp'" + using m'_def(3)[unfolded m'_alt upd_set'_lookup Some] by auto + show ?thesis + using lookup_a2_map'[OF lookup_m Some] new_tstp_lt_isl(2) + tstp_eq new_tstp_False tstp_ok + by (auto intro: max_tstpE[of new_tstp tstp']) + next + case False + then have "tstp = tstp'" + using m'_def(3)[unfolded m'_alt upd_set'_lookup Some] by auto + then show ?thesis + using tstp_ok by auto + qed + qed + qed + qed + have a2_sub_filter: "a2 \ filter_a2_map I ts' tp' a2_map'" + proof (rule subsetI) + fix xs + assume xs_in: "xs \ a2" + then obtain tp'' m tstp where m_def: "tp'' \ tp'" "Mapping.lookup a2_map tp'' = Some m" + "Mapping.lookup m xs = Some tstp" "ts_tp_lt' ts' tp' tstp" + using eqs(3)[unfolded filter_a2_map_def] by (auto split: option.splits) + have tp''_in: "tp'' \ {tp - len..tp}" + using m_def(2) a2_map_keys by (auto intro!: Mapping_keys_intro) + then obtain m' where m'_def: "Mapping.lookup a2_map' tp'' = Some m'" + using a2_map'_keys + by (metis Mapping_keys_dest One_nat_def add_Suc_right add_diff_cancel_right' + atLeastatMost_subset_iff diff_zero le_eq_less_or_eq le_less_Suc_eq subsetD) + have tp''_neq: "tp + 1 \ tp''" + using m_def(1) tp'_lt_tp by auto + have m'_alt: "m' = upd_set' m new_tstp (max_tstp new_tstp) {b. (tp'', b) \ tmp}" + using m'_def[unfolded a2_map'_def Mapping.lookup_update_neq[OF tp''_neq] m_def(2) + upd_nested_lookup] by (auto split: option.splits if_splits) + show "xs \ filter_a2_map I ts' tp' a2_map'" + proof (cases "xs \ {b. (tp'', b) \ tmp}") + case True + then have "Mapping.lookup m' xs = Some (max_tstp new_tstp tstp)" + unfolding m'_alt upd_set'_lookup m_def(3) by auto + moreover have "ts_tp_lt' ts' tp' (max_tstp new_tstp tstp)" + using new_tstp_lt_isl(2) lookup_a2_map'[OF m_def(2,3)] + by (auto intro: max_tstp_intro''''[OF _ m_def(4)]) + ultimately show ?thesis + unfolding filter_a2_map_def using m_def(1) m'_def m_def(4) by auto + next + case False + then have "Mapping.lookup m' xs = Some tstp" + unfolding m'_alt upd_set'_lookup m_def(3) by auto + then show ?thesis + unfolding filter_a2_map_def using m_def(1) m'_def m_def by auto + qed + qed + have "pos \ filter_a1_map pos tp' a1_map' = join a1 True rel1" + proof - + assume pos: pos + note tabL = tabs(1)[unfolded n_def[symmetric] L_def[symmetric]] + have join_eq: "join a1 True rel1 = a1 \ rel1" + using join_eq[OF tabL a1_tab] by auto + show "filter_a1_map pos tp' a1_map' = join a1 True rel1" + using eqs(2) pos tp'_lt_tp unfolding filter_a1_map_def a1_map'_def join_eq + by (auto simp add: Mapping.lookup_filter Mapping_lookup_upd_set split: if_splits option.splits + intro: Mapping_keys_intro dest: Mapping_keys_dest Mapping_keys_filterD) + qed + moreover have "\pos \ filter_a1_map pos tp' a1_map' = a1 \ rel1" + using eqs(2) tp'_lt_tp unfolding filter_a1_map_def a1_map'_def + by (auto simp add: Mapping.lookup_filter Mapping_lookup_upd_set intro: Mapping_keys_intro + dest: Mapping_keys_filterD Mapping_keys_dest split: option.splits) + moreover have "left I \ nt - t \ filter_a2_map I ts' tp' a2_map' = a2 \ join rel2 pos a1" + proof (rule set_eqI, rule iffI) + fix xs + assume in_int: "left I \ nt - t" + assume xs_in: "xs \ filter_a2_map I ts' tp' a2_map'" + then obtain m' tp'' tstp where m'_def: "tp'' \ tp'" "Mapping.lookup a2_map' tp'' = Some m'" + "Mapping.lookup m' xs = Some tstp" "ts_tp_lt' ts' tp' tstp" + unfolding filter_a2_map_def by (fastforce split: option.splits) + show "xs \ a2 \ join rel2 pos a1" + proof (cases "tstp = new_tstp") + case True + note tstp_new_tstp = True + have tp''_neq: "tp + 1 \ tp''" + using m'_def(1) tp'_lt_tp by auto + have tp''_in: "tp'' \ {tp - len..tp}" + using m'_def(1,2) tp'_lt_tp a2_map'_keys + by (auto intro!: Mapping_keys_intro) + obtain m where m_def: "Mapping.lookup a2_map tp'' = Some m" + "m' = upd_set' m new_tstp (max_tstp new_tstp) {b. (tp'', b) \ tmp}" + using m'_def(2)[unfolded a2_map'_def Mapping.lookup_update_neq[OF tp''_neq] + upd_nested_lookup] tp''_in a2_map_keys + by (fastforce dest: Mapping_keys_dest split: option.splits if_splits) + show ?thesis + proof (cases "Mapping.lookup m xs = Some new_tstp") + case True + then show ?thesis + using eqs(3) m'_def(1) m_def(1) m'_def tstp_new_tstp + unfolding filter_a2_map_def by auto + next + case False + then have xs_in_snd_tmp: "xs \ {b. (tp'', b) \ tmp}" + using m'_def(3)[unfolded m_def(2) upd_set'_lookup True] + by (auto split: if_splits) + then have xs_in_rel2: "xs \ rel2" + unfolding tmp_def + by (auto split: if_splits option.splits) + show ?thesis + proof (cases pos) + case True + obtain tp''' where tp'''_def: "Mapping.lookup a1_map (proj_tuple maskL xs) = Some tp'''" + "if pos then tp'' = max (tp - len) tp''' else tp'' = max (tp - len) (tp''' + 1)" + using xs_in_snd_tmp m'_def(1) tp'_lt_tp True + unfolding tmp_def by (auto split: option.splits if_splits) + have "proj_tuple maskL xs \ a1" + using eqs(2)[unfolded filter_a1_map_def] True m'_def(1) tp'''_def + by (auto intro: Mapping_keys_intro) + then show ?thesis + using True xs_in_rel2 unfolding proj_tuple_in_join_def join_rel2_eq by auto + next + case False + show ?thesis + proof (cases "Mapping.lookup a1_map (proj_tuple maskL xs)") + case None + then show ?thesis + using xs_in_rel2 False eqs(2)[unfolded filter_a1_map_def] + unfolding proj_tuple_in_join_def join_rel2_eq + by (auto dest: Mapping_keys_dest) + next + case (Some tp''') + then have "tp'' = max (tp - len) (tp''' + 1)" + using xs_in_snd_tmp m'_def(1) tp'_lt_tp False + unfolding tmp_def by (auto split: option.splits if_splits) + then have "tp''' < tp'" + using m'_def(1) by auto + then have "proj_tuple maskL xs \ a1" + using eqs(2)[unfolded filter_a1_map_def] True m'_def(1) Some False + by (auto intro: Mapping_keys_intro) + then show ?thesis + using xs_in_rel2 False unfolding proj_tuple_in_join_def join_rel2_eq by auto + qed + qed + qed + next + case False + then show ?thesis + using filter_sub_a2[OF m'_def _ xs_in] by auto + qed + next + fix xs + assume in_int: "left I \ nt - t" + assume xs_in: "xs \ a2 \ join rel2 pos a1" + then have "xs \ a2 \ (join rel2 pos a1 - a2)" + by auto + then show "xs \ filter_a2_map I ts' tp' a2_map'" + proof (rule UnE) + assume "xs \ a2" + then show "xs \ filter_a2_map I ts' tp' a2_map'" + using a2_sub_filter by auto + next + assume "xs \ join rel2 pos a1 - a2" + then have xs_props: "xs \ rel2" "xs \ a2" "proj_tuple_in_join pos maskL xs a1" + unfolding join_rel2_eq by auto + have ts_tp_lt'_new_tstp: "ts_tp_lt' ts' tp' new_tstp" + using tp'_lt_tp in_int t_nt eqs(1) unfolding new_tstp_def + by (auto simp add: ts_tp_lt'_def) + show "xs \ filter_a2_map I ts' tp' a2_map'" + proof (cases pos) + case True + then obtain tp''' where tp'''_def: "tp''' \ tp'" + "Mapping.lookup a1_map (proj_tuple maskL xs) = Some tp'''" + using eqs(2)[unfolded filter_a1_map_def] xs_props(3)[unfolded proj_tuple_in_join_def] + by (auto dest: Mapping_keys_dest) + define wtp where "wtp \ max (tp - len) tp'''" + have wtp_xs_in: "(wtp, xs) \ tmp" + unfolding wtp_def using tp'''_def tmp_def xs_props(1) True by fastforce + have wtp_le: "wtp \ tp'" + using tp'''_def(1) tp'_ge unfolding wtp_def by auto + have wtp_in: "wtp \ {tp - len..tp}" + using tp'''_def(1) tp'_lt_tp unfolding wtp_def by auto + have wtp_neq: "tp + 1 \ wtp" + using wtp_in by auto + obtain m where m_def: "Mapping.lookup a2_map wtp = Some m" + using wtp_in a2_map_keys Mapping_keys_dest by fastforce + obtain m' where m'_def: "Mapping.lookup a2_map' wtp = Some m'" + using wtp_in a2_map'_keys Mapping_keys_dest by fastforce + have m'_alt: "m' = upd_set' m new_tstp (max_tstp new_tstp) {b. (wtp, b) \ tmp}" + using m'_def[unfolded a2_map'_def Mapping.lookup_update_neq[OF wtp_neq] + upd_nested_lookup m_def] by auto + show ?thesis + proof (cases "Mapping.lookup m xs") + case None + have "Mapping.lookup m' xs = Some new_tstp" + using wtp_xs_in unfolding m'_alt upd_set'_lookup None by auto + then show ?thesis + unfolding filter_a2_map_def using wtp_le m'_def ts_tp_lt'_new_tstp by auto + next + case (Some tstp') + have "Mapping.lookup m' xs = Some (max_tstp new_tstp tstp')" + using wtp_xs_in unfolding m'_alt upd_set'_lookup Some by auto + moreover have "ts_tp_lt' ts' tp' (max_tstp new_tstp tstp')" + using max_tstp_intro''' ts_tp_lt'_new_tstp lookup_a2_map'[OF m_def Some] new_tstp_lt_isl + by auto + ultimately show ?thesis + using lookup_a2_map'[OF m_def Some] wtp_le m'_def + unfolding filter_a2_map_def by auto + qed + next + case False + show ?thesis + proof (cases "Mapping.lookup a1_map (proj_tuple maskL xs)") + case None + then have in_tmp: "(tp - len, xs) \ tmp" + using tmp_def False xs_props(1) by fastforce + obtain m where m_def: "Mapping.lookup a2_map (tp - len) = Some m" + using a2_map_keys by (fastforce dest: Mapping_keys_dest) + obtain m' where m'_def: "Mapping.lookup a2_map' (tp - len) = Some m'" + using a2_map'_keys by (fastforce dest: Mapping_keys_dest) + have tp_neq: "tp + 1 \ tp - len" + by auto + have m'_alt: "m' = upd_set' m new_tstp (max_tstp new_tstp) {b. (tp - len, b) \ tmp}" + using m'_def[unfolded a2_map'_def Mapping.lookup_update_neq[OF tp_neq] + upd_nested_lookup m_def] by auto + show ?thesis + proof (cases "Mapping.lookup m xs") + case None + have "Mapping.lookup m' xs = Some new_tstp" + unfolding m'_alt upd_set'_lookup None using in_tmp by auto + then show ?thesis + unfolding filter_a2_map_def using tp'_ge m'_def ts_tp_lt'_new_tstp by auto + next + case (Some tstp') + have "Mapping.lookup m' xs = Some (max_tstp new_tstp tstp')" + unfolding m'_alt upd_set'_lookup Some using in_tmp by auto + moreover have "ts_tp_lt' ts' tp' (max_tstp new_tstp tstp')" + using max_tstp_intro''' ts_tp_lt'_new_tstp lookup_a2_map'[OF m_def Some] new_tstp_lt_isl + by auto + ultimately show ?thesis + unfolding filter_a2_map_def using tp'_ge m'_def by auto + qed + next + case (Some tp''') + then have tp'_gt: "tp' > tp'''" + using xs_props(3)[unfolded proj_tuple_in_join_def] eqs(2)[unfolded filter_a1_map_def] + False by (auto intro: Mapping_keys_intro) + define wtp where "wtp \ max (tp - len) (tp''' + 1)" + have wtp_xs_in: "(wtp, xs) \ tmp" + unfolding wtp_def tmp_def using xs_props(1) Some False by fastforce + have wtp_le: "wtp \ tp'" + using tp'_ge tp'_gt unfolding wtp_def by auto + have wtp_in: "wtp \ {tp - len..tp}" + using tp'_lt_tp tp'_gt unfolding wtp_def by auto + have wtp_neq: "tp + 1 \ wtp" + using wtp_in by auto + obtain m where m_def: "Mapping.lookup a2_map wtp = Some m" + using wtp_in a2_map_keys Mapping_keys_dest by fastforce + obtain m' where m'_def: "Mapping.lookup a2_map' wtp = Some m'" + using wtp_in a2_map'_keys Mapping_keys_dest by fastforce + have m'_alt: "m' = upd_set' m new_tstp (max_tstp new_tstp) {b. (wtp, b) \ tmp}" + using m'_def[unfolded a2_map'_def Mapping.lookup_update_neq[OF wtp_neq] + upd_nested_lookup m_def] by auto + show ?thesis + proof (cases "Mapping.lookup m xs") + case None + have "Mapping.lookup m' xs = Some new_tstp" + using wtp_xs_in unfolding m'_alt upd_set'_lookup None by auto + then show ?thesis + unfolding filter_a2_map_def using wtp_le m'_def ts_tp_lt'_new_tstp by auto + next + case (Some tstp') + have "Mapping.lookup m' xs = Some (max_tstp new_tstp tstp')" + using wtp_xs_in unfolding m'_alt upd_set'_lookup Some by auto + moreover have "ts_tp_lt' ts' tp' (max_tstp new_tstp tstp')" + using max_tstp_intro''' ts_tp_lt'_new_tstp lookup_a2_map'[OF m_def Some] new_tstp_lt_isl + by auto + ultimately show ?thesis + using lookup_a2_map'[OF m_def Some] wtp_le m'_def + unfolding filter_a2_map_def by auto + qed + qed + qed + qed + qed + moreover have "nt - t < left I \ filter_a2_map I ts' tp' a2_map' = a2" + proof (rule set_eqI, rule iffI) + fix xs + assume out: "nt - t < left I" + assume xs_in: "xs \ filter_a2_map I ts' tp' a2_map'" + then obtain m' tp'' tstp where m'_def: "tp'' \ tp'" "Mapping.lookup a2_map' tp'' = Some m'" + "Mapping.lookup m' xs = Some tstp" "ts_tp_lt' ts' tp' tstp" + unfolding filter_a2_map_def by (fastforce split: option.splits) + have new_tstp_False: "tstp = new_tstp \ False" + using m'_def t_nt out tp'_lt_tp unfolding eqs(1) + by (auto simp add: ts_tp_lt'_def new_tstp_def) + show "xs \ a2" + using filter_sub_a2[OF m'_def new_tstp_False xs_in] . + next + fix xs + assume "xs \ a2" + then show "xs \ filter_a2_map I ts' tp' a2_map'" + using a2_sub_filter by auto + qed + ultimately show "triple_eq_pair (case tri of (t, a1, a2) \ + (t, if pos then join a1 True rel1 else a1 \ rel1, + if left I \ nt - t then a2 \ join rel2 pos a1 else a2)) + pair (\tp'. filter_a1_map pos tp' a1_map') (\ts' tp'. filter_a2_map I ts' tp' a2_map')" + using eqs unfolding tri_def pair_def by auto + qed + have filter_a1_map_rel1: "filter_a1_map pos tp a1_map' = rel1" + unfolding filter_a1_map_def a1_map'_def using leD lookup_a1_map_keys + by (force simp add: a1_map_lookup less_imp_le_nat Mapping.lookup_filter + Mapping_lookup_upd_set keys_is_none_rep dest: Mapping_keys_filterD + intro: Mapping_keys_intro split: option.splits) + have filter_a1_map_rel2: "filter_a2_map I nt tp a2_map' = + (if left I = 0 then rel2 else empty_table)" + proof (cases "left I = 0") + case True + note left_I_zero = True + have "\tp' m' xs tstp. tp' \ tp \ Mapping.lookup a2_map' tp' = Some m' \ + Mapping.lookup m' xs = Some tstp \ ts_tp_lt' nt tp tstp \ xs \ rel2" + proof - + fix tp' m' xs tstp + assume lassms: "tp' \ tp" "Mapping.lookup a2_map' tp' = Some m'" + "Mapping.lookup m' xs = Some tstp" "ts_tp_lt' nt tp tstp" + have tp'_neq: "tp + 1 \ tp'" + using lassms(1) by auto + have tp'_in: "tp' \ {tp - len..tp}" + using lassms(1,2) a2_map'_keys tp'_neq by (auto intro!: Mapping_keys_intro) + obtain m where m_def: "Mapping.lookup a2_map tp' = Some m" + "m' = upd_set' m new_tstp (max_tstp new_tstp) {b. (tp', b) \ tmp}" + using lassms(2)[unfolded a2_map'_def Mapping.lookup_update_neq[OF tp'_neq] + upd_nested_lookup] tp'_in a2_map_keys + by (fastforce dest: Mapping_keys_dest intro: Mapping_keys_intro split: option.splits) + have "xs \ {b. (tp', b) \ tmp}" + proof (rule ccontr) + assume "xs \ {b. (tp', b) \ tmp}" + then have Some: "Mapping.lookup m xs = Some tstp" + using lassms(3)[unfolded m_def(2) upd_set'_lookup] by auto + show "False" + using lookup_a2_map'[OF m_def(1) Some] lassms(4) + by (auto simp add: tstp_lt_def ts_tp_lt'_def split: sum.splits) + qed + then show "xs \ rel2" + unfolding tmp_def by (auto split: option.splits if_splits) + qed + moreover have "\xs. xs \ rel2 \ \m' tstp. Mapping.lookup a2_map' tp = Some m' \ + Mapping.lookup m' xs = Some tstp \ ts_tp_lt' nt tp tstp" + proof - + fix xs + assume lassms: "xs \ rel2" + obtain m' where m'_def: "Mapping.lookup a2_map' tp = Some m'" + using a2_map'_keys by (fastforce dest: Mapping_keys_dest) + have tp_neq: "tp + 1 \ tp" + by auto + obtain m where m_def: "Mapping.lookup a2_map tp = Some m" + "m' = upd_set' m new_tstp (max_tstp new_tstp) {b. (tp, b) \ tmp}" + using m'_def a2_map_keys unfolding a2_map'_def Mapping.lookup_update_neq[OF tp_neq] + upd_nested_lookup + by (auto dest: Mapping_keys_dest split: option.splits if_splits) + (metis Mapping_keys_dest atLeastAtMost_iff diff_le_self le_eq_less_or_eq + option.simps(3)) + have xs_in_tmp: "xs \ {b. (tp, b) \ tmp}" + using lassms left_I_zero unfolding tmp_def by auto + show "\m' tstp. Mapping.lookup a2_map' tp = Some m' \ + Mapping.lookup m' xs = Some tstp \ ts_tp_lt' nt tp tstp" + proof (cases "Mapping.lookup m xs") + case None + moreover have "Mapping.lookup m' xs = Some new_tstp" + using xs_in_tmp unfolding m_def(2) upd_set'_lookup None by auto + moreover have "ts_tp_lt' nt tp new_tstp" + using left_I_zero new_tstp_def by (auto simp add: ts_tp_lt'_def) + ultimately show ?thesis + using xs_in_tmp m_def + unfolding a2_map'_def Mapping.lookup_update_neq[OF tp_neq] upd_nested_lookup by auto + next + case (Some tstp') + moreover have "Mapping.lookup m' xs = Some (max_tstp new_tstp tstp')" + using xs_in_tmp unfolding m_def(2) upd_set'_lookup Some by auto + moreover have "ts_tp_lt' nt tp (max_tstp new_tstp tstp')" + using max_tstpE[of new_tstp tstp'] lookup_a2_map'[OF m_def(1) Some] new_tstp_lt_isl left_I_zero + by (auto simp add: sum.discI(1) new_tstp_def ts_tp_lt'_def tstp_lt_def split: sum.splits) + ultimately show ?thesis + using xs_in_tmp m_def + unfolding a2_map'_def Mapping.lookup_update_neq[OF tp_neq] upd_nested_lookup by auto + qed + qed + ultimately show ?thesis + using True by (fastforce simp add: filter_a2_map_def split: option.splits) + next + case False + note left_I_pos = False + have "\tp' m xs tstp. tp' \ tp \ Mapping.lookup a2_map' tp' = Some m \ + Mapping.lookup m xs = Some tstp \ \(ts_tp_lt' nt tp tstp)" + proof - + fix tp' m' xs tstp + assume lassms: "tp' \ tp" "Mapping.lookup a2_map' tp' = Some m'" + "Mapping.lookup m' xs = Some tstp" + from lassms(1) have tp'_neq_Suc_tp: "tp + 1 \ tp'" + by auto + show "\(ts_tp_lt' nt tp tstp)" + proof (cases "Mapping.lookup a2_map tp'") + case None + then have tp'_in_tmp: "tp' \ fst ` tmp" and + m'_alt: "m' = upd_set' Mapping.empty new_tstp (max_tstp new_tstp) {b. (tp', b) \ tmp}" + using lassms(2) unfolding a2_map'_def Mapping.lookup_update_neq[OF tp'_neq_Suc_tp] + upd_nested_lookup by (auto split: if_splits) + then have "tstp = new_tstp" + using lassms(3)[unfolded m'_alt upd_set'_lookup] + by (auto simp add: Mapping.lookup_empty split: if_splits) + then show ?thesis + using False by (auto simp add: ts_tp_lt'_def new_tstp_def split: if_splits sum.splits) + next + case (Some m) + then have m'_alt: "m' = upd_set' m new_tstp (max_tstp new_tstp) {b. (tp', b) \ tmp}" + using lassms(2) unfolding a2_map'_def Mapping.lookup_update_neq[OF tp'_neq_Suc_tp] + upd_nested_lookup by auto + note lookup_a2_map_tp' = Some + show ?thesis + proof (cases "Mapping.lookup m xs") + case None + then have "tstp = new_tstp" + using lassms(3) unfolding m'_alt upd_set'_lookup by (auto split: if_splits) + then show ?thesis + using False by (auto simp add: ts_tp_lt'_def new_tstp_def split: if_splits sum.splits) + next + case (Some tstp') + show ?thesis + proof (cases "xs \ {b. (tp', b) \ tmp}") + case True + then have tstp_eq: "tstp = max_tstp new_tstp tstp'" + using lassms(3) + unfolding m'_alt upd_set'_lookup Some by auto + show ?thesis + using max_tstpE[of new_tstp tstp'] lookup_a2_map'[OF lookup_a2_map_tp' Some] new_tstp_lt_isl left_I_pos + by (auto simp add: tstp_eq tstp_lt_def ts_tp_lt'_def split: sum.splits) + next + case False + then show ?thesis + using lassms(3) lookup_a2_map'[OF lookup_a2_map_tp' Some] + unfolding m'_alt upd_set'_lookup Some + by (auto simp add: ts_tp_lt'_def tstp_lt_def split: sum.splits) + qed + qed + qed + qed + then show ?thesis + using False by (auto simp add: filter_a2_map_def empty_table_def split: option.splits) + qed + have zip_dist: "zip (linearize tss @ [nt]) ([tp - len..x y. triple_eq_pair x y (\tp'. filter_a1_map pos tp' a1_map') + (\ts' tp'. filter_a2_map I ts' tp' a2_map')) + (drop (length done) (update_until args rel1 rel2 nt auxlist)) + (zip (linearize tss') [tp + 1 - (len + 1)..x y. triple_eq_pair x y f g) xs (zip ys zs) \ + (\y. y \ set ys \ \enat y + right I < nt) \ x \ set xs \ \check_before I nt x" + by (auto simp: in_set_zip elim!: list_all2_in_setE triple_eq_pair.elims) + +fun eval_mmuaux :: "args \ ts \ 'a mmuaux \ 'a table list \ 'a mmuaux" where + "eval_mmuaux args nt aux = + (let (tp, tss, len, maskL, maskR, a1_map, a2_map, done, done_length) = + shift_mmuaux args nt aux in + (rev done, (tp, tss, len, maskL, maskR, a1_map, a2_map, [], 0)))" + +lemma valid_eval_mmuaux: + assumes "valid_mmuaux args cur aux auxlist" "nt \ cur" + "eval_mmuaux args nt aux = (res, aux')" "eval_until (args_ivl args) nt auxlist = (res', auxlist')" + shows "res = res' \ valid_mmuaux args cur aux' auxlist'" +proof - + define I where "I = args_ivl args" + define pos where "pos = args_pos args" + have valid_folded: "valid_mmuaux' args cur nt aux auxlist" + using assms(1,2) valid_mmuaux'_mono unfolding valid_mmuaux_def by blast + obtain tp len tss maskL maskR a1_map a2_map "done" done_length where shift_aux_def: + "shift_mmuaux args nt aux = (tp, tss, len, maskL, maskR, a1_map, a2_map, done, done_length)" + by (cases "shift_mmuaux args nt aux") auto + have valid_shift_aux: "valid_mmuaux' args cur nt (tp, tss, len, maskL, maskR, + a1_map, a2_map, done, done_length) auxlist" + "\ts. ts \ set (linearize tss) \ \enat ts + right (args_ivl args) < enat nt" + using valid_shift_mmuaux'[OF assms(1)[unfolded valid_mmuaux_def] assms(2)] + unfolding shift_aux_def by auto + have len_done_auxlist: "length done \ length auxlist" + using valid_shift_aux by auto + have list_all: "\x. x \ set (take (length done) auxlist) \ check_before I nt x" + using valid_shift_aux unfolding I_def by auto + have set_drop_auxlist: "\x. x \ set (drop (length done) auxlist) \ \check_before I nt x" + using valid_shift_aux[unfolded valid_mmuaux'.simps] + list_all2_check_before[OF _ valid_shift_aux(2)] unfolding I_def by fast + have take_auxlist_takeWhile: "take (length done) auxlist = takeWhile (check_before I nt) auxlist" + using len_done_auxlist list_all set_drop_auxlist + by (rule take_takeWhile) assumption+ + have rev_done: "rev done = map proj_thd (take (length done) auxlist)" + using valid_shift_aux by auto + then have res'_def: "res' = rev done" + using eval_until_res[OF assms(4)] unfolding take_auxlist_takeWhile I_def by auto + then have auxlist'_def: "auxlist' = drop (length done) auxlist" + using eval_until_auxlist'[OF assms(4)] by auto + have eval_mmuaux_eq: "eval_mmuaux args nt aux = (rev done, (tp, tss, len, maskL, maskR, + a1_map, a2_map, [], 0))" + using shift_aux_def by auto + show ?thesis + using assms(3) done_empty_valid_mmuaux'_intro[OF valid_shift_aux(1)] + unfolding shift_aux_def eval_mmuaux_eq pos_def auxlist'_def res'_def valid_mmuaux_def by auto +qed + +definition init_mmuaux :: "args \ 'a mmuaux" where + "init_mmuaux args = (0, empty_queue, 0, + join_mask (args_n args) (args_L args), join_mask (args_n args) (args_R args), + Mapping.empty, Mapping.update 0 Mapping.empty Mapping.empty, [], 0)" + +lemma valid_init_mmuaux: "L \ R \ valid_mmuaux (init_args I n L R b) 0 + (init_mmuaux (init_args I n L R b)) []" + unfolding init_mmuaux_def valid_mmuaux_def + by (auto simp add: init_args_def empty_queue_rep table_def Mapping.lookup_update) + +fun length_mmuaux :: "args \ 'a mmuaux \ nat" where + "length_mmuaux args (tp, tss, len, maskL, maskR, a1_map, a2_map, done, done_length) = + len + done_length" + +lemma valid_length_mmuaux: + assumes "valid_mmuaux args cur aux auxlist" + shows "length_mmuaux args aux = length auxlist" + using assms by (cases aux) (auto simp add: valid_mmuaux_def dest: list_all2_lengthD) + +end \ No newline at end of file diff --git a/thys/MFODL_Monitor_Optimized/ROOT b/thys/MFODL_Monitor_Optimized/ROOT new file mode 100644 --- /dev/null +++ b/thys/MFODL_Monitor_Optimized/ROOT @@ -0,0 +1,26 @@ +chapter AFP + +session MFODL_Monitor_Optimized (AFP) = Containers + + options [timeout = 1200] + sessions + IEEE_Floating_Point + Generic_Join + theories + Code_Double + Event_Data + Trace + Regex + Interval + Formula + Abstract_Monitor + Optimized_Join + Monitor + Optimized_MTL + Monitor_Impl + theories [condition=ISABELLE_OCAMLFIND, document=false] + Monitor_Code + document_files + "root.tex" + "root.bib" + export_files (in ".") [2] + "MFODL_Monitor_Optimized.Monitor_Code:code/**" diff --git a/thys/MFODL_Monitor_Optimized/Regex.thy b/thys/MFODL_Monitor_Optimized/Regex.thy new file mode 100644 --- /dev/null +++ b/thys/MFODL_Monitor_Optimized/Regex.thy @@ -0,0 +1,369 @@ +(*<*) +theory Regex + imports Trace "HOL-Library.Lattice_Syntax" "HOL-Library.Extended_Nat" +begin +(*>*) + +section \Regular expressions\ + +context begin + +qualified datatype (atms: 'a) regex = Skip nat | Test 'a + | Plus "'a regex" "'a regex" | Times "'a regex" "'a regex" | Star "'a regex" + +lemma finite_atms[simp]: "finite (atms r)" + by (induct r) auto + +definition "Wild = Skip 1" + +lemma size_regex_estimation[termination_simp]: "x \ atms r \ y < f x \ y < size_regex f r" + by (induct r) auto + +lemma size_regex_estimation'[termination_simp]: "x \ atms r \ y \ f x \ y \ size_regex f r" + by (induct r) auto + +qualified definition "TimesL r S = Times r ` S" +qualified definition "TimesR R s = (\r. Times r s) ` R" + +qualified primrec fv_regex where + "fv_regex fv (Skip n) = {}" +| "fv_regex fv (Test \) = fv \" +| "fv_regex fv (Plus r s) = fv_regex fv r \ fv_regex fv s" +| "fv_regex fv (Times r s) = fv_regex fv r \ fv_regex fv s" +| "fv_regex fv (Star r) = fv_regex fv r" + +lemma fv_regex_cong[fundef_cong]: + "r = r' \ (\z. z \ atms r \ fv z = fv' z) \ fv_regex fv r = fv_regex fv' r'" + by (induct r arbitrary: r') auto + +lemma finite_fv_regex[simp]: "(\z. z \ atms r \ finite (fv z)) \ finite (fv_regex fv r)" + by (induct r) auto + +lemma fv_regex_commute: + "(\z. z \ atms r \ x \ fv z \ g x \ fv' z) \ x \ fv_regex fv r \ g x \ fv_regex fv' r" + by (induct r) auto + +lemma fv_regex_alt: "fv_regex fv r = (\z \ atms r. fv z)" + by (induct r) auto + +qualified definition nfv_regex where + "nfv_regex fv r = Max (insert 0 (Suc ` fv_regex fv r))" + +lemma insert_Un: "insert x (A \ B) = insert x A \ insert x B" + by auto + +lemma nfv_regex_simps[simp]: + assumes [simp]: "(\z. z \ atms r \ finite (fv z))" "(\z. z \ atms s \ finite (fv z))" + shows + "nfv_regex fv (Skip n) = 0" + "nfv_regex fv (Test \) = Max (insert 0 (Suc ` fv \))" + "nfv_regex fv (Plus r s) = max (nfv_regex fv r) (nfv_regex fv s)" + "nfv_regex fv (Times r s) = max (nfv_regex fv r) (nfv_regex fv s)" + "nfv_regex fv (Star r) = nfv_regex fv r" + unfolding nfv_regex_def + by (auto simp add: image_Un Max_Un insert_Un simp del: Un_insert_right Un_insert_left) + +abbreviation "min_regex_default f r j \ (if atms r = {} then j else Min ((\z. f z j) ` atms r))" + +qualified primrec match :: "(nat \ 'a \ bool) \ 'a regex \ nat \ nat \ bool" where + "match test (Skip n) = (\i j. j = i + n)" +| "match test (Test \) = (\i j. i = j \ test i \)" +| "match test (Plus r s) = match test r \ match test s" +| "match test (Times r s) = match test r OO match test s" +| "match test (Star r) = (match test r)\<^sup>*\<^sup>*" + +lemma match_cong[fundef_cong]: + "r = r' \ (\i z. z \ atms r \ t i z = t' i z) \ match t r = match t' r'" + by (induct r arbitrary: r') auto + +qualified primrec eps where + "eps test i (Skip n) = (n = 0)" +| "eps test i (Test \) = test i \" +| "eps test i (Plus r s) = (eps test i r \ eps test i s)" +| "eps test i (Times r s) = (eps test i r \ eps test i s)" +| "eps test i (Star r) = True" + +qualified primrec lpd where + "lpd test i (Skip n) = (case n of 0 \ {} | Suc m \ {Skip m})" +| "lpd test i (Test \) = {}" +| "lpd test i (Plus r s) = (lpd test i r \ lpd test i s)" +| "lpd test i (Times r s) = TimesR (lpd test i r) s \ (if eps test i r then lpd test i s else {})" +| "lpd test i (Star r) = TimesR (lpd test i r) (Star r)" + +qualified primrec lpd\ where + "lpd\ \ test i (Skip n) = (case n of 0 \ {} | Suc m \ {\ (Skip m)})" +| "lpd\ \ test i (Test \) = {}" +| "lpd\ \ test i (Plus r s) = lpd\ \ test i r \ lpd\ \ test i s" +| "lpd\ \ test i (Times r s) = lpd\ (\t. \ (Times t s)) test i r \ (if eps test i r then lpd\ \ test i s else {})" +| "lpd\ \ test i (Star r) = lpd\ (\t. \ (Times t (Star r))) test i r" + +qualified primrec rpd where + "rpd test i (Skip n) = (case n of 0 \ {} | Suc m \ {Skip m})" +| "rpd test i (Test \) = {}" +| "rpd test i (Plus r s) = (rpd test i r \ rpd test i s)" +| "rpd test i (Times r s) = TimesL r (rpd test i s) \ (if eps test i s then rpd test i r else {})" +| "rpd test i (Star r) = TimesL (Star r) (rpd test i r)" + +qualified primrec rpd\ where + "rpd\ \ test i (Skip n) = (case n of 0 \ {} | Suc m \ {\ (Skip m)})" +| "rpd\ \ test i (Test \) = {}" +| "rpd\ \ test i (Plus r s) = rpd\ \ test i r \ rpd\ \ test i s" +| "rpd\ \ test i (Times r s) = rpd\ (\t. \ (Times r t)) test i s \ (if eps test i s then rpd\ \ test i r else {})" +| "rpd\ \ test i (Star r) = rpd\ (\t. \ (Times (Star r) t)) test i r" + +lemma lpd\_lpd: "lpd\ \ test i r = \ ` lpd test i r" + by (induct r arbitrary: \) (auto simp: TimesR_def split: nat.splits) + +lemma rpd\_rpd: "rpd\ \ test i r = \ ` rpd test i r" + by (induct r arbitrary: \) (auto simp: TimesL_def split: nat.splits) + +lemma match_le: "match test r i j \ i \ j" +proof (induction r arbitrary: i j) + case (Times r s) + then show ?case using order.trans by fastforce +next + case (Star r) + from Star.prems show ?case + unfolding match.simps by (induct i j rule: rtranclp.induct) (force dest: Star.IH)+ +qed auto + +lemma match_rtranclp_le: "(match test r)\<^sup>*\<^sup>* i j \ i \ j" + by (metis match.simps(5) match_le) + +lemma eps_match: "eps test i r \ match test r i i" + by (induction r) (auto dest: antisym[OF match_le match_le]) + +lemma lpd_match: "i < j \ match test r i j \ (\s \ lpd test i r. match test s) (i + 1) j" +proof (induction r arbitrary: i j) + case (Times r s) + have "match test (Times r s) i j \ (\k. match test r i k \ match test s k j)" + by auto + also have "\ \ match test r i i \ match test s i j \ + (\k>i. match test r i k \ match test s k j)" + using match_le[of test r i] nat_less_le by auto + also have "\ \ match test r i i \ (\t \ lpd test i s. match test t) (i + 1) j \ + (\k>i. (\t \ lpd test i r. match test t) (i + 1) k \ match test s k j)" + using Times.IH(1) Times.IH(2)[OF Times.prems] by metis + also have "\ \ match test r i i \ (\t \ lpd test i s. match test t) (i + 1) j \ + (\k. (\t \ lpd test i r. match test t) (i + 1) k \ match test s k j)" + using Times.prems by (intro disj_cong[OF refl] iff_exI) (auto dest: match_le) + also have "\ \ (\ (match test ` lpd test i (Times r s))) (i + 1) j" + by (force simp: TimesL_def TimesR_def eps_match) + finally show ?case . +next + case (Star r) + have "\s\lpd test i r. (match test s OO (match test r)\<^sup>*\<^sup>*) (i + 1) j" if "(match test r)\<^sup>*\<^sup>* i j" + using that Star.prems match_le[of test _ "i + 1"] + proof (induct rule: converse_rtranclp_induct) + case (step i k) + then show ?case + by (cases "i < k") (auto simp: not_less Star.IH dest: match_le) + qed simp + with Star.prems show ?case using match_le[of test _ "i + 1"] + by (auto simp: TimesL_def TimesR_def Suc_le_eq Star.IH[of i] + elim!: converse_rtranclp_into_rtranclp[rotated]) +qed (auto split: nat.splits) + +lemma rpd_match: "i < j \ match test r i j \ (\s \ rpd test j r. match test s) i (j - 1)" +proof (induction r arbitrary: i j) + case (Times r s) + have "match test (Times r s) i j \ (\k. match test r i k \ match test s k j)" + by auto + also have "\ \ match test r i j \ match test s j j \ + (\k match test s k j)" + using match_le[of test s _ j] nat_less_le by auto + also have "\ \ (\t \ rpd test j r. match test t) i (j - 1) \ match test s j j \ + (\k (\t \ rpd test j s. match test t) k (j - 1))" + using Times.IH(1)[OF Times.prems] Times.IH(2) by metis + also have "\ \ (\t \ rpd test j r. match test t) i (j - 1) \ match test s j j \ + (\k. match test r i k \ (\t \ rpd test j s. match test t) k (j - 1))" + using Times.prems by (intro disj_cong[OF refl] iff_exI) (auto dest: match_le) + also have "\ \ (\ (match test ` rpd test j (Times r s))) i (j - 1)" + by (force simp: TimesL_def TimesR_def eps_match) + finally show ?case . +next + case (Star r) + have "\s\rpd test j r. ((match test r)\<^sup>*\<^sup>* OO match test s) i (j - 1)" if "(match test r)\<^sup>*\<^sup>* i j" + using that Star.prems match_le[of test _ _ "j - 1"] + proof (induct rule: rtranclp_induct) + case (step k j) + then show ?case + by (cases "k < j") (auto simp: not_less Star.IH dest: match_le) + qed simp + with Star.prems show ?case + by (auto 0 3 simp: TimesL_def TimesR_def intro: Star.IH[of _ j, THEN iffD2] + elim!: rtranclp.rtrancl_into_rtrancl dest: match_le[of test _ _ "j - 1", unfolded One_nat_def]) +qed (auto split: nat.splits) + +lemma lpd_fv_regex: "s \ lpd test i r \ fv_regex fv s \ fv_regex fv r" + by (induct r arbitrary: s) (auto simp: TimesR_def TimesL_def split: if_splits nat.splits)+ + +lemma rpd_fv_regex: "s \ rpd test i r \ fv_regex fv s \ fv_regex fv r" + by (induct r arbitrary: s) (auto simp: TimesR_def TimesL_def split: if_splits nat.splits)+ + +lemma match_fv_cong: + "(\i x. x \ atms r \ test i x = test' i x) \ match test r = match test' r" + by (induct r) auto + +lemma eps_fv_cong: + "(\i x. x \ atms r \ test i x = test' i x) \ eps test i r = eps test' i r" + by (induct r) auto + +datatype modality = Past | Futu +datatype safety = Strict | Lax + +context + fixes fv :: "'a \ 'b set" + and safe :: "safety \ 'a \ bool" +begin + +qualified fun safe_regex :: "modality \ safety \ 'a regex \ bool" where + "safe_regex m _ (Skip n) = True" +| "safe_regex m g (Test \) = safe g \" +| "safe_regex m g (Plus r s) = ((g = Lax \ fv_regex fv r = fv_regex fv s) \ safe_regex m g r \ safe_regex m g s)" +| "safe_regex Futu g (Times r s) = + ((g = Lax \ fv_regex fv r \ fv_regex fv s) \ safe_regex Futu g s \ safe_regex Futu Lax r)" +| "safe_regex Past g (Times r s) = + ((g = Lax \ fv_regex fv s \ fv_regex fv r) \ safe_regex Past g r \ safe_regex Past Lax s)" +| "safe_regex m g (Star r) = ((g = Lax \ fv_regex fv r = {}) \ safe_regex m g r)" + +lemmas safe_regex_induct = safe_regex.induct[case_names Skip Test Plus TimesF TimesP Star] + +lemma safe_cosafe: + "(\x. x \ atms r \ safe Strict x \ safe Lax x) \ safe_regex m Strict r \ safe_regex m Lax r" + by (induct r; cases m) auto + +lemma safe_lpd_fv_regex_le: "safe_regex Futu Strict r \ s \ lpd test i r \ fv_regex fv r \ fv_regex fv s" + by (induct r) (auto simp: TimesR_def split: if_splits) + +lemma safe_lpd_fv_regex: "safe_regex Futu Strict r \ s \ lpd test i r \ fv_regex fv s = fv_regex fv r" + by (simp add: eq_iff lpd_fv_regex safe_lpd_fv_regex_le) + +lemma cosafe_lpd: "safe_regex Futu Lax r \ s \ lpd test i r \ safe_regex Futu Lax s" +proof (induct r arbitrary: s) + case (Plus r1 r2) + from Plus(3,4) show ?case + by (auto elim: Plus(1,2)) +next + case (Times r1 r2) + from Times(3,4) show ?case + by (auto simp: TimesR_def elim: Times(1,2) split: if_splits) +qed (auto simp: TimesR_def split: nat.splits) + +lemma safe_lpd: "(\x \ atms r. safe Strict x \ safe Lax x) \ + safe_regex Futu Strict r \ s \ lpd test i r \ safe_regex Futu Strict s" +proof (induct r arbitrary: s) + case (Plus r1 r2) + from Plus(3,4,5) show ?case + by (auto elim: Plus(1,2) simp: ball_Un) +next + case (Times r1 r2) + from Times(3,4,5) show ?case + by (force simp: TimesR_def ball_Un elim: Times(1,2) cosafe_lpd dest: lpd_fv_regex split: if_splits) +next + case (Star r) + from Star(2,3,4) show ?case + by (force simp: TimesR_def elim: Star(1) cosafe_lpd + dest: safe_cosafe[rotated] lpd_fv_regex[where fv=fv] split: if_splits) +qed (auto split: nat.splits) + +lemma safe_rpd_fv_regex_le: "safe_regex Past Strict r \ s \ rpd test i r \ fv_regex fv r \ fv_regex fv s" + by (induct r) (auto simp: TimesL_def split: if_splits) + +lemma safe_rpd_fv_regex: "safe_regex Past Strict r \ s \ rpd test i r \ fv_regex fv s = fv_regex fv r" + by (simp add: eq_iff rpd_fv_regex safe_rpd_fv_regex_le) + +lemma cosafe_rpd: "safe_regex Past Lax r \ s \ rpd test i r \ safe_regex Past Lax s" +proof (induct r arbitrary: s) + case (Plus r1 r2) + from Plus(3,4) show ?case + by (auto elim: Plus(1,2)) +next + case (Times r1 r2) + from Times(3,4) show ?case + by (auto simp: TimesL_def elim: Times(1,2) split: if_splits) +qed (auto simp: TimesL_def split: nat.splits) + +lemma safe_rpd: "(\x \ atms r. safe Strict x \ safe Lax x) \ + safe_regex Past Strict r \ s \ rpd test i r \ safe_regex Past Strict s" +proof (induct r arbitrary: s) + case (Plus r1 r2) + from Plus(3,4,5) show ?case + by (auto elim: Plus(1,2) simp: ball_Un) +next + case (Times r1 r2) + from Times(3,4,5) show ?case + by (force simp: TimesL_def ball_Un elim: Times(1,2) cosafe_rpd dest: rpd_fv_regex split: if_splits) +next + case (Star r) + from Star(2,3,4) show ?case + by (force simp: TimesL_def elim: Star(1) cosafe_rpd + dest: safe_cosafe[rotated] rpd_fv_regex[where fv=fv] split: if_splits) +qed (auto split: nat.splits) + +lemma safe_regex_safe: "(\g r. safe g r \ safe Lax r) \ + safe_regex m g r \ x \ atms r \ safe Lax x" + by (induct m g r rule: safe_regex.induct) auto + +lemma safe_regex_map_regex: + "(\g x. x \ atms r \ safe g x \ safe g (f x)) \ (\x. x \ atms r \ fv (f x) = fv x) \ + safe_regex m g r \ safe_regex m g (map_regex f r)" + by (induct m g r rule: safe_regex.induct) (auto simp: fv_regex_alt regex.set_map) + +end + +lemma safe_regex_cong[fundef_cong]: + "(\g x. x \ atms r \ safe g x = safe' g x) \ + Regex.safe_regex fv safe m g r = Regex.safe_regex fv safe' m g r" + by (induct m g r rule: safe_regex.induct) auto + +lemma safe_regex_mono: + "(\g x. x \ atms r \ safe g x \ safe' g x) \ + Regex.safe_regex fv safe m g r \ Regex.safe_regex fv safe' m g r" + by (induct m g r rule: safe_regex.induct) auto + +lemma match_map_regex: "match t (map_regex f r) = match (\k z. t k (f z)) r" + by (induct r) auto + +lemma match_cong_strong: + "(\k z. k \ {i ..< j + 1} \ z \ atms r \ t k z = t' k z) \ match t r i j = match t' r i j" +proof (induction r arbitrary: i j) + case (Times r s) + from Times.prems show ?case + by (auto 0 4 simp: relcompp_apply intro: le_less_trans match_le less_Suc_eq_le + dest: Times.IH[THEN iffD1, rotated -1] Times.IH[THEN iffD2, rotated -1] match_le) +next + case (Star r) + show ?case unfolding match.simps + proof (rule iffI) + assume *: "(match t r)\<^sup>*\<^sup>* i j" + then have "i \ j" unfolding match.simps(5)[symmetric] + by (rule match_le) + with * show "(match t' r)\<^sup>*\<^sup>* i j" using Star.prems + proof (induction i j rule: rtranclp.induct) + case (rtrancl_into_rtrancl a b c) + from rtrancl_into_rtrancl(1,2,4,5) show ?case + by (intro rtranclp.rtrancl_into_rtrancl[OF rtrancl_into_rtrancl.IH]) + (auto dest!: Star.IH[THEN iffD1, rotated -1] + dest: match_le match_rtranclp_le simp: less_Suc_eq_le) + qed simp + next + assume *: "(match t' r)\<^sup>*\<^sup>* i j" + then have "i \ j" unfolding match.simps(5)[symmetric] + by (rule match_le) + with * show "(match t r)\<^sup>*\<^sup>* i j" using Star.prems + proof (induction i j rule: rtranclp.induct) + case (rtrancl_into_rtrancl a b c) + from rtrancl_into_rtrancl(1,2,4,5) show ?case + by (intro rtranclp.rtrancl_into_rtrancl[OF rtrancl_into_rtrancl.IH]) + (auto dest!: Star.IH[THEN iffD2, rotated -1] + dest: match_le match_rtranclp_le simp: less_Suc_eq_le) + qed simp + qed +qed auto + +end + +(*<*) +end +(*>*) diff --git a/thys/MFODL_Monitor_Optimized/Trace.thy b/thys/MFODL_Monitor_Optimized/Trace.thy new file mode 100644 --- /dev/null +++ b/thys/MFODL_Monitor_Optimized/Trace.thy @@ -0,0 +1,302 @@ +(*<*) +theory Trace + imports "HOL-Library.Stream" +begin +(*>*) + +section \Traces and trace prefixes\ + +subsection \Infinite traces\ + +coinductive ssorted :: "'a :: linorder stream \ bool" where + "shd s \ shd (stl s) \ ssorted (stl s) \ ssorted s" + +lemma ssorted_siterate[simp]: "(\n. n \ f n) \ ssorted (siterate f n)" + by (coinduction arbitrary: n) auto + +lemma ssortedD: "ssorted s \ s !! i \ stl s !! i" + by (induct i arbitrary: s) (auto elim: ssorted.cases) + +lemma ssorted_sdrop: "ssorted s \ ssorted (sdrop i s)" + by (coinduction arbitrary: i s) (auto elim: ssorted.cases ssortedD) + +lemma ssorted_monoD: "ssorted s \ i \ j \ s !! i \ s !! j" +proof (induct "j - i" arbitrary: j) + case (Suc x) + from Suc(1)[of "j - 1"] Suc(2-4) ssortedD[of s "j - 1"] + show ?case by (cases j) (auto simp: le_Suc_eq Suc_diff_le) +qed simp + +lemma sorted_stake: "ssorted s \ sorted (stake i s)" + by (induct i arbitrary: s) + (auto elim: ssorted.cases simp: in_set_conv_nth + intro!: ssorted_monoD[of _ 0, simplified, THEN order_trans, OF _ ssortedD]) + +lemma ssorted_monoI: "\i j. i \ j \ s !! i \ s !! j \ ssorted s" + by (coinduction arbitrary: s) + (auto dest: spec2[of _ "Suc _" "Suc _"] spec2[of _ 0 "Suc 0"]) + +lemma ssorted_iff_mono: "ssorted s \ (\i j. i \ j \ s !! i \ s !! j)" + using ssorted_monoI ssorted_monoD by metis + +definition "sincreasing s = (\i. \j>i. s !! i < s !! j)" + +lemma sincreasing_siterate[simp]: + assumes "(\n. n < f n)" + shows "sincreasing (siterate f n)" +unfolding sincreasing_def proof + fix i + show "\j>i. siterate f n !! i < siterate f n !! j" (is "\j. ?P n i j") + proof (induct i arbitrary: n) + case (Suc i) + from Suc[of "f n"] obtain j where "?P (f n) i j" by blast + then show ?case + by (intro exI[of _ "Suc j"]) auto + qed (auto intro!: exI[of _ "Suc 0"] assms) +qed + +typedef 'a trace = "{s :: ('a set \ nat) stream. ssorted (smap snd s) \ sincreasing (smap snd s)}" + by (intro exI[of _ "smap (\i. ({}, i)) nats"]) + (auto simp: stream.map_comp stream.map_ident cong: stream.map_cong) + +setup_lifting type_definition_trace + +lift_definition \ :: "'a trace \ nat \ 'a set" is + "\s i. fst (s !! i)" . +lift_definition \ :: "'a trace \ nat \ nat" is + "\s i. snd (s !! i)" . + +lemma \_mono[simp]: "i \ j \ \ s i \ \ s j" + by transfer (auto simp: ssorted_iff_mono) + +lemma ex_le_\: "\j\i. x \ \ s j" +proof (transfer fixing: i x) + fix s :: "('a set \ nat) stream" + presume sincreasing: "sincreasing (smap snd s)" + show "\j\i. x \ snd (s !! j)" proof (induction x) + case 0 + show ?case by auto + next + case (Suc x) + then show ?case + using sincreasing unfolding sincreasing_def + by (metis Suc_le_eq le_less_trans less_imp_le_nat snth_smap) + qed +qed simp + +lemma le_\_less: "\ \ i \ \ \ j \ j < i \ \ \ i = \ \ j" + by (simp add: antisym) + +lemma less_\D: "\ \ i < \ \ j \ i < j" + by (meson \_mono less_le_not_le not_le_imp_less) + +abbreviation "\ s i \ \ s i - \ s (i - 1)" + +lift_definition map_\ :: "('a set \ 'b set) \ 'a trace \ 'b trace" is + "\f s. smap (\(x, i). (f x, i)) s" + by (auto simp: stream.map_comp prod.case_eq_if cong: stream.map_cong) + +lemma \_map_\[simp]: "\ (map_\ f s) i = f (\ s i)" + by transfer (simp add: prod.case_eq_if) + +lemma \_map_\[simp]: "\ (map_\ f s) i = \ s i" + by transfer (simp add: prod.case_eq_if) + +lemma map_\_id[simp]: "map_\ id s = s" + by transfer (simp add: stream.map_id) + +lemma map_\_comp: "map_\ g (map_\ f s) = map_\ (g \ f) s" + by transfer (simp add: stream.map_comp comp_def prod.case_eq_if case_prod_beta') + +lemma map_\_cong: "\\<^sub>1 = \\<^sub>2 \ (\x. f\<^sub>1 x = f\<^sub>2 x) \ map_\ f\<^sub>1 \\<^sub>1 = map_\ f\<^sub>2 \\<^sub>2" + by transfer (auto intro!: stream.map_cong) + + +subsection \Finite trace prefixes\ + +typedef 'a prefix = "{p :: ('a set \ nat) list. sorted (map snd p)}" + by (auto intro!: exI[of _ "[]"]) + +setup_lifting type_definition_prefix + +lift_definition last_ts :: "'a prefix \ nat" is + "\p. (case p of [] \ 0 | _ \ snd (last p))" . + +lift_definition first_ts :: "nat \ 'a prefix \ nat" is + "\n p. (case p of [] \ n | _ \ snd (hd p))" . + +lift_definition pnil :: "'a prefix" is "[]" by simp + +lift_definition plen :: "'a prefix \ nat" is "length" . + +lift_definition psnoc :: "'a prefix \ 'a set \ nat \ 'a prefix" is + "\p x. if (case p of [] \ 0 | _ \ snd (last p)) \ snd x then p @ [x] else []" +proof (goal_cases sorted_psnoc) + case (sorted_psnoc p x) + then show ?case + by (induction p) (auto split: if_splits list.splits) +qed + +instantiation prefix :: (type) order begin + +lift_definition less_eq_prefix :: "'a prefix \ 'a prefix \ bool" is + "\p q. \r. q = p @ r" . + +definition less_prefix :: "'a prefix \ 'a prefix \ bool" where + "less_prefix x y = (x \ y \ \ y \ x)" + +instance +proof (standard, goal_cases less refl trans antisym) + case (less x y) + then show ?case unfolding less_prefix_def .. +next + case (refl x) + then show ?case by transfer auto +next + case (trans x y z) + then show ?case by transfer auto +next + case (antisym x y) + then show ?case by transfer auto +qed + +end + +lemma psnoc_inject[simp]: + "last_ts p \ snd x \ last_ts q \ snd y \ psnoc p x = psnoc q y \ (p = q \ x = y)" + by transfer auto + +lift_definition prefix_of :: "'a prefix \ 'a trace \ bool" is "\p s. stake (length p) s = p" . + +lemma prefix_of_pnil[simp]: "prefix_of pnil \" + by transfer auto + +lemma plen_pnil[simp]: "plen pnil = 0" + by transfer auto + +lemma plen_mono: "\ \ \' \ plen \ \ plen \'" + by transfer auto + +lemma prefix_of_psnocE: "prefix_of (psnoc p x) s \ last_ts p \ snd x \ + (prefix_of p s \ \ s (plen p) = fst x \ \ s (plen p) = snd x \ P) \ P" + by transfer (simp del: stake.simps add: stake_Suc) + +lemma le_pnil[simp]: "pnil \ \" + by transfer auto + +lift_definition take_prefix :: "nat \ 'a trace \ 'a prefix" is stake + by (auto dest: sorted_stake) + +lemma plen_take_prefix[simp]: "plen (take_prefix i \) = i" + by transfer auto + +lemma plen_psnoc[simp]: "last_ts \ \ snd x \ plen (psnoc \ x) = plen \ + 1" + by transfer auto + +lemma prefix_of_take_prefix[simp]: "prefix_of (take_prefix i \) \" + by transfer auto + +lift_definition pdrop :: "nat \ 'a prefix \ 'a prefix" is drop + by (auto simp: drop_map[symmetric] sorted_drop) + +lemma pdrop_0[simp]: "pdrop 0 \ = \" + by transfer auto + +lemma prefix_of_antimono: "\ \ \' \ prefix_of \' s \ prefix_of \ s" + by transfer (auto simp del: stake_add simp add: stake_add[symmetric]) + +lemma ex_prefix_of: "\s. prefix_of p s" +proof (transfer, intro bexI CollectI conjI) + fix p :: "('a set \ nat) list" + assume *: "sorted (map snd p)" + let ?\ = "p @- smap (Pair undefined) (fromN (snd (last p)))" + show "stake (length p) ?\ = p" by (simp add: stake_shift) + have le_last: "snd (p ! i) \ snd (last p)" if "i < length p" for i + using sorted_nth_mono[OF *, of i "length p - 1"] that + by (cases p) (auto simp: last_conv_nth nth_Cons') + with * show "ssorted (smap snd ?\)" + by (force simp: ssorted_iff_mono sorted_iff_nth_mono shift_snth) + show "sincreasing (smap snd ?\)" unfolding sincreasing_def + proof (rule allI) + fix i + show "\j > i. smap snd ?\ !! i < smap snd ?\ !! j" + proof (cases "i < length p") + case True + with le_last[of i] show ?thesis + by (auto intro!: exI[of _ "Suc (length p)"]) + next + case False + then show ?thesis + by (auto simp: neq_Nil_conv intro!: exI[of _ "Suc i"]) + qed + qed +qed + +lemma \_prefix_conv: "prefix_of p s \ prefix_of p s' \ i < plen p \ \ s i = \ s' i" + by transfer (simp add: stake_nth[symmetric]) + +lemma \_prefix_conv: "prefix_of p s \ prefix_of p s' \ i < plen p \ \ s i = \ s' i" + by transfer (simp add: stake_nth[symmetric]) + +lemma sincreasing_sdrop: + assumes "sincreasing s" + shows "sincreasing (sdrop n s)" +proof (unfold sincreasing_def; safe) + fix i + from assms obtain j where "n + i < j" "s !! (n + i) < s !! j" + unfolding sincreasing_def by auto + then show "\j>i. sdrop n s !! i < sdrop n s !! j" + by (auto simp: sdrop_snth intro!: exI[of _ "j - n"]) +qed + +lemma ssorted_shift: + "ssorted (xs @- s) = (sorted xs \ ssorted s \ (\x\set xs. \y\sset s. x \ y))" +proof safe + assume *: "ssorted (xs @- s)" + then show "sorted xs" + by (auto simp: ssorted_iff_mono shift_snth sorted_iff_nth_mono split: if_splits) + from ssorted_sdrop[OF *, of "length xs"] show "ssorted s" + by (auto simp: sdrop_shift) + fix x y assume "x \ set xs" "y \ sset s" + then obtain i j where "i < length xs" "xs ! i = x" "s !! j = y" + by (auto simp: set_conv_nth sset_range) + with ssorted_monoD[OF *, of i "j + length xs"] show "x \ y" by auto +next + assume "sorted xs" "ssorted s" "\x\set xs. \y\sset s. x \ y" + then show "ssorted (xs @- s)" + proof (coinduction arbitrary: xs s) + case (ssorted xs s) + with \ssorted s\ show ?case + by (subst (asm) ssorted.simps) (auto 0 4 simp: neq_Nil_conv shd_sset intro: exI[of _ "_ # _"]) + qed +qed + +lemma sincreasing_shift: + assumes "ssorted (xs @- s)" "sincreasing s" + shows "sincreasing (xs @- s)" +proof (unfold sincreasing_def; safe) + fix i + show "\j>i. (xs @- s) !! i < (xs @- s) !! j" + proof (cases "i < length xs") + case True + with assms(1) have "xs ! i \ shd s" unfolding ssorted_shift by (auto simp: shd_sset) + also obtain j where "\ < s !! j" + using assms(2) by (auto simp: sincreasing_def dest: spec[of _ 0]) + finally show ?thesis using True by (auto intro!: exI[of _ "j + length xs"]) + next + case False + then obtain j where "i - length xs < j" "s !! (i - length xs) < s !! j" + using assms(2) by (auto simp: sincreasing_def) + then show ?thesis using False by (auto simp: not_less intro!: exI[of _ "j + length xs"]) + qed +qed + +lift_definition replace_prefix :: "'a prefix \ 'a trace \ 'a trace" is + "\\ \. if ssorted (smap snd (\ @- sdrop (length \) \)) then + \ @- sdrop (length \) \ else smap (\i. ({}, i)) nats" + by (auto split: if_splits simp: stream.map_comp stream.map_ident sdrop_smap[symmetric] + simp del: sdrop_smap intro!: sincreasing_shift sincreasing_sdrop cong: stream.map_cong) + +(*<*) +end +(*>*) diff --git a/thys/MFODL_Monitor_Optimized/document/root.bib b/thys/MFODL_Monitor_Optimized/document/root.bib new file mode 100644 --- /dev/null +++ b/thys/MFODL_Monitor_Optimized/document/root.bib @@ -0,0 +1,44 @@ +@article{BasinKMZ-JACM15, + author = {Basin, David and Klaedtke, Felix and M{\"u}ller, Samuel and Z{\u a}linescu, Eugen}, + title = {Monitoring Metric First-Order Temporal Properties}, + journal = {J.\ ACM}, + volume = {62}, + number = {2}, + year = {2015}, + pages = {15:1--15:45}, +} + +@inproceedings{SchneiderBKT2019RV, + author = {Joshua Schneider and David Basin and Sr{\dj{}}an Krsti{\'c} and Dmitriy Traytel}, + title = {A Formally Verified Monitor for Metric First-Order Temporal Logic}, + editor = {Bernd Finkbeiner and Leonardo Mariani}, + booktitle = {{RV} 2019}, + series = {LNCS}, + volume = {11757}, + pages = {310--328}, + publisher = {Springer}, + year = {2019}, +} + +@inproceedings{BasinKT-RV17, + author = {David Basin and Sr{\dj{}}an Krsti{\'c} and Dmitriy Traytel}, + title = {Almost Event-Rate Independent Monitoring of Metric Dynamic Logic}, + editor = {Shuvendu K. Lahiri and Giles Reger}, + booktitle = {{RV} 2017}, + series = {LNCS}, + volume = {10548}, + pages = {85--102}, + publisher = {Springer}, + year = {2017}, +} + +@inproceedings{BasinDHKRST2020IJCAR, + author = {David Basin and Thibault Dardinier and Lukas Heimes and Sr{\dj{}}an Krsti{\'c} + and Martin Raszyk and Joshua Schneider and Dmitriy Traytel}, + title = {A Formally Verified, Optimized Monitor for Metric First-Order Dynamic Logic}, + editor = {Nicolas Peltier and Viorica Sofronie-Stokkermans}, + booktitle = {{IJCAR} 2020}, + year = {2020}, + note = {To appear}, + url = {http://people.inf.ethz.ch/trayteld/papers/ijcar20-verimonplus/verimonplus.pdf}, +} diff --git a/thys/MFODL_Monitor_Optimized/document/root.tex b/thys/MFODL_Monitor_Optimized/document/root.tex new file mode 100644 --- /dev/null +++ b/thys/MFODL_Monitor_Optimized/document/root.tex @@ -0,0 +1,58 @@ +\documentclass[10pt,a4paper]{article} +\usepackage{isabelle,isabellesym} + +\usepackage{a4wide} +\usepackage[english]{babel} +\usepackage{eufrak} +\usepackage{amssymb} + +% this should be the last package used +\usepackage{pdfsetup} + +% urls in roman style, theory text in math-similar italics +\urlstyle{rm} +\isabellestyle{literal} + + +\begin{document} + +\title{Formalization of an Optimized Monitoring Algorithm for\\ Metric First-Order Dynamic Logic with Aggregations} +\author{Thibault Dardinier \and Lukas Heimes \and Martin Raszyk \and Joshua Schneider \and Dmitriy Traytel} + +\maketitle + +\begin{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)~\cite{BasinKMZ-JACM15} and metric dynamic logic~\cite{BasinKT-RV17}. 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~\cite{BasinDHKRST2020IJCAR}, significantly extends +\href{https://www.isa-afp.org/entries/MFOTL_Monitor.html}{previous work on a verified +monitor} for MFOTL~\cite{SchneiderBKT2019RV}. Apart from the addition of regular +expressions and aggregations, we implemented +\href{https://www.isa-afp.org/entries/Generic_Join.html}{multi-way joins} and +a specialized sliding window algorithm to further optimize the monitor. +\end{abstract} + +\tableofcontents + +% sane default for proof documents +\parindent 0pt\parskip 0.5ex + +% generated text of all theories +\input{session} + +\bibliographystyle{abbrv} +\bibliography{root} + +\end{document} + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: t +%%% End: diff --git a/thys/ROOTS b/thys/ROOTS --- a/thys/ROOTS +++ b/thys/ROOTS @@ -1,525 +1,528 @@ AODV Auto2_HOL Auto2_Imperative_HOL 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 Amortized_Complexity AnselmGod Applicative_Lifting Approximation_Algorithms Architectural_Design_Patterns Aristotles_Assertoric_Syllogistic Arith_Prog_Rel_Primes ArrowImpossibilityGS AutoFocus-Stream Automatic_Refinement AxiomaticCategoryTheory BDD BNF_Operations Bell_Numbers_Spivey Berlekamp_Zassenhaus Bernoulli Bertrands_Postulate Bicategory BinarySearchTree Binding_Syntax_Theory Binomial-Heaps Binomial-Queues BNF_CC 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 Chord_Segments Circus Clean ClockSynchInst Closest_Pair_Points CofGroups Coinductive Coinductive_Languages Collections Comparison_Sort_Lower_Bound Compiling-Exceptions-Correctly Completeness Complete_Non_Orders Complex_Geometry Complx ComponentDependencies ConcurrentGC ConcurrentIMP Concurrent_Ref_Alg Concurrent_Revisions Consensus_Refined Constructive_Cryptography Constructor_Funs Containers CoreC++ Core_DOM Count_Complex_Roots CryptHOL CryptoBasedCompositionalProperties DFS_Framework DPT-SAT-Solver DataRefinementIBP Datatype_Order_Generator Decl_Sem_Fun_PL Decreasing-Diagrams Decreasing-Diagrams-II Deep_Learning 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 Discrete_Summation DiscretePricing DiskPaxos 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 Factored_Transition_System_Bounding Farkas FFT FLP FOL-Fitting FOL_Harrison FOL_Seq_Calc1 Falling_Factorial_Sum FeatherweightJava Featherweight_OCL Fermat3_4 FileRefinement FinFun Finger-Trees Finite_Automata_HF First_Order_Terms First_Welfare_Theorem Fishburn_Impossibility Fisher_Yates Flow_Networks Floyd_Warshall Flyspeck-Tame FocusStreamsCaseStudies 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 GenClock General-Triangle Generalized_Counting_Sort Generic_Deriving Generic_Join GewirthPGCProof Girth_Chromatic GoedelGod 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 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 InfPathElimination InformationFlowSlicing InformationFlowSlicing_Inter Integration Interval_Arithmetic_Word32 Iptables_Semantics Irrationality_J_Hancl Isabelle_C Isabelle_Meta_Model Jacobson_Basic_Algebra Jinja JinjaThreads JiveDataStoreModel Jordan_Hoelder Jordan_Normal_Form KAD KAT_and_DRA KBPs KD_Tree Key_Agreement_Strong_Adversaries Kleene_Algebra Knot_Theory Knuth_Morris_Pratt Koenigsberg_Friendship Kruskal Kuratowski_Closure_Complement LLL_Basis_Reduction LLL_Factorization LOFT LTL LTL_to_DRA LTL_to_GBA LTL_Master_Theorem Lam-ml-Normalization LambdaAuth LambdaMu Lambda_Free_KBOs Lambda_Free_RPOs Landau_Symbols Laplace_Transform Latin_Square LatticeProperties Lambda_Free_EPO 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 MFMC_Countable MSO_Regex_Equivalence Markov_Models Marriage Mason_Stothers Matrix Matrix_Tensor Matroids Max-Card-Matching Median_Of_Medians_Selection Menger Mersenne_Primes +MFODL_Monitor_Optimized MFOTL_Monitor 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 Multirelations Multi_Party_Computation Myhill-Nerode Name_Carrying_Type_Inference 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 Open_Induction OpSets Optics Optimal_BST Orbit_Stabiliser Order_Lattice_Props Ordered_Resolution_Prover Ordinal Ordinals_and_Cardinals Ordinary_Differential_Equations PCF PLM Pell POPLmark-deBruijn PSemigroupsConvolution Pairing_Heap Paraconsistency Parity_Game Partial_Function_MR Partial_Order_Reduction Password_Authentication_Protocol Perfect-Number-Thm Perron_Frobenius Pi_Calculus Pi_Transcendental Planarity_Certificates Polynomial_Factorization Polynomial_Interpolation Polynomials Poincare_Bendixson Poincare_Disc Pop_Refinement Posix-Lexing Possibilistic_Noninterference 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 Projective_Geometry Program-Conflict-Analysis 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 Randomised_BSTs Random_Graph_Subgraph_Threshold Randomised_Social_Choice Rank_Nullity_Theorem Real_Impl Recursion-Theory-I Refine_Imperative_HOL Refine_Monadic RefinementReactive Regex_Equivalence Regular-Sets Regular_Algebras Relation_Algebra Relational-Incorrectness-Logic Rep_Fin_Groups Residuated_Lattices Resolution_FOL Rewriting_Z Ribbon_Proofs Robbins-Conjecture Root_Balanced_Tree Routing Roy_Floyd_Warshall -Safe_OCL SATSolverVerification SDS_Impossibility SIFPL SIFUM_Type_Systems SPARCv8 +Safe_OCL +Saturation_Framework Secondary_Sylow Security_Protocol_Refinement Selection_Heap_Sort SenSocialChoice Separata Separation_Algebra Separation_Logic_Imperative_HOL SequentInvertibility Shivers-CFA ShortestPath Show Sigma_Commit_Crypto Signature_Groebner Simpl Simple_Firewall Simplex Skew_Heap Skip_Lists Slicing +Sliding_Window_Algorithm Smooth_Manifolds Sort_Encodings Source_Coding_Theorem Special_Function_Bounds Splay_Tree Sqrt_Babylonian Stable_Matching Statecharts 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 Szpilrajn TESL_Language TLA Tail_Recursive_Functions Tarskis_Geometry Taylor_Models Timed_Automata 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 Universal_Turing_Machine UPF UPF_Firewall UpDown_Scheme UTP Valuation VectorSpace VeriComp Verified-Prover VerifyThis2018 VerifyThis2019 Vickrey_Clarke_Groves VolpanoSmith WHATandWHERE_Security WebAssembly Weight_Balanced_Trees Well_Quasi_Orders Winding_Number_Eval WOOT_Strong_Eventual_Consistency Word_Lib WorkerWrapper XML Zeta_Function Zeta_3_Irrational ZFC_in_HOL pGCL diff --git a/thys/Saturation_Framework/Calculi.thy b/thys/Saturation_Framework/Calculi.thy new file mode 100644 --- /dev/null +++ b/thys/Saturation_Framework/Calculi.thy @@ -0,0 +1,925 @@ +(* Title: Calculi of the Saturation Framework + * Author: Sophie Tourret , 2018-2020 *) + +section \Calculi\ + +text \In this section, the section 2.2 to 2.4 of the report are covered. This + includes results on calculi equipped with a redundancy criterion or with a + family of redundancy criteria, as well as a proof that various notions of + redundancy are equivalent\ + +theory Calculi + imports + Consequence_Relations_and_Inference_Systems + Ordered_Resolution_Prover.Lazy_List_Liminf + Ordered_Resolution_Prover.Lazy_List_Chain +begin + +subsection \Calculi with a Redundancy Criterion\ + +locale calculus_with_red_crit = inference_system Inf + consequence_relation Bot entails + for + Bot :: "'f set" and + Inf :: \'f inference set\ and + entails :: "'f set \ 'f set \ bool" (infix "\" 50) + + fixes + Red_Inf :: "'f set \ 'f inference set" and + Red_F :: "'f set \ 'f set" + assumes + Red_Inf_to_Inf: "Red_Inf N \ Inf" and + Red_F_Bot: "B \ Bot \ N \ {B} \ N - Red_F N \ {B}" and + Red_F_of_subset: "N \ N' \ Red_F N \ Red_F N'" and + Red_Inf_of_subset: "N \ N' \ Red_Inf N \ Red_Inf N'" and + Red_F_of_Red_F_subset: "N' \ Red_F N \ Red_F N \ Red_F (N - N')" and + Red_Inf_of_Red_F_subset: "N' \ Red_F N \ Red_Inf N \ Red_Inf (N - N')" and + Red_Inf_of_Inf_to_N: "\ \ Inf \ concl_of \ \ N \ \ \ Red_Inf N" +begin + +lemma Red_Inf_of_Inf_to_N_subset: "{\ \ Inf. (concl_of \ \ N)} \ Red_Inf N" + using Red_Inf_of_Inf_to_N by blast + +(* lem:red-concl-implies-red-inf *) +lemma red_concl_to_red_inf: + assumes + i_in: "\ \ Inf" and + concl: "concl_of \ \ Red_F N" + shows "\ \ Red_Inf N" +proof - + have "\ \ Red_Inf (Red_F N)" by (simp add: Red_Inf_of_Inf_to_N i_in concl) + then have i_in_Red: "\ \ Red_Inf (N \ Red_F N)" by (simp add: Red_Inf_of_Inf_to_N concl i_in) + have red_n_subs: "Red_F N \ Red_F (N \ Red_F N)" by (simp add: Red_F_of_subset) + then have "\ \ Red_Inf ((N \ Red_F N) - (Red_F N - N))" using Red_Inf_of_Red_F_subset i_in_Red + by (meson Diff_subset subsetCE subset_trans) + then show ?thesis by (metis Diff_cancel Diff_subset Un_Diff Un_Diff_cancel contra_subsetD + calculus_with_red_crit.Red_Inf_of_subset calculus_with_red_crit_axioms sup_bot.right_neutral) +qed + +definition saturated :: "'f set \ bool" where + "saturated N \ Inf_from N \ Red_Inf N" + +definition reduc_saturated :: "'f set \ bool" where +"reduc_saturated N \ Inf_from (N - Red_F N) \ Red_Inf N" + +lemma Red_Inf_without_red_F: + "Red_Inf (N - Red_F N) = Red_Inf N" + using Red_Inf_of_subset [of "N - Red_F N" N] + and Red_Inf_of_Red_F_subset [of "Red_F N" N] by blast + +lemma saturated_without_red_F: + assumes saturated: "saturated N" + shows "saturated (N - Red_F N)" +proof - + have "Inf_from (N - Red_F N) \ Inf_from N" unfolding Inf_from_def by auto + also have "Inf_from N \ Red_Inf N" using saturated unfolding saturated_def by auto + also have "Red_Inf N \ Red_Inf (N - Red_F N)" using Red_Inf_of_Red_F_subset by auto + finally have "Inf_from (N - Red_F N) \ Red_Inf (N - Red_F N)" by auto + then show ?thesis unfolding saturated_def by auto +qed + +definition Sup_Red_Inf_llist :: "'f set llist \ 'f inference set" where + "Sup_Red_Inf_llist D = (\i \ {i. enat i < llength D}. Red_Inf (lnth D i))" + +lemma Sup_Red_Inf_unit: "Sup_Red_Inf_llist (LCons X LNil) = Red_Inf X" + using Sup_Red_Inf_llist_def enat_0_iff(1) by simp + +definition fair :: "'f set llist \ bool" where + "fair D \ Inf_from (Liminf_llist D) \ Sup_Red_Inf_llist D" + +inductive "derive" :: "'f set \ 'f set \ bool" (infix "\Red" 50) where + derive: "M - N \ Red_F N \ M \Red N" + +text \TODO: replace in \<^theory>\Ordered_Resolution_Prover.Lazy_List_Liminf\.\ +lemma (in-) elem_Sup_llist_imp_Sup_upto_llist': + "x \ Sup_llist Xs \ \j < llength Xs. x \ Sup_upto_llist Xs j" + unfolding Sup_llist_def Sup_upto_llist_def by blast + +lemma gt_Max_notin: \finite A \ A \ {} \ x > Max A \ x \ A\ by auto + +lemma equiv_Sup_Liminf: + assumes + in_Sup: "C \ Sup_llist D" and + not_in_Liminf: "C \ Liminf_llist D" + shows + "\ i \ {i. enat (Suc i) < llength D}. C \ lnth D i - lnth D (Suc i)" +proof - + obtain i where C_D_i: "C \ Sup_upto_llist D i" and "i < llength D" + using elem_Sup_llist_imp_Sup_upto_llist' in_Sup by fast + then obtain j where j: "j \ i \ enat j < llength D \ C \ lnth D j" using not_in_Liminf + unfolding Sup_llist_def chain_def Liminf_llist_def by auto + obtain k where k: "C \ lnth D k" "enat k < llength D" "k \ i" using C_D_i + unfolding Sup_upto_llist_def by auto + let ?S = "{i. i < j \ i \ k \ C \ lnth D i}" + define l where "l \ Max ?S" + have \k \ {i. i < j \ k \ i \ C \ lnth D i}\ using k j by (auto simp: order.order_iff_strict) + then have nempty: "{i. i < j \ k \ i \ C \ lnth D i} \ {}" by auto + then have l_prop: "l < j \ l \ k \ C \ (lnth D l)" using Max_in[of ?S, OF _ nempty] unfolding l_def by auto + then have "C \ lnth D l - lnth D (Suc l)" using j gt_Max_notin[OF _ nempty, of "Suc l"] + unfolding l_def[symmetric] by (auto intro: Suc_lessI) + then show ?thesis + proof (rule bexI[of _ l]) + show "l \ {i. enat (Suc i) < llength D}" + using l_prop j by (clarify, metis Suc_leI dual_order.order_iff_strict enat_ord_simps(2) less_trans) + qed +qed + +(* lem:nonpersistent-is-redundant *) +lemma Red_in_Sup: + assumes deriv: "chain (\Red) D" + shows "Sup_llist D - Liminf_llist D \ Red_F (Sup_llist D)" +proof + fix C + assume C_in_subset: "C \ Sup_llist D - Liminf_llist D" + { + fix C i + assume + in_ith_elem: "C \ lnth D i - lnth D (Suc i)" and + i: "enat (Suc i) < llength D" + have "lnth D i \Red lnth D (Suc i)" using i deriv in_ith_elem chain_lnth_rel by auto + then have "C \ Red_F (lnth D (Suc i))" using in_ith_elem derive.cases by blast + then have "C \ Red_F (Sup_llist D)" using Red_F_of_subset + by (meson contra_subsetD i lnth_subset_Sup_llist) + } + then show "C \ Red_F (Sup_llist D)" using equiv_Sup_Liminf[of C] C_in_subset by fast +qed + +(* lem:redundant-remains-redundant-during-run 1/2 *) +lemma Red_Inf_subset_Liminf: + assumes deriv: \chain (\Red) D\ and + i: \enat i < llength D\ + shows \Red_Inf (lnth D i) \ Red_Inf (Liminf_llist D)\ +proof - + have Sup_in_diff: \Red_Inf (Sup_llist D) \ Red_Inf (Sup_llist D - (Sup_llist D - Liminf_llist D))\ + using Red_Inf_of_Red_F_subset[OF Red_in_Sup] deriv by auto + also have \Sup_llist D - (Sup_llist D - Liminf_llist D) = Liminf_llist D\ + by (simp add: Liminf_llist_subset_Sup_llist double_diff) + then have Red_Inf_Sup_in_Liminf: \Red_Inf (Sup_llist D) \ Red_Inf (Liminf_llist D)\ using Sup_in_diff by auto + have \lnth D i \ Sup_llist D\ unfolding Sup_llist_def using i by blast + then have "Red_Inf (lnth D i) \ Red_Inf (Sup_llist D)" using Red_Inf_of_subset + unfolding Sup_llist_def by auto + then show ?thesis using Red_Inf_Sup_in_Liminf by auto +qed + +(* lem:redundant-remains-redundant-during-run 2/2 *) +lemma Red_F_subset_Liminf: + assumes deriv: \chain (\Red) D\ and + i: \enat i < llength D\ + shows \Red_F (lnth D i) \ Red_F (Liminf_llist D)\ +proof - + have Sup_in_diff: \Red_F (Sup_llist D) \ Red_F (Sup_llist D - (Sup_llist D - Liminf_llist D))\ + using Red_F_of_Red_F_subset[OF Red_in_Sup] deriv by auto + also have \Sup_llist D - (Sup_llist D - Liminf_llist D) = Liminf_llist D\ + by (simp add: Liminf_llist_subset_Sup_llist double_diff) + then have Red_F_Sup_in_Liminf: \Red_F (Sup_llist D) \ Red_F (Liminf_llist D)\ + using Sup_in_diff by auto + have \lnth D i \ Sup_llist D\ unfolding Sup_llist_def using i by blast + then have "Red_F (lnth D i) \ Red_F (Sup_llist D)" using Red_F_of_subset + unfolding Sup_llist_def by auto + then show ?thesis using Red_F_Sup_in_Liminf by auto +qed + +(* lem:N-i-is-persistent-or-redundant *) +lemma i_in_Liminf_or_Red_F: + assumes + deriv: \chain (\Red) D\ and + i: \enat i < llength D\ + shows \lnth D i \ Red_F (Liminf_llist D) \ Liminf_llist D\ +proof (rule,rule) + fix C + assume C: \C \ lnth D i\ + and C_not_Liminf: \C \ Liminf_llist D\ + have \C \ Sup_llist D\ unfolding Sup_llist_def using C i by auto + then obtain j where j: \C \ lnth D j - lnth D (Suc j)\ \enat (Suc j) < llength D\ + using equiv_Sup_Liminf[of C D] C_not_Liminf by auto + then have \C \ Red_F (lnth D (Suc j))\ + using deriv by (meson chain_lnth_rel contra_subsetD derive.cases) + then show \C \ Red_F (Liminf_llist D)\ using Red_F_subset_Liminf[of D "Suc j"] deriv j(2) by blast +qed + +(* lem:fairness-implies-saturation *) +lemma fair_implies_Liminf_saturated: + assumes + deriv: \chain (\Red) D\ and + fair: \fair D\ + shows \saturated (Liminf_llist D)\ + unfolding saturated_def +proof + fix \ + assume \: \\ \ Inf_from (Liminf_llist D)\ + have \\ \ Sup_Red_Inf_llist D\ using fair \ unfolding fair_def by auto + then obtain i where i: \enat i < llength D\ \\ \ Red_Inf (lnth D i)\ + unfolding Sup_Red_Inf_llist_def by auto + then show \\ \ Red_Inf (Liminf_llist D)\ + using deriv i_in_Liminf_or_Red_F[of D i] Red_Inf_subset_Liminf by blast +qed + +end + +locale static_refutational_complete_calculus = calculus_with_red_crit + + assumes static_refutational_complete: "B \ Bot \ saturated N \ N \ {B} \ \B'\Bot. B' \ N" + +locale dynamic_refutational_complete_calculus = calculus_with_red_crit + + assumes + dynamic_refutational_complete: "B \ Bot \ chain (\Red) D \ fair D + \ lnth D 0 \ {B} \ \i \ {i. enat i < llength D}. \B'\Bot. B' \ lnth D i" +begin + +(* lem:dynamic-ref-compl-implies-static *) +sublocale static_refutational_complete_calculus +proof + fix B N + assume + bot_elem: \B \ Bot\ and + saturated_N: "saturated N" and + refut_N: "N \ {B}" + define D where "D = LCons N LNil" + have[simp]: \\ lnull D\ by (auto simp: D_def) + have deriv_D: \chain (\Red) D\ by (simp add: chain.chain_singleton D_def) + have liminf_is_N: "Liminf_llist D = N" by (simp add: D_def Liminf_llist_LCons) + have head_D: "N = lnth D 0" by (simp add: D_def) + have "Sup_Red_Inf_llist D = Red_Inf N" by (simp add: D_def Sup_Red_Inf_unit) + then have fair_D: "fair D" using saturated_N by (simp add: fair_def saturated_def liminf_is_N) + obtain i B' where B'_is_bot: \B' \ Bot\ and B'_in: "B' \ (lnth D i)" and \i < llength D\ + using dynamic_refutational_complete[of B D] bot_elem fair_D head_D saturated_N deriv_D refut_N + by auto + then have "i = 0" + by (auto simp: D_def enat_0_iff) + show \\B'\Bot. B' \ N\ + using B'_is_bot B'_in unfolding \i = 0\ head_D[symmetric] by auto +qed + +end + +(* lem:static-ref-compl-implies-dynamic *) +sublocale static_refutational_complete_calculus \ dynamic_refutational_complete_calculus +proof + fix B D + assume + bot_elem: \B \ Bot\ and + deriv: \chain (\Red) D\ and + fair: \fair D\ and + unsat: \(lnth D 0) \ {B}\ + have non_empty: \\ lnull D\ using chain_not_lnull[OF deriv] . + have subs: \(lnth D 0) \ Sup_llist D\ + using lhd_subset_Sup_llist[of D] non_empty by (simp add: lhd_conv_lnth) + have \Sup_llist D \ {B}\ + using unsat subset_entailed[OF subs] entails_trans[of "Sup_llist D" "lnth D 0"] by auto + then have Sup_no_Red: \Sup_llist D - Red_F (Sup_llist D) \ {B}\ + using bot_elem Red_F_Bot by auto + have Sup_no_Red_in_Liminf: \Sup_llist D - Red_F (Sup_llist D) \ Liminf_llist D\ + using deriv Red_in_Sup by auto + have Liminf_entails_Bot: \Liminf_llist D \ {B}\ + using Sup_no_Red subset_entailed[OF Sup_no_Red_in_Liminf] entails_trans by blast + have \saturated (Liminf_llist D)\ + using deriv fair fair_implies_Liminf_saturated unfolding saturated_def by auto + + then have \\B'\Bot. B' \ (Liminf_llist D)\ + using bot_elem static_refutational_complete Liminf_entails_Bot by auto + then show \\i\{i. enat i < llength D}. \B'\Bot. B' \ lnth D i\ + unfolding Liminf_llist_def by auto +qed + +subsection \Calculi with a Family of Redundancy Criteria\ + +locale calculus_with_red_crit_family = inference_system Inf + consequence_relation_family Bot Q entails_q + for + Bot :: "'f set" and + Inf :: \'f inference set\ and + Q :: "'q itself" and + entails_q :: "'q \ ('f set \ 'f set \ bool)" + + fixes + Red_Inf_q :: "'q \ ('f set \ 'f inference set)" and + Red_F_q :: "'q \ ('f set \ 'f set)" + assumes + all_red_crit: "calculus_with_red_crit Bot Inf (entails_q q) (Red_Inf_q q) (Red_F_q q)" +begin + +definition Red_Inf_Q :: "'f set \ 'f inference set" where + "Red_Inf_Q N = \ {X N |X. X \ (Red_Inf_q ` UNIV)}" + +definition Red_F_Q :: "'f set \ 'f set" where + "Red_F_Q N = \ {X N |X. X \ (Red_F_q ` UNIV)}" + +(* lem:intersection-of-red-crit *) +lemma inter_red_crit: "calculus_with_red_crit Bot Inf entails_Q Red_Inf_Q Red_F_Q" + unfolding calculus_with_red_crit_def calculus_with_red_crit_axioms_def +proof (intro conjI) + show "consequence_relation Bot entails_Q" + using intersect_cons_rel_family . +next + show "\N. Red_Inf_Q N \ Inf" + unfolding Red_Inf_Q_def + proof + fix N + show "\ {X N |X. X \ Red_Inf_q ` UNIV} \ Inf" + proof (intro Inter_subset) + fix Red_Infs + assume one_red_inf: "Red_Infs \ {X N |X. X \ Red_Inf_q ` UNIV}" + show "Red_Infs \ Inf" using one_red_inf + proof + assume "\Red_Inf_qi. Red_Infs = Red_Inf_qi N \ Red_Inf_qi \ Red_Inf_q ` UNIV" + then obtain Red_Inf_qi where + red_infs_def: "Red_Infs = Red_Inf_qi N" and red_inf_qi_in: "Red_Inf_qi \ Red_Inf_q ` UNIV" + by blast + obtain qi where red_inf_qi_def: "Red_Inf_qi = Red_Inf_q qi" and qi_in: "qi \ UNIV" + using red_inf_qi_in by blast + show "Red_Infs \ Inf" + using all_red_crit calculus_with_red_crit.Red_Inf_to_Inf red_inf_qi_def + red_infs_def by blast + qed + next + show "{X N |X. X \ Red_Inf_q ` UNIV} \ {}" by blast + qed + qed +next + show "\B N. B \ Bot \ N \Q {B} \ N - Red_F_Q N \Q {B}" + proof (intro allI impI) + fix B N + assume + B_in: "B \ Bot" and + N_unsat: "N \Q {B}" + show "N - Red_F_Q N \Q {B}" unfolding entails_Q_def Red_F_Q_def + proof + fix qi + define entails_qi (infix "\qi" 50) where "entails_qi = entails_q qi" + have cons_rel_qi: "consequence_relation Bot entails_qi" + unfolding entails_qi_def using all_red_crit calculus_with_red_crit.axioms(1) by blast + define Red_F_qi where "Red_F_qi = Red_F_q qi" + have red_qi_in_Q: "Red_F_Q N \ Red_F_qi N" + unfolding Red_F_Q_def Red_F_qi_def using image_iff by blast + then have "N - (Red_F_qi N) \ N - (Red_F_Q N)" by blast + then have entails_1: "(N - Red_F_Q N) \qi (N - Red_F_qi N)" + using all_red_crit + unfolding calculus_with_red_crit_def consequence_relation_def entails_qi_def by metis + have N_unsat_qi: "N \qi {B}" using N_unsat unfolding entails_qi_def entails_Q_def by simp + then have N_unsat_qi: "(N - Red_F_qi N) \qi {B}" + using all_red_crit Red_F_qi_def calculus_with_red_crit.Red_F_Bot[OF _ B_in] entails_qi_def + by fastforce + show "(N - \ {X N |X. X \ Red_F_q ` UNIV}) \qi {B}" + using consequence_relation.entails_trans[OF cons_rel_qi entails_1 N_unsat_qi] + unfolding Red_F_Q_def . + qed + qed +next + show "\N1 N2. N1 \ N2 \ Red_F_Q N1 \ Red_F_Q N2" + proof (intro allI impI) + fix N1 :: "'f set" + and N2 :: "'f set" + assume + N1_in_N2: "N1 \ N2" + show "Red_F_Q N1 \ Red_F_Q N2" + proof + fix x + assume x_in: "x \ Red_F_Q N1" + then have "\qi. x \ Red_F_q qi N1" unfolding Red_F_Q_def by blast + then have "\qi. x \ Red_F_q qi N2" + using N1_in_N2 all_red_crit calculus_with_red_crit.axioms(2) calculus_with_red_crit.Red_F_of_subset by blast + then show "x \ Red_F_Q N2" unfolding Red_F_Q_def by blast + qed + qed +next + show "\N1 N2. N1 \ N2 \ Red_Inf_Q N1 \ Red_Inf_Q N2" + proof (intro allI impI) + fix N1 :: "'f set" + and N2 :: "'f set" + assume + N1_in_N2: "N1 \ N2" + show "Red_Inf_Q N1 \ Red_Inf_Q N2" + proof + fix x + assume x_in: "x \ Red_Inf_Q N1" + then have "\qi. x \ Red_Inf_q qi N1" unfolding Red_Inf_Q_def by blast + then have "\qi. x \ Red_Inf_q qi N2" + using N1_in_N2 all_red_crit calculus_with_red_crit.axioms(2) calculus_with_red_crit.Red_Inf_of_subset by blast + then show "x \ Red_Inf_Q N2" unfolding Red_Inf_Q_def by blast + qed + qed +next + show "\N2 N1. N2 \ Red_F_Q N1 \ Red_F_Q N1 \ Red_F_Q (N1 - N2)" + proof (intro allI impI) + fix N2 N1 + assume N2_in_Red_N1: "N2 \ Red_F_Q N1" + show "Red_F_Q N1 \ Red_F_Q (N1 - N2)" + proof + fix x + assume x_in: "x \ Red_F_Q N1" + then have "\qi. x \ Red_F_q qi N1" unfolding Red_F_Q_def by blast + moreover have "\qi. N2 \ Red_F_q qi N1" using N2_in_Red_N1 unfolding Red_F_Q_def by blast + ultimately have "\qi. x \ Red_F_q qi (N1 - N2)" + using all_red_crit calculus_with_red_crit.axioms(2) calculus_with_red_crit.Red_F_of_Red_F_subset by blast + then show "x \ Red_F_Q (N1 - N2)" unfolding Red_F_Q_def by blast + qed + qed +next + show "\N2 N1. N2 \ Red_F_Q N1 \ Red_Inf_Q N1 \ Red_Inf_Q (N1 - N2)" + proof (intro allI impI) + fix N2 N1 + assume N2_in_Red_N1: "N2 \ Red_F_Q N1" + show "Red_Inf_Q N1 \ Red_Inf_Q (N1 - N2)" + proof + fix x + assume x_in: "x \ Red_Inf_Q N1" + then have "\qi. x \ Red_Inf_q qi N1" unfolding Red_Inf_Q_def by blast + moreover have "\qi. N2 \ Red_F_q qi N1" using N2_in_Red_N1 unfolding Red_F_Q_def by blast + ultimately have "\qi. x \ Red_Inf_q qi (N1 - N2)" + using all_red_crit calculus_with_red_crit.axioms(2) calculus_with_red_crit.Red_Inf_of_Red_F_subset by blast + then show "x \ Red_Inf_Q (N1 - N2)" unfolding Red_Inf_Q_def by blast + qed + qed +next + show "\\ N. \ \ Inf \ concl_of \ \ N \ \ \ Red_Inf_Q N" + proof (intro allI impI) + fix \ N + assume + i_in: "\ \ Inf" and + concl_in: "concl_of \ \ N" + then have "\qi. \ \ Red_Inf_q qi N" + using all_red_crit calculus_with_red_crit.axioms(2) calculus_with_red_crit.Red_Inf_of_Inf_to_N by blast + then show "\ \ Red_Inf_Q N" unfolding Red_Inf_Q_def by blast + qed +qed + +sublocale inter_red_crit_calculus: calculus_with_red_crit + where Bot=Bot + and Inf=Inf + and entails=entails_Q + and Red_Inf=Red_Inf_Q + and Red_F=Red_F_Q + using inter_red_crit . + +(* lem:satur-wrt-intersection-of-red *) +lemma sat_int_to_sat_q: "calculus_with_red_crit.saturated Inf Red_Inf_Q N \ + (\qi. calculus_with_red_crit.saturated Inf (Red_Inf_q qi) N)" for N +proof + fix N + assume inter_sat: "calculus_with_red_crit.saturated Inf Red_Inf_Q N" + show "\qi. calculus_with_red_crit.saturated Inf (Red_Inf_q qi) N" + proof + fix qi + interpret one: calculus_with_red_crit Bot Inf "entails_q qi" "Red_Inf_q qi" "Red_F_q qi" + by (rule all_red_crit) + show "one.saturated N" + using inter_sat unfolding one.saturated_def inter_red_crit_calculus.saturated_def Red_Inf_Q_def + by blast + qed +next + fix N + assume all_sat: "\qi. calculus_with_red_crit.saturated Inf (Red_Inf_q qi) N" + show "inter_red_crit_calculus.saturated N" unfolding inter_red_crit_calculus.saturated_def Red_Inf_Q_def + proof + fix x + assume x_in: "x \ Inf_from N" + have "\Red_Inf_qi \ Red_Inf_q ` UNIV. x \ Red_Inf_qi N" + proof + fix Red_Inf_qi + assume red_inf_in: "Red_Inf_qi \ Red_Inf_q ` UNIV" + then obtain qi where red_inf_qi_def: "Red_Inf_qi = Red_Inf_q qi" by blast + interpret one: calculus_with_red_crit Bot Inf "entails_q qi" "Red_Inf_q qi" "Red_F_q qi" + by (rule all_red_crit) + have "one.saturated N" using all_sat red_inf_qi_def by blast + then show "x \ Red_Inf_qi N" unfolding one.saturated_def using x_in red_inf_qi_def by blast + qed + then show "x \ \ {X N |X. X \ Red_Inf_q ` UNIV}" by blast + qed +qed + +(* lem:checking-static-ref-compl-for-intersections *) +lemma stat_ref_comp_from_bot_in_sat: + "\N. (calculus_with_red_crit.saturated Inf Red_Inf_Q N \ (\B \ Bot. B \ N)) \ + (\B \ Bot. \qi. \ entails_q qi N {B}) + \ static_refutational_complete_calculus Bot Inf entails_Q Red_Inf_Q Red_F_Q" +proof (rule ccontr) + assume + N_saturated: "\N. (calculus_with_red_crit.saturated Inf Red_Inf_Q N \ (\B \ Bot. B \ N)) \ + (\B \ Bot. \qi. \ entails_q qi N {B})" and + no_stat_ref_comp: "\ static_refutational_complete_calculus Bot Inf (\Q) Red_Inf_Q Red_F_Q" + obtain N1 B1 where B1_in: + "B1 \ Bot" and N1_saturated: "calculus_with_red_crit.saturated Inf Red_Inf_Q N1" and + N1_unsat: "N1 \Q {B1}" and no_B_in_N1: "\B \ Bot. B \ N1" + using no_stat_ref_comp by (metis inter_red_crit static_refutational_complete_calculus.intro + static_refutational_complete_calculus_axioms.intro) + obtain B2 qi where no_qi:"\ entails_q qi N1 {B2}" using N_saturated N1_saturated no_B_in_N1 by blast + have "N1 \Q {B2}" using N1_unsat B1_in intersect_cons_rel_family + unfolding consequence_relation_def by metis + then have "entails_q qi N1 {B2}" unfolding entails_Q_def by blast + then show "False" using no_qi by simp +qed + +end + +subsection \Variations on a Theme\ + +locale calculus_with_reduced_red_crit = calculus_with_red_crit Bot Inf entails Red_Inf Red_F + for + Bot :: "'f set" and + Inf :: \'f inference set\ and + entails :: "'f set \ 'f set \ bool" (infix "\" 50) and + Red_Inf :: "'f set \ 'f inference set" and + Red_F :: "'f set \ 'f set" + + assumes + inf_in_red_inf: "Inf_from2 UNIV (Red_F N) \ Red_Inf N" +begin + +(* lem:reduced-rc-implies-sat-equiv-reduced-sat *) +lemma sat_eq_reduc_sat: "saturated N \ reduc_saturated N" +proof + fix N + assume "saturated N" + then show "reduc_saturated N" + using Red_Inf_without_red_F saturated_without_red_F + unfolding saturated_def reduc_saturated_def + by blast +next + fix N + assume red_sat_n: "reduc_saturated N" + show "saturated N" unfolding saturated_def + proof + fix \ + assume i_in: "\ \ Inf_from N" + show "\ \ Red_Inf N" + using i_in red_sat_n inf_in_red_inf unfolding reduc_saturated_def Inf_from_def Inf_from2_def by blast + qed +qed + +end + +locale reduc_static_refutational_complete_calculus = calculus_with_red_crit + + assumes reduc_static_refutational_complete: "B \ Bot \ reduc_saturated N \ N \ {B} \ \B'\Bot. B' \ N" + +locale reduc_static_refutational_complete_reduc_calculus = calculus_with_reduced_red_crit + + assumes reduc_static_refutational_complete: "B \ Bot \ reduc_saturated N \ N \ {B} \ \B'\Bot. B' \ N" +begin + +sublocale reduc_static_refutational_complete_calculus + by (simp add: calculus_with_red_crit_axioms reduc_static_refutational_complete + reduc_static_refutational_complete_calculus_axioms.intro reduc_static_refutational_complete_calculus_def) + +(* cor:reduced-rc-implies-st-ref-comp-equiv-reduced-st-ref-comp 1/2 *) +sublocale static_refutational_complete_calculus +proof + fix B N + assume + bot_elem: \B \ Bot\ and + saturated_N: "saturated N" and + refut_N: "N \ {B}" + have reduc_saturated_N: "reduc_saturated N" using saturated_N sat_eq_reduc_sat by blast + show "\B'\Bot. B' \ N" using reduc_static_refutational_complete[OF bot_elem reduc_saturated_N refut_N] . +qed +end + +context calculus_with_reduced_red_crit +begin + +(* cor:reduced-rc-implies-st-ref-comp-equiv-reduced-st-ref-comp 2/2 *) +lemma stat_ref_comp_imp_red_stat_ref_comp: "static_refutational_complete_calculus Bot Inf entails Red_Inf Red_F \ + reduc_static_refutational_complete_calculus Bot Inf entails Red_Inf Red_F" +proof + fix B N + assume + stat_ref_comp: "static_refutational_complete_calculus Bot Inf (\) Red_Inf Red_F" and + bot_elem: \B \ Bot\ and + saturated_N: "reduc_saturated N" and + refut_N: "N \ {B}" + have reduc_saturated_N: "saturated N" using saturated_N sat_eq_reduc_sat by blast + show "\B'\Bot. B' \ N" + using Calculi.static_refutational_complete_calculus.static_refutational_complete[OF stat_ref_comp + bot_elem reduc_saturated_N refut_N] . +qed +end + +context calculus_with_red_crit +begin + +definition Red_Red_Inf :: "'f set \ 'f inference set" where + "Red_Red_Inf N = Red_Inf N \ Inf_from2 UNIV (Red_F N)" + +lemma reduced_calc_is_calc: "calculus_with_red_crit Bot Inf entails Red_Red_Inf Red_F" +proof + fix N + show "Red_Red_Inf N \ Inf" + unfolding Red_Red_Inf_def Inf_from2_def Inf_from_def using Red_Inf_to_Inf by auto +next + fix B N + assume + b_in: "B \ Bot" and + n_entails: "N \ {B}" + show "N - Red_F N \ {B}" + by (simp add: Red_F_Bot b_in n_entails) +next + fix N N' :: "'f set" + assume "N \ N'" + then show "Red_F N \ Red_F N'" by (simp add: Red_F_of_subset) +next + fix N N' :: "'f set" + assume n_in: "N \ N'" + then have "Inf_from (UNIV - (Red_F N')) \ Inf_from (UNIV - (Red_F N))" + using Red_F_of_subset[OF n_in] unfolding Inf_from_def by auto + then have "Inf_from2 UNIV (Red_F N) \ Inf_from2 UNIV (Red_F N')" + unfolding Inf_from2_def by auto + then show "Red_Red_Inf N \ Red_Red_Inf N'" + unfolding Red_Red_Inf_def using Red_Inf_of_subset[OF n_in] by blast +next + fix N N' :: "'f set" + assume "N' \ Red_F N" + then show "Red_F N \ Red_F (N - N')" by (simp add: Red_F_of_Red_F_subset) +next + fix N N' :: "'f set" + assume np_subs: "N' \ Red_F N" + have "Red_F N \ Red_F (N - N')" by (simp add: Red_F_of_Red_F_subset np_subs) + then have "Inf_from (UNIV - (Red_F (N - N'))) \ Inf_from (UNIV - (Red_F N))" + by (metis Diff_subset Red_F_of_subset eq_iff) + then have "Inf_from2 UNIV (Red_F N) \ Inf_from2 UNIV (Red_F (N - N'))" + unfolding Inf_from2_def by auto + then show "Red_Red_Inf N \ Red_Red_Inf (N - N')" + unfolding Red_Red_Inf_def using Red_Inf_of_Red_F_subset[OF np_subs] by blast +next + fix \ N + assume "\ \ Inf" + "concl_of \ \ N" + then show "\ \ Red_Red_Inf N" + by (simp add: Red_Inf_of_Inf_to_N Red_Red_Inf_def) +qed + +lemma inf_subs_reduced_red_inf: "Inf_from2 UNIV (Red_F N) \ Red_Red_Inf N" + unfolding Red_Red_Inf_def by simp + +(* lem:red'-is-reduced-redcrit *) +text \The following is a lemma and not a sublocale as was previously used in similar cases. + Here, a sublocale cannot be used because it would create an infinitely descending + chain of sublocales. \ +lemma reduc_calc: "calculus_with_reduced_red_crit Bot Inf entails Red_Red_Inf Red_F" + using inf_subs_reduced_red_inf reduced_calc_is_calc + by (simp add: calculus_with_reduced_red_crit.intro calculus_with_reduced_red_crit_axioms_def) + +interpretation reduc_calc : calculus_with_reduced_red_crit Bot Inf entails Red_Red_Inf Red_F + using reduc_calc by simp + +(* lem:saturation-red-vs-red'-1 *) +lemma sat_imp_red_calc_sat: "saturated N \ reduc_calc.saturated N" + unfolding saturated_def reduc_calc.saturated_def Red_Red_Inf_def by blast + +(* lem:saturation-red-vs-red'-2 1/2 (i) \ (ii) *) +lemma red_sat_eq_red_calc_sat: "reduc_saturated N \ reduc_calc.saturated N" +proof + assume red_sat_n: "reduc_saturated N" + show "reduc_calc.saturated N" + unfolding reduc_calc.saturated_def + proof + fix \ + assume i_in: "\ \ Inf_from N" + show "\ \ Red_Red_Inf N" + using i_in red_sat_n unfolding reduc_saturated_def Inf_from2_def Inf_from_def Red_Red_Inf_def by blast + qed +next + assume red_sat_n: "reduc_calc.saturated N" + show "reduc_saturated N" + unfolding reduc_saturated_def + proof + fix \ + assume i_in: "\ \ Inf_from (N - Red_F N)" + show "\ \ Red_Inf N" + using i_in red_sat_n unfolding Inf_from_def reduc_calc.saturated_def Red_Red_Inf_def Inf_from2_def by blast + qed +qed + +(* lem:saturation-red-vs-red'-2 2/2 (i) \ (iii) *) +lemma red_sat_eq_sat: "reduc_saturated N \ saturated (N - Red_F N)" + unfolding reduc_saturated_def saturated_def by (simp add: Red_Inf_without_red_F) + +(* thm:reduced-stat-ref-compl 1/3 (i) \ (iii) *) +theorem stat_is_stat_red: "static_refutational_complete_calculus Bot Inf entails Red_Inf Red_F \ + static_refutational_complete_calculus Bot Inf entails Red_Red_Inf Red_F" +proof + assume + stat_ref1: "static_refutational_complete_calculus Bot Inf entails Red_Inf Red_F" + show "static_refutational_complete_calculus Bot Inf entails Red_Red_Inf Red_F" + using reduc_calc.calculus_with_red_crit_axioms + unfolding static_refutational_complete_calculus_def static_refutational_complete_calculus_axioms_def + proof + show "\B N. B \ Bot \ reduc_calc.saturated N \ N \ {B} \ (\B'\Bot. B' \ N)" + proof (clarify) + fix B N + assume + b_in: "B \ Bot" and + n_sat: "reduc_calc.saturated N" and + n_imp_b: "N \ {B}" + have "saturated (N - Red_F N)" using red_sat_eq_red_calc_sat[of N] red_sat_eq_sat[of N] n_sat by blast + moreover have "(N - Red_F N) \ {B}" using n_imp_b b_in by (simp add: reduc_calc.Red_F_Bot) + ultimately show "\B'\Bot. B'\ N" + using stat_ref1 by (meson DiffD1 b_in static_refutational_complete_calculus.static_refutational_complete) + qed + qed +next + assume + stat_ref3: "static_refutational_complete_calculus Bot Inf entails Red_Red_Inf Red_F" + show "static_refutational_complete_calculus Bot Inf entails Red_Inf Red_F" + unfolding static_refutational_complete_calculus_def static_refutational_complete_calculus_axioms_def + using calculus_with_red_crit_axioms + proof + show "\B N. B \ Bot \ saturated N \ N \ {B} \ (\B'\Bot. B' \ N)" + proof clarify + fix B N + assume + b_in: "B \ Bot" and + n_sat: "saturated N" and + n_imp_b: "N \ {B}" + then show "\B'\ Bot. B' \ N" + using stat_ref3 sat_imp_red_calc_sat[OF n_sat] + by (meson static_refutational_complete_calculus.static_refutational_complete) + qed + qed +qed + +(* thm:reduced-stat-ref-compl 2/3 (iv) \ (iii) *) +theorem red_stat_red_is_stat_red: "reduc_static_refutational_complete_calculus Bot Inf entails Red_Red_Inf Red_F \ + static_refutational_complete_calculus Bot Inf entails Red_Red_Inf Red_F" + using reduc_calc.stat_ref_comp_imp_red_stat_ref_comp + by (metis reduc_calc.sat_eq_reduc_sat reduc_static_refutational_complete_calculus.axioms(2) + reduc_static_refutational_complete_calculus_axioms_def reduced_calc_is_calc + static_refutational_complete_calculus.intro static_refutational_complete_calculus_axioms.intro) + +(* thm:reduced-stat-ref-compl 3/3 (ii) \ (iii) *) +theorem red_stat_is_stat_red: "reduc_static_refutational_complete_calculus Bot Inf entails Red_Inf Red_F \ + static_refutational_complete_calculus Bot Inf entails Red_Red_Inf Red_F" + using reduc_calc.calculus_with_red_crit_axioms calculus_with_red_crit_axioms red_sat_eq_red_calc_sat + unfolding static_refutational_complete_calculus_def static_refutational_complete_calculus_axioms_def + reduc_static_refutational_complete_calculus_def reduc_static_refutational_complete_calculus_axioms_def + by blast + +definition Sup_Red_F_llist :: "'f set llist \ 'f set" where +"Sup_Red_F_llist D = (\i \ {i. enat i < llength D}. Red_F (lnth D i))" + +lemma Sup_Red_F_unit: "Sup_Red_F_llist (LCons X LNil) = Red_F X" +using Sup_Red_F_llist_def enat_0_iff(1) by simp + +lemma sup_red_f_in_red_liminf: "chain derive D \ Sup_Red_F_llist D \ Red_F (Liminf_llist D)" +proof + fix N + assume + deriv: "chain derive D" and + n_in_sup: "N \ Sup_Red_F_llist D" + obtain i0 where i_smaller: "enat i0 < llength D" and n_in: "N \ Red_F (lnth D i0)" + using n_in_sup unfolding Sup_Red_F_llist_def by blast + have "Red_F (lnth D i0) \ Red_F (Liminf_llist D)" + using i_smaller by (simp add: deriv Red_F_subset_Liminf) + then show "N \ Red_F (Liminf_llist D)" + using n_in by fast +qed + +lemma sup_red_inf_in_red_liminf: "chain derive D \ Sup_Red_Inf_llist D \ Red_Inf (Liminf_llist D)" +proof + fix \ + assume + deriv: "chain derive D" and + i_in_sup: "\ \ Sup_Red_Inf_llist D" + obtain i0 where i_smaller: "enat i0 < llength D" and n_in: "\ \ Red_Inf (lnth D i0)" + using i_in_sup unfolding Sup_Red_Inf_llist_def by blast + have "Red_Inf (lnth D i0) \ Red_Inf (Liminf_llist D)" + using i_smaller by (simp add: deriv Red_Inf_subset_Liminf) + then show "\ \ Red_Inf (Liminf_llist D)" + using n_in by fast +qed + +definition reduc_fair :: "'f set llist \ bool" where +"reduc_fair D \ Inf_from (Liminf_llist D - (Sup_Red_F_llist D)) \ Sup_Red_Inf_llist D" + +(* lem:red-fairness-implies-red-saturation *) +lemma reduc_fair_imp_Liminf_reduc_sat: "chain derive D \ reduc_fair D \ reduc_saturated (Liminf_llist D)" + unfolding reduc_saturated_def +proof - + fix D + assume + deriv: "chain derive D" and + red_fair: "reduc_fair D" + have "Inf_from (Liminf_llist D - Red_F (Liminf_llist D)) \ Inf_from (Liminf_llist D - Sup_Red_F_llist D)" + using sup_red_f_in_red_liminf[OF deriv] unfolding Inf_from_def by blast + then have "Inf_from (Liminf_llist D - Red_F (Liminf_llist D)) \ Sup_Red_Inf_llist D" + using red_fair unfolding reduc_fair_def by simp + then show "Inf_from (Liminf_llist D - Red_F (Liminf_llist D)) \ Red_Inf (Liminf_llist D)" + using sup_red_inf_in_red_liminf[OF deriv] by fast +qed + +end + +locale reduc_dynamic_refutational_complete_calculus = calculus_with_red_crit + + assumes + reduc_dynamic_refutational_complete: "B \ Bot \ chain derive D \ reduc_fair D + \ lnth D 0 \ {B} \ \i \ {i. enat i < llength D}. \ B'\Bot. B' \ lnth D i" +begin + +sublocale reduc_static_refutational_complete_calculus +proof + fix B N + assume + bot_elem: \B \ Bot\ and + saturated_N: "reduc_saturated N" and + refut_N: "N \ {B}" + define D where "D = LCons N LNil" + have[simp]: \\ lnull D\ by (auto simp: D_def) + have deriv_D: \chain (\Red) D\ by (simp add: chain.chain_singleton D_def) + have liminf_is_N: "Liminf_llist D = N" by (simp add: D_def Liminf_llist_LCons) + have head_D: "N = lnth D 0" by (simp add: D_def) + have "Sup_Red_F_llist D = Red_F N" by (simp add: D_def Sup_Red_F_unit) + moreover have "Sup_Red_Inf_llist D = Red_Inf N" by (simp add: D_def Sup_Red_Inf_unit) + ultimately have fair_D: "reduc_fair D" + using saturated_N liminf_is_N unfolding reduc_fair_def reduc_saturated_def + by (simp add: reduc_fair_def reduc_saturated_def liminf_is_N) + obtain i B' where B'_is_bot: \B' \ Bot\ and B'_in: "B' \ (lnth D i)" and \i < llength D\ + using reduc_dynamic_refutational_complete[of B D] bot_elem fair_D head_D saturated_N deriv_D refut_N + by auto + then have "i = 0" + by (auto simp: D_def enat_0_iff) + show \\B'\Bot. B' \ N\ + using B'_is_bot B'_in unfolding \i = 0\ head_D[symmetric] by auto +qed + +end + +sublocale reduc_static_refutational_complete_calculus \ reduc_dynamic_refutational_complete_calculus +proof + fix B D + assume + bot_elem: \B \ Bot\ and + deriv: \chain (\Red) D\ and + fair: \reduc_fair D\ and + unsat: \(lnth D 0) \ {B}\ + have non_empty: \\ lnull D\ using chain_not_lnull[OF deriv] . + have subs: \(lnth D 0) \ Sup_llist D\ + using lhd_subset_Sup_llist[of D] non_empty by (simp add: lhd_conv_lnth) + have \Sup_llist D \ {B}\ + using unsat subset_entailed[OF subs] entails_trans[of "Sup_llist D" "lnth D 0"] by auto + then have Sup_no_Red: \Sup_llist D - Red_F (Sup_llist D) \ {B}\ + using bot_elem Red_F_Bot by auto + have Sup_no_Red_in_Liminf: \Sup_llist D - Red_F (Sup_llist D) \ Liminf_llist D\ + using deriv Red_in_Sup by auto + have Liminf_entails_Bot: \Liminf_llist D \ {B}\ + using Sup_no_Red subset_entailed[OF Sup_no_Red_in_Liminf] entails_trans by blast + have \reduc_saturated (Liminf_llist D)\ + using deriv fair reduc_fair_imp_Liminf_reduc_sat unfolding reduc_saturated_def + by auto + then have \\B'\Bot. B' \ (Liminf_llist D)\ + using bot_elem reduc_static_refutational_complete Liminf_entails_Bot + by auto + then show \\i\{i. enat i < llength D}. \B'\Bot. B' \ lnth D i\ + unfolding Liminf_llist_def by auto +qed + +context calculus_with_red_crit +begin + +lemma dyn_equiv_stat: "dynamic_refutational_complete_calculus Bot Inf entails Red_Inf Red_F = + static_refutational_complete_calculus Bot Inf entails Red_Inf Red_F" +proof + assume "dynamic_refutational_complete_calculus Bot Inf entails Red_Inf Red_F" + then interpret dynamic_refutational_complete_calculus Bot Inf entails Red_Inf Red_F + by simp + show "static_refutational_complete_calculus Bot Inf entails Red_Inf Red_F" + by (simp add: static_refutational_complete_calculus_axioms) +next + assume "static_refutational_complete_calculus Bot Inf entails Red_Inf Red_F" + then interpret static_refutational_complete_calculus Bot Inf entails Red_Inf Red_F + by simp + show "dynamic_refutational_complete_calculus Bot Inf entails Red_Inf Red_F" + by (simp add: dynamic_refutational_complete_calculus_axioms) +qed + +lemma red_dyn_equiv_red_stat: "reduc_dynamic_refutational_complete_calculus Bot Inf entails Red_Inf Red_F = + reduc_static_refutational_complete_calculus Bot Inf entails Red_Inf Red_F" +proof + assume "reduc_dynamic_refutational_complete_calculus Bot Inf entails Red_Inf Red_F" + then interpret reduc_dynamic_refutational_complete_calculus Bot Inf entails Red_Inf Red_F + by simp + show "reduc_static_refutational_complete_calculus Bot Inf entails Red_Inf Red_F" + by (simp add: reduc_static_refutational_complete_calculus_axioms) +next + assume "reduc_static_refutational_complete_calculus Bot Inf entails Red_Inf Red_F" + then interpret reduc_static_refutational_complete_calculus Bot Inf entails Red_Inf Red_F + by simp + show "reduc_dynamic_refutational_complete_calculus Bot Inf entails Red_Inf Red_F" + by (simp add: reduc_dynamic_refutational_complete_calculus_axioms) +qed + +interpretation reduc_calc : calculus_with_reduced_red_crit Bot Inf entails Red_Red_Inf Red_F +using reduc_calc by simp + +(* thm:reduced-dyn-ref-compl 1/3 (v) \ (vii) *) +theorem dyn_ref_eq_dyn_ref_red: "dynamic_refutational_complete_calculus Bot Inf entails Red_Inf Red_F \ + dynamic_refutational_complete_calculus Bot Inf entails Red_Red_Inf Red_F" + using dyn_equiv_stat stat_is_stat_red reduc_calc.dyn_equiv_stat by meson + +(* thm:reduced-dyn-ref-compl 2/3 (viii) \ (vii) *) +theorem red_dyn_ref_red_eq_dyn_ref_red: "reduc_dynamic_refutational_complete_calculus Bot Inf + entails Red_Red_Inf Red_F \ + dynamic_refutational_complete_calculus Bot Inf entails Red_Red_Inf Red_F" + using red_dyn_equiv_red_stat dyn_equiv_stat red_stat_red_is_stat_red + by (simp add: reduc_calc.dyn_equiv_stat reduc_calc.red_dyn_equiv_red_stat) + +(* thm:reduced-dyn-ref-compl 3/3 (vi) \ (vii) *) +theorem red_dyn_ref_eq_dyn_ref_red: "reduc_dynamic_refutational_complete_calculus Bot Inf entails Red_Inf Red_F \ + dynamic_refutational_complete_calculus Bot Inf entails Red_Red_Inf Red_F" + using red_dyn_equiv_red_stat dyn_equiv_stat red_stat_is_stat_red + reduc_calc.dyn_equiv_stat reduc_calc.red_dyn_equiv_red_stat + by blast + +end + +end diff --git a/thys/Saturation_Framework/Consequence_Relations_and_Inference_Systems.thy b/thys/Saturation_Framework/Consequence_Relations_and_Inference_Systems.thy new file mode 100644 --- /dev/null +++ b/thys/Saturation_Framework/Consequence_Relations_and_Inference_Systems.thy @@ -0,0 +1,100 @@ +(* Title: Consequence Relations and Inference Systems of the Saturation Framework + * Author: Sophie Tourret , 2018-2020 *) + +section \Consequence Relations and Inference Systems\ + +text \This section introduces the most basic notions upon which the framework is + built: consequence relations and inference systems. It also defines the notion + of a family of consequence relations. This corresponds to section 2.1 of the report.\ + +theory Consequence_Relations_and_Inference_Systems + imports + Main +begin + +subsection \Consequence Relations\ + +locale consequence_relation = + fixes + Bot :: "'f set" and + entails :: "'f set \ 'f set \ bool" (infix "\" 50) + assumes + bot_not_empty: "Bot \ {}" and + bot_implies_all: "B \ Bot \ {B} \ N1" and + subset_entailed: "N2 \ N1 \ N1 \ N2" and + all_formulas_entailed: "(\C \ N2. N1 \ {C}) \ N1 \ N2" and + entails_trans [trans]: "N1 \ N2 \ N2 \ N3 \ N1 \ N3" +begin + +lemma entail_set_all_formulas: "N1 \ N2 \ (\C \ N2. N1 \ {C})" + by (meson all_formulas_entailed empty_subsetI insert_subset subset_entailed entails_trans) + +lemma entail_union: "N \ N1 \ N \ N2 \ N \ N1 \ N2" + using entail_set_all_formulas[of N N1] entail_set_all_formulas[of N N2] + entail_set_all_formulas[of N "N1 \ N2"] by blast + +lemma entail_unions: "(\i \ I. N \ Ni i) \ N \ UNION I Ni" + using entail_set_all_formulas[of N "\ (Ni ` I)"] entail_set_all_formulas[of N] + Complete_Lattices.UN_ball_bex_simps(2)[of Ni I "\C. N \ {C}", symmetric] + by meson + +lemma entail_all_bot: "(\B \ Bot. N \ {B}) \ (\B' \ Bot. N \ {B'})" + using bot_implies_all entails_trans by blast + +end + +subsection \Families of Consequence Relations\ + +locale consequence_relation_family = + fixes + Bot :: "'f set" and + Q :: "'q itself" and + entails_q :: "'q \ ('f set \ 'f set \ bool)" + assumes + Bot_not_empty: "Bot \ {}" and + q_cons_rel: "consequence_relation Bot (entails_q q)" +begin + +definition entails_Q :: "'f set \ 'f set \ bool" (infix "\Q" 50) where + "(N1 \Q N2) = (\q. entails_q q N1 N2)" + +(* lem:intersection-of-conseq-rel *) +lemma intersect_cons_rel_family: "consequence_relation Bot entails_Q" + unfolding consequence_relation_def +proof (intro conjI) + show \Bot \ {}\ using Bot_not_empty . +next + show "\B N. B \ Bot \ {B} \Q N" + unfolding entails_Q_def by (metis consequence_relation_def q_cons_rel) +next + show "\N2 N1. N2 \ N1 \ N1 \Q N2" + unfolding entails_Q_def by (metis consequence_relation_def q_cons_rel) +next + show "\N2 N1. (\C\N2. N1 \Q {C}) \ N1 \Q N2" + unfolding entails_Q_def by (metis consequence_relation_def q_cons_rel) +next + show "\N1 N2 N3. N1 \Q N2 \ N2 \Q N3 \ N1 \Q N3" + unfolding entails_Q_def by (metis consequence_relation_def q_cons_rel) +qed + +end + +subsection \Inference Systems\ + +datatype 'f inference = + Infer (prems_of: "'f list") (concl_of: "'f") + +locale inference_system = + fixes + Inf :: \'f inference set\ +begin + +definition Inf_from :: "'f set \ 'f inference set" where + "Inf_from N = {\ \ Inf. set (prems_of \) \ N}" + +definition Inf_from2 :: "'f set \ 'f set \ 'f inference set" where + "Inf_from2 N M = Inf_from (N \ M) - Inf_from (N - M)" + +end + +end diff --git a/thys/Saturation_Framework/Labeled_Lifting_to_Non_Ground_Calculi.thy b/thys/Saturation_Framework/Labeled_Lifting_to_Non_Ground_Calculi.thy new file mode 100644 --- /dev/null +++ b/thys/Saturation_Framework/Labeled_Lifting_to_Non_Ground_Calculi.thy @@ -0,0 +1,434 @@ +(* Title: Labeled Lifting to Non-Ground Calculi of the Saturation Framework + * Author: Sophie Tourret , 2019-2020 *) + +section \Labeled Liftings\ + +text \This section formalizes the extension of the lifting results to labeled + calculi. This corresponds to section 3.4 of the report.\ + +theory Labeled_Lifting_to_Non_Ground_Calculi + imports Lifting_to_Non_Ground_Calculi +begin + +subsection \Labeled Lifting with a Family of Well-founded Orderings\ + +locale labeled_lifting_w_wf_ord_family = + lifting_with_wf_ordering_family Bot_F Inf_F Bot_G entails_G Inf_G Red_Inf_G Red_F_G \_F \_Inf Prec_F + for + Bot_F :: "'f set" and + Inf_F :: "'f inference set" and + Bot_G :: "'g set" and + entails_G :: "'g set \ 'g set \ bool" (infix "\G" 50) and + Inf_G :: "'g inference set" and + Red_Inf_G :: "'g set \ 'g inference set" and + Red_F_G :: "'g set \ 'g set" and + \_F :: "'f \ 'g set" and + \_Inf :: "'f inference \ 'g inference set option" and + Prec_F :: "'g \ 'f \ 'f \ bool" (infix "\" 50) + + fixes + l :: \'l itself\ and + Inf_FL :: \('f \ 'l) inference set\ + assumes + Inf_F_to_Inf_FL: \\\<^sub>F \ Inf_F \ length (Ll :: 'l list) = length (prems_of \\<^sub>F) \ + \L0. Infer (zip (prems_of \\<^sub>F) Ll) (concl_of \\<^sub>F, L0) \ Inf_FL\ and + Inf_FL_to_Inf_F: \\\<^sub>F\<^sub>L \ Inf_FL \ Infer (map fst (prems_of \\<^sub>F\<^sub>L)) (fst (concl_of \\<^sub>F\<^sub>L)) \ Inf_F\ +begin + +definition to_F :: \('f \ 'l) inference \ 'f inference\ where + \to_F \\<^sub>F\<^sub>L = Infer (map fst (prems_of \\<^sub>F\<^sub>L)) (fst (concl_of \\<^sub>F\<^sub>L))\ + +definition Bot_FL :: \('f \ 'l) set\ where \Bot_FL = Bot_F \ UNIV\ + +definition \_F_L :: \('f \ 'l) \ 'g set\ where \\_F_L CL = \_F (fst CL)\ + +definition \_Inf_L :: \('f \ 'l) inference \ 'g inference set option\ where \\_Inf_L \\<^sub>F\<^sub>L = \_Inf (to_F \\<^sub>F\<^sub>L)\ + +(* lem:labeled-grounding-function *) +sublocale labeled_standard_lifting: standard_lifting + where + Bot_F = Bot_FL and + Inf_F = Inf_FL and + \_F = \_F_L and + \_Inf = \_Inf_L +proof + show "Bot_FL \ {}" + unfolding Bot_FL_def using Bot_F_not_empty by simp +next + show "B\Bot_FL \ \_F_L B \ {}" for B + unfolding \_F_L_def Bot_FL_def using Bot_map_not_empty by auto +next + show "B\Bot_FL \ \_F_L B \ Bot_G" for B + unfolding \_F_L_def Bot_FL_def using Bot_map by force +next + fix CL + show "\_F_L CL \ Bot_G \ {} \ CL \ Bot_FL" + unfolding \_F_L_def Bot_FL_def using Bot_cond + by (metis SigmaE UNIV_I UNIV_Times_UNIV mem_Sigma_iff prod.sel(1)) +next + fix \ + assume + i_in: \\ \ Inf_FL\ and + ground_not_none: \\_Inf_L \ \ None\ + then show "the (\_Inf_L \) \ Red_Inf_G (\_F_L (concl_of \))" + unfolding \_Inf_L_def \_F_L_def to_F_def using inf_map Inf_FL_to_Inf_F by fastforce +qed + +abbreviation Labeled_Empty_Order :: \ ('f \ 'l) \ ('f \ 'l) \ bool\ where + "Labeled_Empty_Order C1 C2 \ False" + +sublocale labeled_lifting_w_empty_ord_family : + lifting_with_wf_ordering_family Bot_FL Inf_FL Bot_G entails_G Inf_G Red_Inf_G Red_F_G + \_F_L \_Inf_L "\g. Labeled_Empty_Order" +proof + show "po_on Labeled_Empty_Order UNIV" + unfolding po_on_def by (simp add: transp_onI wfp_on_imp_irreflp_on) + show "wfp_on Labeled_Empty_Order UNIV" + unfolding wfp_on_def by simp +qed + +notation "labeled_standard_lifting.entails_\" (infix "\\L" 50) + +(* lem:labeled-consequence *) +lemma labeled_entailment_lifting: "NL1 \\L NL2 \ fst ` NL1 \\ fst ` NL2" + unfolding labeled_standard_lifting.entails_\_def \_F_L_def entails_\_def by auto + +lemma (in-) subset_fst: "A \ fst ` AB \ \x \ A. \y. (x,y) \ AB" by fastforce + +lemma red_inf_impl: "\ \ labeled_lifting_w_empty_ord_family.Red_Inf_\ NL \ to_F \ \ Red_Inf_\ (fst ` NL)" + unfolding labeled_lifting_w_empty_ord_family.Red_Inf_\_def Red_Inf_\_def \_Inf_L_def \_F_L_def to_F_def + using Inf_FL_to_Inf_F by auto + +(* lem:labeled-saturation *) +lemma labeled_saturation_lifting: + "labeled_lifting_w_empty_ord_family.lifted_calculus_with_red_crit.saturated NL \ + empty_order_lifting.lifted_calculus_with_red_crit.saturated (fst ` NL)" + unfolding labeled_lifting_w_empty_ord_family.lifted_calculus_with_red_crit.saturated_def + empty_order_lifting.lifted_calculus_with_red_crit.saturated_def + labeled_standard_lifting.Non_ground.Inf_from_def Non_ground.Inf_from_def +proof clarify + fix \ + assume + subs_Red_Inf: "{\ \ Inf_FL. set (prems_of \) \ NL} \ labeled_lifting_w_empty_ord_family.Red_Inf_\ NL" and + i_in: "\ \ Inf_F" and + i_prems: "set (prems_of \) \ fst ` NL" + define Lli where "Lli i \ (SOME x. ((prems_of \)!i,x) \ NL)" for i + have [simp]:"((prems_of \)!i,Lli i) \ NL" if "i < length (prems_of \)" for i + using that subset_fst[OF i_prems] unfolding Lli_def by (meson nth_mem someI_ex) + define Ll where "Ll \ map Lli [0..)]" + have Ll_length: "length Ll = length (prems_of \)" unfolding Ll_def by auto + have subs_NL: "set (zip (prems_of \) Ll) \ NL" unfolding Ll_def by (auto simp:in_set_zip) + obtain L0 where L0: "Infer (zip (prems_of \) Ll) (concl_of \, L0) \ Inf_FL" + using Inf_F_to_Inf_FL[OF i_in Ll_length] .. + define \_FL where "\_FL = Infer (zip (prems_of \) Ll) (concl_of \, L0)" + then have "set (prems_of \_FL) \ NL" using subs_NL by simp + then have "\_FL \ {\ \ Inf_FL. set (prems_of \) \ NL}" unfolding \_FL_def using L0 by blast + then have "\_FL \ labeled_lifting_w_empty_ord_family.Red_Inf_\ NL" using subs_Red_Inf by fast + moreover have "\ = to_F \_FL" unfolding to_F_def \_FL_def using Ll_length by (cases \) auto + ultimately show "\ \ Red_Inf_\ (fst ` NL)" by (auto intro:red_inf_impl) +qed + +(* lem:labeled-static-ref-compl *) +lemma stat_ref_comp_to_labeled_sta_ref_comp: "static_refutational_complete_calculus Bot_F Inf_F (\\) Red_Inf_\ Red_F_\ \ + static_refutational_complete_calculus Bot_FL Inf_FL (\\L) + labeled_lifting_w_empty_ord_family.Red_Inf_\ labeled_lifting_w_empty_ord_family.Red_F_\" + unfolding static_refutational_complete_calculus_def +proof (rule conjI impI; clarify) + interpret calculus_with_red_crit Bot_FL Inf_FL labeled_standard_lifting.entails_\ + labeled_lifting_w_empty_ord_family.Red_Inf_\ labeled_lifting_w_empty_ord_family.Red_F_\ + by (simp add: + labeled_lifting_w_empty_ord_family.lifted_calculus_with_red_crit.calculus_with_red_crit_axioms) + show "calculus_with_red_crit Bot_FL Inf_FL (\\L) labeled_lifting_w_empty_ord_family.Red_Inf_\ + labeled_lifting_w_empty_ord_family.Red_F_\" + by standard +next + assume + calc: "calculus_with_red_crit Bot_F Inf_F (\\) Red_Inf_\ Red_F_\" and + static: "static_refutational_complete_calculus_axioms Bot_F Inf_F (\\) Red_Inf_\" + show "static_refutational_complete_calculus_axioms Bot_FL Inf_FL (\\L) + labeled_lifting_w_empty_ord_family.Red_Inf_\" + unfolding static_refutational_complete_calculus_axioms_def + proof (intro conjI impI allI) + fix Bl :: \'f \ 'l\ and Nl :: \('f \ 'l) set\ + assume + Bl_in: \Bl \ Bot_FL\ and + Nl_sat: \labeled_lifting_w_empty_ord_family.lifted_calculus_with_red_crit.saturated Nl\ and + Nl_entails_Bl: \Nl \\L {Bl}\ + have static_axioms: "B \ Bot_F \ empty_order_lifting.lifted_calculus_with_red_crit.saturated N \ + N \\ {B} \ (\B'\Bot_F. B' \ N)" for B N + using static[unfolded static_refutational_complete_calculus_axioms_def] by fast + define B where "B = fst Bl" + have B_in: "B \ Bot_F" using Bl_in Bot_FL_def B_def SigmaE by force + define N where "N = fst ` Nl" + have N_sat: "empty_order_lifting.lifted_calculus_with_red_crit.saturated N" + using N_def Nl_sat labeled_saturation_lifting by blast + have N_entails_B: "N \\ {B}" + using Nl_entails_Bl unfolding labeled_entailment_lifting N_def B_def by force + have "\B' \ Bot_F. B' \ N" using B_in N_sat N_entails_B static_axioms[of B N] by blast + then obtain B' where in_Bot: "B' \ Bot_F" and in_N: "B' \ N" by force + then have "B' \ fst ` Bot_FL" unfolding Bot_FL_def by fastforce + obtain Bl' where in_Nl: "Bl' \ Nl" and fst_Bl': "fst Bl' = B'" + using in_N unfolding N_def by blast + have "Bl' \ Bot_FL" unfolding Bot_FL_def using fst_Bl' in_Bot vimage_fst by fastforce + then show \\Bl'\Bot_FL. Bl' \ Nl\ using in_Nl by blast + qed +qed + +end + +subsection \Labeled Lifting with a Family of Redundancy Criteria\ + +locale labeled_lifting_with_red_crit_family = no_labels: standard_lifting_with_red_crit_family Inf_F + Bot_G Inf_G Q entails_q Red_Inf_q Red_F_q Bot_F \_F_q \_Inf_q "\g. Empty_Order" + for + Bot_F :: "'f set" and + Inf_F :: "'f inference set" and + Bot_G :: "'g set" and + Q :: "'q itself" and + entails_q :: "'q \ 'g set \ 'g set \ bool" and + Inf_G :: "'g inference set" and + Red_Inf_q :: "'q \ 'g set \ 'g inference set" and + Red_F_q :: "'q \ 'g set \ 'g set" and + \_F_q :: "'q \ 'f \ 'g set" and + \_Inf_q :: "'q \ 'f inference \ 'g inference set option" + + fixes + l :: "'l itself" and + Inf_FL :: \('f \ 'l) inference set\ + assumes + Inf_F_to_Inf_FL: \\\<^sub>F \ Inf_F \ length (Ll :: 'l list) = length (prems_of \\<^sub>F) \ \L0. Infer (zip (prems_of \\<^sub>F) Ll) (concl_of \\<^sub>F, L0) \ Inf_FL\ and + Inf_FL_to_Inf_F: \\\<^sub>F\<^sub>L \ Inf_FL \ Infer (map fst (prems_of \\<^sub>F\<^sub>L)) (fst (concl_of \\<^sub>F\<^sub>L)) \ Inf_F\ +begin + +definition to_F :: \('f \ 'l) inference \ 'f inference\ where + \to_F \\<^sub>F\<^sub>L = Infer (map fst (prems_of \\<^sub>F\<^sub>L)) (fst (concl_of \\<^sub>F\<^sub>L))\ + +definition Bot_FL :: \('f \ 'l) set\ where \Bot_FL = Bot_F \ UNIV\ + +definition \_F_L_q :: \'q \ ('f \ 'l) \ 'g set\ where \\_F_L_q q CL = \_F_q q (fst CL)\ + +definition \_Inf_L_q :: \'q \ ('f \ 'l) inference \ 'g inference set option\ where + \\_Inf_L_q q \\<^sub>F\<^sub>L = \_Inf_q q (to_F \\<^sub>F\<^sub>L)\ + +definition \_set_L_q :: "'q \ ('f \ 'l) set \ 'g set" where + "\_set_L_q q N \ UNION N (\_F_L_q q)" + +definition Red_Inf_\_L_q :: "'q \ ('f \ 'l) set \ ('f \ 'l) inference set" where + "Red_Inf_\_L_q q N = {\ \ Inf_FL. ((\_Inf_L_q q \) \ None \ the (\_Inf_L_q q \) \ Red_Inf_q q (\_set_L_q q N)) + \ ((\_Inf_L_q q \ = None) \ \_F_L_q q (concl_of \) \ (\_set_L_q q N \ Red_F_q q (\_set_L_q q N)))}" + +definition Red_Inf_\_L_Q :: "('f \ 'l) set \ ('f \ 'l) inference set" where + "Red_Inf_\_L_Q N = \ {X N |X. X \ (Red_Inf_\_L_q ` UNIV)}" + +definition Labeled_Empty_Order :: \ ('f \ 'l) \ ('f \ 'l) \ bool\ where + "Labeled_Empty_Order C1 C2 \ False" + +definition Red_F_\_empty_L_q :: "'q \ ('f \ 'l) set \ ('f \ 'l) set" where + "Red_F_\_empty_L_q q N = {C. \D \ \_F_L_q q C. D \ Red_F_q q (\_set_L_q q N) \ + (\E \ N. Labeled_Empty_Order E C \ D \ \_F_L_q q E)}" + +definition Red_F_\_empty_L :: "('f \ 'l) set \ ('f \ 'l) set" where + "Red_F_\_empty_L N = \ {X N |X. X \ (Red_F_\_empty_L_q ` UNIV)}" + +definition entails_\_L_q :: "'q \ ('f \ 'l) set \ ('f \ 'l) set \ bool" where + "entails_\_L_q q N1 N2 \ entails_q q (\_set_L_q q N1) (\_set_L_q q N2)" + +definition entails_\_L_Q :: "('f \ 'l) set \ ('f \ 'l) set \ bool" (infix "\\L" 50) where + "entails_\_L_Q N1 N2 \ \q. entails_\_L_q q N1 N2" + +lemma lifting_q: "labeled_lifting_w_wf_ord_family Bot_F Inf_F Bot_G (entails_q q) Inf_G (Red_Inf_q q) + (Red_F_q q) (\_F_q q) (\_Inf_q q) (\g. Empty_Order) Inf_FL" +proof - + fix q + show "labeled_lifting_w_wf_ord_family Bot_F Inf_F Bot_G (entails_q q) Inf_G (Red_Inf_q q) + (Red_F_q q) (\_F_q q) (\_Inf_q q) (\g. Empty_Order) Inf_FL" + using no_labels.standard_lifting_family Inf_F_to_Inf_FL Inf_FL_to_Inf_F + by (simp add: labeled_lifting_w_wf_ord_family_axioms_def labeled_lifting_w_wf_ord_family_def) +qed + +lemma lifted_q: "standard_lifting Bot_FL Inf_FL Bot_G Inf_G (entails_q q) (Red_Inf_q q) + (Red_F_q q) (\_F_L_q q) (\_Inf_L_q q)" +proof - + fix q + interpret q_lifting: labeled_lifting_w_wf_ord_family Bot_F Inf_F Bot_G "entails_q q" Inf_G + "Red_Inf_q q" "Red_F_q q" "\_F_q q" "\_Inf_q q" "\g. Empty_Order" l Inf_FL + using lifting_q . + have "\_F_L_q q = q_lifting.\_F_L" + unfolding \_F_L_q_def q_lifting.\_F_L_def by simp + moreover have "\_Inf_L_q q = q_lifting.\_Inf_L" + unfolding \_Inf_L_q_def q_lifting.\_Inf_L_def to_F_def q_lifting.to_F_def by simp + moreover have "Bot_FL = q_lifting.Bot_FL" + unfolding Bot_FL_def q_lifting.Bot_FL_def by simp + ultimately show "standard_lifting Bot_FL Inf_FL Bot_G Inf_G (entails_q q) (Red_Inf_q q) (Red_F_q q) + (\_F_L_q q) (\_Inf_L_q q)" + using q_lifting.labeled_standard_lifting.standard_lifting_axioms by simp +qed + +lemma ord_fam_lifted_q: "lifting_with_wf_ordering_family Bot_FL Inf_FL Bot_G (entails_q q) Inf_G + (Red_Inf_q q) (Red_F_q q) (\_F_L_q q) (\_Inf_L_q q) (\g. Labeled_Empty_Order)" +proof - + fix q + interpret standard_q_lifting: standard_lifting Bot_FL Inf_FL Bot_G Inf_G "entails_q q" + "Red_Inf_q q" "Red_F_q q" "\_F_L_q q" "\_Inf_L_q q" + using lifted_q . + have "minimal_element Labeled_Empty_Order UNIV" + unfolding Labeled_Empty_Order_def + by (simp add: minimal_element.intro po_on_def transp_onI wfp_on_imp_irreflp_on) + then show "lifting_with_wf_ordering_family Bot_FL Inf_FL Bot_G (entails_q q) Inf_G + (Red_Inf_q q) (Red_F_q q) (\_F_L_q q) (\_Inf_L_q q) (\g. Labeled_Empty_Order)" + using standard_q_lifting.standard_lifting_axioms + by (simp add: lifting_with_wf_ordering_family_axioms.intro lifting_with_wf_ordering_family_def) +qed + +lemma all_lifted_red_crit: "calculus_with_red_crit Bot_FL Inf_FL (entails_\_L_q q) (Red_Inf_\_L_q q) + (Red_F_\_empty_L_q q)" +proof - + fix q + interpret ord_q_lifting: lifting_with_wf_ordering_family Bot_FL Inf_FL Bot_G "entails_q q" Inf_G + "Red_Inf_q q" "Red_F_q q" "\_F_L_q q" "\_Inf_L_q q" "\g. Labeled_Empty_Order" + using ord_fam_lifted_q . + have "entails_\_L_q q = ord_q_lifting.entails_\" + unfolding entails_\_L_q_def \_set_L_q_def ord_q_lifting.entails_\_def by simp + moreover have "Red_Inf_\_L_q q = ord_q_lifting.Red_Inf_\" + unfolding Red_Inf_\_L_q_def ord_q_lifting.Red_Inf_\_def \_set_L_q_def by simp + moreover have "Red_F_\_empty_L_q q = ord_q_lifting.Red_F_\" + unfolding Red_F_\_empty_L_q_def ord_q_lifting.Red_F_\_def \_set_L_q_def by simp + ultimately show "calculus_with_red_crit Bot_FL Inf_FL (entails_\_L_q q) (Red_Inf_\_L_q q) + (Red_F_\_empty_L_q q)" + using ord_q_lifting.lifted_calculus_with_red_crit.calculus_with_red_crit_axioms by argo +qed + +lemma all_lifted_cons_rel: "consequence_relation Bot_FL (entails_\_L_q q)" +proof - + fix q + interpret q_red_crit: calculus_with_red_crit Bot_FL Inf_FL "entails_\_L_q q" "Red_Inf_\_L_q q" + "Red_F_\_empty_L_q q" + using all_lifted_red_crit . + show "consequence_relation Bot_FL (entails_\_L_q q)" + using q_red_crit.consequence_relation_axioms . +qed + +sublocale labeled_cons_rel_family: consequence_relation_family Bot_FL Q entails_\_L_q + using all_lifted_cons_rel no_labels.lifted_calc_w_red_crit_family.Bot_not_empty + unfolding Bot_FL_def + by (simp add: consequence_relation_family.intro) + +sublocale with_labels: calculus_with_red_crit_family Bot_FL Inf_FL Q entails_\_L_q Red_Inf_\_L_q + Red_F_\_empty_L_q + using calculus_with_red_crit_family.intro[OF labeled_cons_rel_family.consequence_relation_family_axioms] + all_lifted_cons_rel + by (simp add: all_lifted_red_crit calculus_with_red_crit_family_axioms_def) + +notation "no_labels.entails_\_Q" (infix "\\" 50) + +(* lem:labeled-consequence-intersection *) +lemma labeled_entailment_lifting: "NL1 \\L NL2 \ fst ` NL1 \\ fst ` NL2" + unfolding no_labels.entails_\_Q_def no_labels.entails_\_q_def no_labels.\_set_q_def + entails_\_L_Q_def entails_\_L_q_def \_set_L_q_def \_F_L_q_def + by force + +lemma subset_fst: "A \ fst ` AB \ \x \ A. \y. (x,y) \ AB" by fastforce + +lemma red_inf_impl: "\ \ with_labels.Red_Inf_Q NL \ + to_F \ \ no_labels.empty_ord_lifted_calc_w_red_crit_family.Red_Inf_Q (fst ` NL)" + unfolding no_labels.empty_ord_lifted_calc_w_red_crit_family.Red_Inf_Q_def with_labels.Red_Inf_Q_def +proof clarify + fix X Xa q + assume + i_in_inter: "\ \ \ {X NL |X. X \ Red_Inf_\_L_q ` UNIV}" + have i_in_q: "\ \ Red_Inf_\_L_q q NL" using i_in_inter image_eqI by blast + then have i_in: "\ \ Inf_FL" unfolding Red_Inf_\_L_q_def by blast + have to_F_in: "to_F \ \ Inf_F" unfolding to_F_def using Inf_FL_to_Inf_F[OF i_in] . + have rephrase1: "(\CL\NL. \_F_q q (fst CL)) = (\ (\_F_q q ` fst ` NL))" by blast + have rephrase2: "fst (concl_of \) = concl_of (to_F \)" + unfolding concl_of_def to_F_def by simp + have subs_red: "((\_Inf_L_q q \) \ None \ the (\_Inf_L_q q \) \ Red_Inf_q q (\_set_L_q q NL)) + \ ((\_Inf_L_q q \ = None) \ \_F_L_q q (concl_of \) \ (\_set_L_q q NL \ Red_F_q q (\_set_L_q q NL)))" + using i_in_q unfolding Red_Inf_\_L_q_def by blast + then have to_F_subs_red: "((\_Inf_q q (to_F \)) \ None \ + the (\_Inf_q q (to_F \)) \ Red_Inf_q q (no_labels.\_set_q q (fst ` NL))) + \ ((\_Inf_q q (to_F \) = None) \ + \_F_q q (concl_of (to_F \)) \ (no_labels.\_set_q q (fst ` NL) \ Red_F_q q (no_labels.\_set_q q (fst ` NL))))" + unfolding \_Inf_L_q_def \_set_L_q_def no_labels.\_set_q_def \_F_L_q_def + using rephrase1 rephrase2 by metis + then show "to_F \ \ no_labels.Red_Inf_\_q q (fst ` NL)" + using to_F_in unfolding no_labels.Red_Inf_\_q_def by simp +qed + +(* lem:labeled-saturation-intersection *) +lemma labeled_family_saturation_lifting: "with_labels.inter_red_crit_calculus.saturated NL \ + no_labels.lifted_calc_w_red_crit_family.inter_red_crit_calculus.saturated (fst ` NL)" + unfolding with_labels.inter_red_crit_calculus.saturated_def + no_labels.lifted_calc_w_red_crit_family.inter_red_crit_calculus.saturated_def + with_labels.Inf_from_def no_labels.Non_ground.Inf_from_def +proof clarify + fix \F + assume + labeled_sat: "{\ \ Inf_FL. set (prems_of \) \ NL} \ with_labels.Red_Inf_Q NL" and + iF_in: "\F \ Inf_F" and + iF_prems: "set (prems_of \F) \ fst ` NL" + define Lli where "Lli i \ (SOME x. ((prems_of \F)!i,x) \ NL)" for i + have [simp]:"((prems_of \F)!i,Lli i) \ NL" if "i < length (prems_of \F)" for i + using that subset_fst[OF iF_prems] nth_mem someI_ex unfolding Lli_def + by metis + define Ll where "Ll \ map Lli [0..F)]" + have Ll_length: "length Ll = length (prems_of \F)" unfolding Ll_def by auto + have subs_NL: "set (zip (prems_of \F) Ll) \ NL" unfolding Ll_def by (auto simp:in_set_zip) + obtain L0 where L0: "Infer (zip (prems_of \F) Ll) (concl_of \F, L0) \ Inf_FL" + using Inf_F_to_Inf_FL[OF iF_in Ll_length] .. + define \FL where "\FL = Infer (zip (prems_of \F) Ll) (concl_of \F, L0)" + then have "set (prems_of \FL) \ NL" using subs_NL by simp + then have "\FL \ {\ \ Inf_FL. set (prems_of \) \ NL}" unfolding \FL_def using L0 by blast + then have "\FL \ with_labels.Red_Inf_Q NL" using labeled_sat by fast + moreover have "\F = to_F \FL" unfolding to_F_def \FL_def using Ll_length by (cases \F) auto + ultimately show "\F \ no_labels.empty_ord_lifted_calc_w_red_crit_family.Red_Inf_Q (fst ` NL)" + by (auto intro:red_inf_impl) +qed + +(* thm:labeled-static-ref-compl-intersection *) +theorem labeled_static_ref: "static_refutational_complete_calculus Bot_F Inf_F (\\) + no_labels.empty_ord_lifted_calc_w_red_crit_family.Red_Inf_Q + no_labels.empty_ord_lifted_calc_w_red_crit_family.Red_F_Q + \ static_refutational_complete_calculus Bot_FL Inf_FL (\\L) with_labels.Red_Inf_Q with_labels.Red_F_Q" + unfolding static_refutational_complete_calculus_def +proof (rule conjI impI; clarify) + show "calculus_with_red_crit Bot_FL Inf_FL (\\L) with_labels.Red_Inf_Q with_labels.Red_F_Q" + using with_labels.inter_red_crit_calculus.calculus_with_red_crit_axioms + unfolding labeled_cons_rel_family.entails_Q_def entails_\_L_Q_def . +next + assume + calc: "calculus_with_red_crit Bot_F Inf_F (\\) + no_labels.empty_ord_lifted_calc_w_red_crit_family.Red_Inf_Q + no_labels.empty_ord_lifted_calc_w_red_crit_family.Red_F_Q" and + static: "static_refutational_complete_calculus_axioms Bot_F Inf_F (\\) + no_labels.empty_ord_lifted_calc_w_red_crit_family.Red_Inf_Q" + show "static_refutational_complete_calculus_axioms Bot_FL Inf_FL (\\L) with_labels.Red_Inf_Q" + unfolding static_refutational_complete_calculus_axioms_def + proof (intro conjI impI allI) + fix Bl :: \'f \ 'l\ and Nl :: \('f \ 'l) set\ + assume + Bl_in: \Bl \ Bot_FL\ and + Nl_sat: \with_labels.inter_red_crit_calculus.saturated Nl\ and + Nl_entails_Bl: \Nl \\L {Bl}\ + have static_axioms: "B \ Bot_F \ + no_labels.lifted_calc_w_red_crit_family.inter_red_crit_calculus.saturated N \ + N \\ {B} \ (\B'\Bot_F. B' \ N)" for B N + using static[unfolded static_refutational_complete_calculus_axioms_def] by fast + define B where "B = fst Bl" + have B_in: "B \ Bot_F" using Bl_in Bot_FL_def B_def SigmaE by force + define N where "N = fst ` Nl" + have N_sat: "no_labels.lifted_calc_w_red_crit_family.inter_red_crit_calculus.saturated N" + using N_def Nl_sat labeled_family_saturation_lifting by blast + have N_entails_B: "N \\ {B}" + using Nl_entails_Bl unfolding labeled_entailment_lifting N_def B_def by force + have "\B' \ Bot_F. B' \ N" using B_in N_sat N_entails_B static_axioms[of B N] by blast + then obtain B' where in_Bot: "B' \ Bot_F" and in_N: "B' \ N" by force + then have "B' \ fst ` Bot_FL" unfolding Bot_FL_def by fastforce + obtain Bl' where in_Nl: "Bl' \ Nl" and fst_Bl': "fst Bl' = B'" + using in_N unfolding N_def by blast + have "Bl' \ Bot_FL" unfolding Bot_FL_def using fst_Bl' in_Bot vimage_fst by fastforce + then show \\Bl'\Bot_FL. Bl' \ Nl\ using in_Nl by blast + qed +qed + +end + +end diff --git a/thys/Saturation_Framework/Lifting_to_Non_Ground_Calculi.thy b/thys/Saturation_Framework/Lifting_to_Non_Ground_Calculi.thy new file mode 100644 --- /dev/null +++ b/thys/Saturation_Framework/Lifting_to_Non_Ground_Calculi.thy @@ -0,0 +1,865 @@ +(* Title: Lifting to Non-Ground Calculi of the Saturation Framework + * Author: Sophie Tourret , 2018-2020 *) + +section \Lifting to Non-ground Calculi\ + +text \The section 3.1 to 3.3 of the report are covered by the current section. + Various forms of lifting are proven correct. These allow to obtain the dynamic + refutational completeness of a non-ground calculus from the static refutational + completeness of its ground counterpart.\ + +theory Lifting_to_Non_Ground_Calculi + imports + Calculi + Well_Quasi_Orders.Minimal_Elements +begin + +subsection \Standard Lifting\ + +locale standard_lifting = Non_ground: inference_system Inf_F + + Ground: calculus_with_red_crit Bot_G Inf_G entails_G Red_Inf_G Red_F_G + for + Bot_F :: \'f set\ and + Inf_F :: \'f inference set\ and + Bot_G :: \'g set\ and + Inf_G :: \'g inference set\ and + entails_G :: \'g set \ 'g set \ bool\ (infix "\G" 50) and + Red_Inf_G :: \'g set \ 'g inference set\ and + Red_F_G :: \'g set \ 'g set\ + + fixes + \_F :: \'f \ 'g set\ and + \_Inf :: \'f inference \ 'g inference set option\ + assumes + Bot_F_not_empty: "Bot_F \ {}" and + Bot_map_not_empty: \B \ Bot_F \ \_F B \ {}\ and + Bot_map: \B \ Bot_F \ \_F B \ Bot_G\ and + Bot_cond: \\_F C \ Bot_G \ {} \ C \ Bot_F\ and + inf_map: \\ \ Inf_F \ \_Inf \ \ None \ the (\_Inf \) \ Red_Inf_G (\_F (concl_of \))\ +begin + +abbreviation \_set :: \'f set \ 'g set\ where + \\_set N \ UNION N \_F\ + +lemma \_subset: \N1 \ N2 \ \_set N1 \ \_set N2\ by auto + +definition entails_\ :: \'f set \ 'f set \ bool\ (infix "\\" 50) where + \N1 \\ N2 \ \_set N1 \G \_set N2\ + +lemma subs_Bot_G_entails: + assumes + not_empty: \sB \ {}\ and + in_bot: \sB \ Bot_G\ + shows \sB \G N\ +proof - + have \\B. B \ sB\ using not_empty by auto + then obtain B where B_in: \B \ sB\ by auto + then have r_trans: \{B} \G N\ using Ground.bot_implies_all in_bot by auto + have l_trans: \sB \G {B}\ using B_in Ground.subset_entailed by auto + then show ?thesis using r_trans Ground.entails_trans[of sB "{B}"] by auto +qed + +(* lem:derived-consequence-relation *) +sublocale lifted_consequence_relation: consequence_relation + where Bot=Bot_F and entails=entails_\ +proof + show "Bot_F \ {}" using Bot_F_not_empty . +next + show \B\Bot_F \ {B} \\ N\ for B N + proof - + assume \B \ Bot_F\ + then show \{B} \\ N\ + using Bot_map Ground.bot_implies_all[of _ "\_set N"] subs_Bot_G_entails Bot_map_not_empty + unfolding entails_\_def + by auto + qed +next + fix N1 N2 :: \'f set\ + assume + \N2 \ N1\ + then show \N1 \\ N2\ using entails_\_def \_subset Ground.subset_entailed by auto +next + fix N1 N2 + assume + N1_entails_C: \\C \ N2. N1 \\ {C}\ + show \N1 \\ N2\ using Ground.all_formulas_entailed N1_entails_C entails_\_def + by (smt UN_E UN_I Ground.entail_set_all_formulas singletonI) +next + fix N1 N2 N3 + assume + \N1 \\ N2\ and \N2 \\ N3\ + then show \N1 \\ N3\ using entails_\_def Ground.entails_trans by blast +qed + +end + +subsection \Strong Standard Lifting\ + +(* rmk:strong-standard-lifting *) +locale strong_standard_lifting = Non_ground: inference_system Inf_F + + Ground: calculus_with_red_crit Bot_G Inf_G entails_G Red_Inf_G Red_F_G + for + Bot_F :: \'f set\ and + Inf_F :: \'f inference set\ and + Bot_G :: \'g set\ and + Inf_G :: \'g inference set\ and + entails_G :: \'g set \ 'g set \ bool\ (infix "\G" 50) and + Red_Inf_G :: \'g set \ 'g inference set\ and + Red_F_G :: \'g set \ 'g set\ + + fixes + \_F :: \'f \ 'g set\ and + \_Inf :: \'f inference \ 'g inference set option\ + assumes + Bot_F_not_empty: "Bot_F \ {}" and + Bot_map_not_empty: \B \ Bot_F \ \_F B \ {}\ and + Bot_map: \B \ Bot_F \ \_F B \ Bot_G\ and + Bot_cond: \\_F C \ Bot_G \ {} \ C \ Bot_F\ and + strong_inf_map: \\ \ Inf_F \ \_Inf \ \ None \ concl_of ` (the (\_Inf \)) \ (\_F (concl_of \))\ and + inf_map_in_Inf: \\ \ Inf_F \ \_Inf \ \ None \ the (\_Inf \) \ Inf_G\ +begin + +sublocale standard_lifting +proof + show "Bot_F \ {}" using Bot_F_not_empty . +next + fix B + assume b_in: "B \ Bot_F" + show "\_F B \ {}" using Bot_map_not_empty[OF b_in] . +next + fix B + assume b_in: "B \ Bot_F" + show "\_F B \ Bot_G" using Bot_map[OF b_in] . +next + show "\C. \_F C \ Bot_G \ {} \ C \ Bot_F" using Bot_cond . +next + fix \ + assume i_in: "\ \ Inf_F" and + some_g: "\_Inf \ \ None" + show "the (\_Inf \) \ Red_Inf_G (\_F (concl_of \))" + proof + fix \G + assume ig_in1: "\G \ the (\_Inf \)" + then have ig_in2: "\G \ Inf_G" using inf_map_in_Inf[OF i_in some_g] by blast + show "\G \ Red_Inf_G (\_F (concl_of \))" + using strong_inf_map[OF i_in some_g] Ground.Red_Inf_of_Inf_to_N[OF ig_in2] + ig_in1 by blast + qed +qed + +end + +subsection \Lifting with a Family of Well-founded Orderings\ + +locale lifting_with_wf_ordering_family = + standard_lifting Bot_F Inf_F Bot_G Inf_G entails_G Red_Inf_G Red_F_G \_F \_Inf + for + Bot_F :: \'f set\ and + Inf_F :: \'f inference set\ and + Bot_G :: \'g set\ and + entails_G :: \'g set \ 'g set \ bool\ (infix "\G" 50) and + Inf_G :: \'g inference set\ and + Red_Inf_G :: \'g set \ 'g inference set\ and + Red_F_G :: \'g set \ 'g set\ and + \_F :: "'f \ 'g set" and + \_Inf :: "'f inference \ 'g inference set option" + + fixes + Prec_F_g :: \'g \ 'f \ 'f \ bool\ + assumes + all_wf: "minimal_element (Prec_F_g g) UNIV" +begin + +definition Red_Inf_\ :: "'f set \ 'f inference set" where + \Red_Inf_\ N = {\ \ Inf_F. (\_Inf \ \ None \ the (\_Inf \) \ Red_Inf_G (\_set N)) + \ (\_Inf \ = None \ \_F (concl_of \) \ (\_set N \ Red_F_G (\_set N)))}\ + +definition Red_F_\ :: "'f set \ 'f set" where + \Red_F_\ N = {C. \D \ \_F C. D \ Red_F_G (\_set N) \ (\E \ N. Prec_F_g D E C \ D \ \_F E)}\ + +lemma Prec_trans: + assumes + \Prec_F_g D A B\ and + \Prec_F_g D B C\ + shows + \Prec_F_g D A C\ + using minimal_element.po assms unfolding po_on_def transp_on_def by (smt UNIV_I all_wf) + +lemma prop_nested_in_set: "D \ P C \ C \ {C. \D \ P C. A D \ B C D} \ A D \ B C D" + by blast + +(* lem:wolog-C'-nonredundant *) +lemma Red_F_\_equiv_def: + \Red_F_\ N = {C. \Di \ \_F C. Di \ Red_F_G (\_set N) \ + (\E \ (N - Red_F_\ N). Prec_F_g Di E C \ Di \ \_F E)}\ +proof (rule;clarsimp) + fix C D + assume + C_in: \C \ Red_F_\ N\ and + D_in: \D \ \_F C\ and + not_sec_case: \\E \ N - Red_F_\ N. Prec_F_g D E C \ D \ \_F E\ + have C_in_unfolded: "C \ {C. \Di \ \_F C. Di \ Red_F_G (\_set N) \ + (\E\N. Prec_F_g Di E C \ Di \ \_F E)}" + using C_in unfolding Red_F_\_def . + have neg_not_sec_case: \\ (\E\N - Red_F_\ N. Prec_F_g D E C \ D \ \_F E)\ + using not_sec_case by clarsimp + have unfol_C_D: \D \ Red_F_G (\_set N) \ (\E\N. Prec_F_g D E C \ D \ \_F E)\ + using prop_nested_in_set[of D \_F C "\x. x \ Red_F_G (\ (\_F ` N))" + "\x y. \E \ N. Prec_F_g y E x \ y \ \_F E", OF D_in C_in_unfolded] by blast + show \D \ Red_F_G (\_set N)\ + proof (rule ccontr) + assume contrad: \D \ Red_F_G (\_set N)\ + have non_empty: \\E\N. Prec_F_g D E C \ D \ \_F E\ using contrad unfol_C_D by auto + define B where \B = {E \ N. Prec_F_g D E C \ D \ \_F E}\ + then have B_non_empty: \B \ {}\ using non_empty by auto + interpret minimal_element "Prec_F_g D" UNIV using all_wf[of D] . + obtain F :: 'f where F: \F = min_elt B\ by auto + then have D_in_F: \D \ \_F F\ unfolding B_def using non_empty + by (smt Sup_UNIV Sup_upper UNIV_I contra_subsetD empty_iff empty_subsetI mem_Collect_eq + min_elt_mem unfol_C_D) + have F_prec: \Prec_F_g D F C\ using F min_elt_mem[of B, OF _ B_non_empty] unfolding B_def by auto + have F_not_in: \F \ Red_F_\ N\ + proof + assume F_in: \F \ Red_F_\ N\ + have unfol_F_D: \D \ Red_F_G (\_set N) \ (\G\N. Prec_F_g D G F \ D \ \_F G)\ + using F_in D_in_F unfolding Red_F_\_def by auto + then have \\G\N. Prec_F_g D G F \ D \ \_F G\ using contrad D_in unfolding Red_F_\_def by auto + then obtain G where G_in: \G \ N\ and G_prec: \Prec_F_g D G F\ and G_map: \D \ \_F G\ by auto + have \Prec_F_g D G C\ using G_prec F_prec Prec_trans by blast + then have \G \ B\ unfolding B_def using G_in G_map by auto + then show \False\ using F G_prec min_elt_minimal[of B G, OF _ B_non_empty] by auto + qed + have \F \ N\ using F by (metis B_def B_non_empty mem_Collect_eq min_elt_mem top_greatest) + then have \F \ N - Red_F_\ N\ using F_not_in by auto + then show \False\ + using D_in_F neg_not_sec_case F_prec by blast + qed +next + fix C + assume only_if: \\D\\_F C. D \ Red_F_G (\_set N) \ (\E\N - Red_F_\ N. Prec_F_g D E C \ D \ \_F E)\ + show \C \ Red_F_\ N\ unfolding Red_F_\_def using only_if by auto +qed + +(* lem:lifting-main-technical *) +lemma not_red_map_in_map_not_red: \\_set N - Red_F_G (\_set N) \ \_set (N - Red_F_\ N)\ +proof + fix D + assume + D_hyp: \D \ \_set N - Red_F_G (\_set N)\ + interpret minimal_element "Prec_F_g D" UNIV using all_wf[of D] . + have D_in: \D \ \_set N\ using D_hyp by blast + have D_not_in: \D \ Red_F_G (\_set N)\ using D_hyp by blast + have exist_C: \\C. C \ N \ D \ \_F C\ using D_in by auto + define B where \B = {C \ N. D \ \_F C}\ + obtain C where C: \C = min_elt B\ by auto + have C_in_N: \C \ N\ + using exist_C by (metis B_def C empty_iff mem_Collect_eq min_elt_mem top_greatest) + have D_in_C: \D \ \_F C\ + using exist_C by (metis B_def C empty_iff mem_Collect_eq min_elt_mem top_greatest) + have C_not_in: \C \ Red_F_\ N\ + proof + assume C_in: \C \ Red_F_\ N\ + have \D \ Red_F_G (\_set N) \ (\E\N. Prec_F_g D E C \ D \ \_F E)\ + using C_in D_in_C unfolding Red_F_\_def by auto + then show \False\ + proof + assume \D \ Red_F_G (\_set N)\ + then show \False\ using D_not_in by simp + next + assume \\E\N. Prec_F_g D E C \ D \ \_F E\ + then show \False\ + using C by (metis (no_types, lifting) B_def UNIV_I empty_iff mem_Collect_eq + min_elt_minimal top_greatest) + qed + qed + show \D \ \_set (N - Red_F_\ N)\ using D_in_C C_not_in C_in_N by blast +qed + +(* lem:nonredundant-entails-redundant *) +lemma Red_F_Bot_F: \B \ Bot_F \ N \\ {B} \ N - Red_F_\ N \\ {B}\ +proof - + fix B N + assume + B_in: \B \ Bot_F\ and + N_entails: \N \\ {B}\ + then have to_bot: \\_set N - Red_F_G (\_set N) \G \_F B\ + using Ground.Red_F_Bot Bot_map unfolding entails_\_def + by (smt cSup_singleton Ground.entail_set_all_formulas image_insert image_is_empty subsetCE) + have from_f: \\_set (N - Red_F_\ N) \G \_set N - Red_F_G (\_set N)\ + using Ground.subset_entailed[OF not_red_map_in_map_not_red] by blast + then have \\_set (N - Red_F_\ N) \G \_F B\ using to_bot Ground.entails_trans by blast + then show \N - Red_F_\ N \\ {B}\ using Bot_map unfolding entails_\_def by simp +qed + +(* lem:redundancy-monotonic-addition 1/2 *) +lemma Red_F_of_subset_F: \N \ N' \ Red_F_\ N \ Red_F_\ N'\ + using Ground.Red_F_of_subset unfolding Red_F_\_def by (smt Collect_mono \_subset subset_iff) + +(* lem:redundancy-monotonic-addition 2/2 *) +lemma Red_Inf_of_subset_F: \N \ N' \ Red_Inf_\ N \ Red_Inf_\ N'\ + using Collect_mono \_subset subset_iff Ground.Red_Inf_of_subset unfolding Red_Inf_\_def + by (smt Ground.Red_F_of_subset Un_iff) + +(* lem:redundancy-monotonic-deletion-forms *) +lemma Red_F_of_Red_F_subset_F: \N' \ Red_F_\ N \ Red_F_\ N \ Red_F_\ (N - N')\ +proof + fix N N' C + assume + N'_in_Red_F_N: \N' \ Red_F_\ N\ and + C_in_red_F_N: \C \ Red_F_\ N\ + have lem8: \\D \ \_F C. D \ Red_F_G (\_set N) \ (\E \ (N - Red_F_\ N). Prec_F_g D E C \ D \ \_F E)\ + using Red_F_\_equiv_def C_in_red_F_N by blast + show \C \ Red_F_\ (N - N')\ unfolding Red_F_\_def + proof (rule,rule) + fix D + assume \D \ \_F C\ + then have \D \ Red_F_G (\_set N) \ (\E \ (N - Red_F_\ N). Prec_F_g D E C \ D \ \_F E)\ + using lem8 by auto + then show \D \ Red_F_G (\_set (N - N')) \ (\E\N - N'. Prec_F_g D E C \ D \ \_F E)\ + proof + assume \D \ Red_F_G (\_set N)\ + then have \D \ Red_F_G (\_set N - Red_F_G (\_set N))\ + using Ground.Red_F_of_Red_F_subset[of "Red_F_G (\_set N)" "\_set N"] by auto + then have \D \ Red_F_G (\_set (N - Red_F_\ N))\ + using Ground.Red_F_of_subset[OF not_red_map_in_map_not_red[of N]] by auto + then have \D \ Red_F_G (\_set (N - N'))\ + using N'_in_Red_F_N \_subset[of "N - Red_F_\ N" "N - N'"] + by (smt DiffE DiffI Ground.Red_F_of_subset subsetCE subsetI) + then show ?thesis by blast + next + assume \\E\N - Red_F_\ N. Prec_F_g D E C \ D \ \_F E\ + then obtain E where + E_in: \E\N - Red_F_\ N\ and + E_prec_C: \Prec_F_g D E C\ and + D_in: \D \ \_F E\ + by auto + have \E \ N - N'\ using E_in N'_in_Red_F_N by blast + then show ?thesis using E_prec_C D_in by blast + qed + qed +qed + +(* lem:redundancy-monotonic-deletion-infs *) +lemma Red_Inf_of_Red_F_subset_F: \N' \ Red_F_\ N \ Red_Inf_\ N \ Red_Inf_\ (N - N') \ +proof + fix N N' \ + assume + N'_in_Red_F_N: \N' \ Red_F_\ N\ and + i_in_Red_Inf_N: \\ \ Red_Inf_\ N\ + have i_in: \\ \ Inf_F\ using i_in_Red_Inf_N unfolding Red_Inf_\_def by blast + { + assume not_none: "\_Inf \ \ None" + have \\\' \ the (\_Inf \). \' \ Red_Inf_G (\_set N)\ + using not_none i_in_Red_Inf_N unfolding Red_Inf_\_def by auto + then have \\\' \ the (\_Inf \). \' \ Red_Inf_G (\_set N - Red_F_G (\_set N))\ + using not_none Ground.Red_Inf_of_Red_F_subset by blast + then have ip_in_Red_Inf_G: \\\' \ the (\_Inf \). \' \ Red_Inf_G (\_set (N - Red_F_\ N))\ + using not_none Ground.Red_Inf_of_subset[OF not_red_map_in_map_not_red[of N]] by auto + then have not_none_in: \\\' \ the (\_Inf \). \' \ Red_Inf_G (\_set (N - N'))\ + using not_none N'_in_Red_F_N + by (meson Diff_mono Ground.Red_Inf_of_subset \_subset subset_iff subset_refl) + then have "the (\_Inf \) \ Red_Inf_G (\_set (N - N'))" by blast + } + moreover { + assume none: "\_Inf \ = None" + have ground_concl_subs: "\_F (concl_of \) \ (\_set N \ Red_F_G (\_set N))" + using none i_in_Red_Inf_N unfolding Red_Inf_\_def by blast + then have d_in_imp12: "D \ \_F (concl_of \) \ D \ \_set N - Red_F_G (\_set N) \ D \ Red_F_G (\_set N)" + by blast + have d_in_imp1: "D \ \_set N - Red_F_G (\_set N) \ D \ \_set (N - N')" + using not_red_map_in_map_not_red N'_in_Red_F_N by blast + have d_in_imp_d_in: "D \ Red_F_G (\_set N) \ D \ Red_F_G (\_set N - Red_F_G (\_set N))" + using Ground.Red_F_of_Red_F_subset[of "Red_F_G (\_set N)" "\_set N"] by blast + have g_subs1: "\_set N - Red_F_G (\_set N) \ \_set (N - Red_F_\ N)" + using not_red_map_in_map_not_red unfolding Red_F_\_def by auto + have g_subs2: "\_set (N - Red_F_\ N) \ \_set (N - N')" + using N'_in_Red_F_N by blast + have d_in_imp2: "D \ Red_F_G (\_set N) \ D \ Red_F_G (\_set (N - N'))" + using Ground.Red_F_of_subset Ground.Red_F_of_subset[OF g_subs1] + Ground.Red_F_of_subset[OF g_subs2] d_in_imp_d_in by blast + have "\_F (concl_of \) \ (\_set (N - N') \ Red_F_G (\_set (N - N')))" + using d_in_imp12 d_in_imp1 d_in_imp2 + by (smt Ground.Red_F_of_Red_F_subset Ground.Red_F_of_subset UnCI UnE Un_Diff_cancel2 + ground_concl_subs g_subs1 g_subs2 subset_iff) + } + ultimately show \\ \ Red_Inf_\ (N - N')\ using i_in unfolding Red_Inf_\_def by auto +qed + +(* lem:concl-contained-implies-red-inf *) +lemma Red_Inf_of_Inf_to_N_F: + assumes + i_in: \\ \ Inf_F\ and + concl_i_in: \concl_of \ \ N\ + shows + \\ \ Red_Inf_\ N \ +proof - + have \\ \ Inf_F \ \_Inf \ \ None \ the (\_Inf \) \ Red_Inf_G (\_F (concl_of \))\ using inf_map by simp + moreover have \Red_Inf_G (\_F (concl_of \)) \ Red_Inf_G (\_set N)\ + using concl_i_in Ground.Red_Inf_of_subset by blast + moreover have "\ \ Inf_F \ \_Inf \ = None \ concl_of \ \ N \ \_F (concl_of \) \ \_set N" + by blast + ultimately show ?thesis using i_in concl_i_in unfolding Red_Inf_\_def by auto +qed + +(* thm:FRedsqsubset-is-red-crit and also thm:lifted-red-crit if ordering empty *) +sublocale lifted_calculus_with_red_crit: calculus_with_red_crit + where + Bot = Bot_F and Inf = Inf_F and entails = entails_\ and + Red_Inf = Red_Inf_\ and Red_F = Red_F_\ +proof + fix B N N' \ + show \Red_Inf_\ N \ Inf_F\ unfolding Red_Inf_\_def by blast + show \B \ Bot_F \ N \\ {B} \ N - Red_F_\ N \\ {B}\ using Red_F_Bot_F by simp + show \N \ N' \ Red_F_\ N \ Red_F_\ N'\ using Red_F_of_subset_F by simp + show \N \ N' \ Red_Inf_\ N \ Red_Inf_\ N'\ using Red_Inf_of_subset_F by simp + show \N' \ Red_F_\ N \ Red_F_\ N \ Red_F_\ (N - N')\ using Red_F_of_Red_F_subset_F by simp + show \N' \ Red_F_\ N \ Red_Inf_\ N \ Red_Inf_\ (N - N')\ using Red_Inf_of_Red_F_subset_F by simp + show \\ \ Inf_F \ concl_of \ \ N \ \ \ Red_Inf_\ N\ using Red_Inf_of_Inf_to_N_F by simp +qed + +lemma lifted_calc_is_calc: "calculus_with_red_crit Bot_F Inf_F entails_\ Red_Inf_\ Red_F_\" + using lifted_calculus_with_red_crit.calculus_with_red_crit_axioms . + +lemma grounded_inf_in_ground_inf: "\ \ Inf_F \ \_Inf \ \ None \ the (\_Inf \) \ Inf_G" + using inf_map Ground.Red_Inf_to_Inf by blast + +(* lem:sat-wrt-finf *) +lemma sat_imp_ground_sat: "lifted_calculus_with_red_crit.saturated N \ Ground.Inf_from (\_set N) \ + ({\. \\'\ Non_ground.Inf_from N. \_Inf \' \ None \ \ \ the (\_Inf \')} \ Red_Inf_G (\_set N)) \ + Ground.saturated (\_set N)" +proof - + fix N + assume + sat_n: "lifted_calculus_with_red_crit.saturated N" and + inf_grounded_in: "Ground.Inf_from (\_set N) \ + ({\. \\'\ Non_ground.Inf_from N. \_Inf \' \ None \ \ \ the (\_Inf \')} \ Red_Inf_G (\_set N))" + show "Ground.saturated (\_set N)" unfolding Ground.saturated_def + proof + fix \ + assume i_in: "\ \ Ground.Inf_from (\_set N)" + { + assume "\ \ {\. \\'\ Non_ground.Inf_from N. \_Inf \' \ None \ \ \ the (\_Inf \')}" + then obtain \' where "\'\ Non_ground.Inf_from N" "\_Inf \' \ None" "\ \ the (\_Inf \')" by blast + then have "\ \ Red_Inf_G (\_set N)" + using Red_Inf_\_def sat_n unfolding lifted_calculus_with_red_crit.saturated_def by auto + } + then show "\ \ Red_Inf_G (\_set N)" using inf_grounded_in i_in by blast + qed +qed + +(* thm:finf-complete *) +theorem stat_ref_comp_to_non_ground: + assumes + stat_ref_G: "static_refutational_complete_calculus Bot_G Inf_G entails_G Red_Inf_G Red_F_G" and + sat_n_imp: "\N. (lifted_calculus_with_red_crit.saturated N \ Ground.Inf_from (\_set N) \ + ({\. \\'\ Non_ground.Inf_from N. \_Inf \' \ None \ \ \ the (\_Inf \')} \ Red_Inf_G (\_set N)))" + shows + "static_refutational_complete_calculus Bot_F Inf_F entails_\ Red_Inf_\ Red_F_\" +proof + fix B N + assume + b_in: "B \ Bot_F" and + sat_n: "lifted_calculus_with_red_crit.saturated N" and + n_entails_bot: "N \\ {B}" + have ground_n_entails: "\_set N \G \_F B" + using n_entails_bot unfolding entails_\_def by simp + then obtain BG where bg_in1: "BG \ \_F B" + using Bot_map_not_empty[OF b_in] by blast + then have bg_in: "BG \ Bot_G" + using Bot_map[OF b_in] by blast + have ground_n_entails_bot: "\_set N \G {BG}" + using ground_n_entails bg_in1 Ground.entail_set_all_formulas by blast + have "Ground.Inf_from (\_set N) \ + ({\. \\'\ Non_ground.Inf_from N. \_Inf \' \ None \ \ \ the (\_Inf \')} \ Red_Inf_G (\_set N))" + using sat_n_imp[OF sat_n] . + have "Ground.saturated (\_set N)" + using sat_imp_ground_sat[OF sat_n sat_n_imp[OF sat_n]] . + then have "\BG'\Bot_G. BG' \ (\_set N)" + using stat_ref_G Ground.calculus_with_red_crit_axioms bg_in ground_n_entails_bot + unfolding static_refutational_complete_calculus_def static_refutational_complete_calculus_axioms_def + by blast + then show "\B'\ Bot_F. B' \ N" + using bg_in Bot_cond Bot_map_not_empty Bot_cond by blast +qed + +end + +abbreviation Empty_Order where + "Empty_Order C1 C2 \ False" + +lemma any_to_empty_order_lifting: + "lifting_with_wf_ordering_family Bot_F Inf_F Bot_G entails_G Inf_G Red_Inf_G Red_F_G \_F + \_Inf Prec_F_g \ lifting_with_wf_ordering_family Bot_F Inf_F Bot_G entails_G Inf_G Red_Inf_G + Red_F_G \_F \_Inf (\g. Empty_Order)" +proof - + fix Bot_F Inf_F Bot_G entails_G Inf_G Red_Inf_G Red_F_G \_F \_Inf Prec_F_g + assume lift: "lifting_with_wf_ordering_family Bot_F Inf_F Bot_G entails_G Inf_G Red_Inf_G + Red_F_G \_F \_Inf Prec_F_g" + then interpret lift_g: + lifting_with_wf_ordering_family Bot_F Inf_F Bot_G entails_G Inf_G Red_Inf_G Red_F_G \_F + \_Inf Prec_F_g + by auto + have empty_wf: "minimal_element ((\g. Empty_Order) g) UNIV" + by (simp add: lift_g.all_wf minimal_element.intro po_on_def transp_on_def wfp_on_def + wfp_on_imp_irreflp_on) + then show "lifting_with_wf_ordering_family Bot_F Inf_F Bot_G entails_G Inf_G Red_Inf_G Red_F_G + \_F \_Inf (\g. Empty_Order)" + by (simp add: empty_wf lift_g.standard_lifting_axioms + lifting_with_wf_ordering_family_axioms.intro lifting_with_wf_ordering_family_def) +qed + +locale lifting_equivalence_with_empty_order = + any_order_lifting: lifting_with_wf_ordering_family Bot_F Inf_F Bot_G entails_G Inf_G Red_Inf_G + Red_F_G \_F \_Inf Prec_F_g + + empty_order_lifting: lifting_with_wf_ordering_family Bot_F Inf_F Bot_G entails_G Inf_G Red_Inf_G + Red_F_G \_F \_Inf "\g. Empty_Order" + for + \_F :: \'f \ 'g set\ and + \_Inf :: \'f inference \ 'g inference set option\ and + Bot_F :: \'f set\ and + Inf_F :: \'f inference set\ and + Bot_G :: \'g set\ and + Inf_G :: \'g inference set\ and + entails_G :: \'g set \ 'g set \ bool\ (infix "\G" 50) and + Red_Inf_G :: \'g set \ 'g inference set\ and + Red_F_G :: \'g set \ 'g set\ and + Prec_F_g :: \'g \ 'f \ 'f \ bool\ + +sublocale lifting_with_wf_ordering_family \ lifting_equivalence_with_empty_order +proof + show "po_on Empty_Order UNIV" + unfolding po_on_def by (simp add: transp_onI wfp_on_imp_irreflp_on) + show "wfp_on Empty_Order UNIV" + unfolding wfp_on_def by simp +qed + +context lifting_equivalence_with_empty_order +begin + +(* lem:saturation-indep-of-sqsubset *) +lemma saturated_empty_order_equiv_saturated: + "any_order_lifting.lifted_calculus_with_red_crit.saturated N = + empty_order_lifting.lifted_calculus_with_red_crit.saturated N" by standard + +(* lem:static-ref-compl-indep-of-sqsubset *) +lemma static_empty_order_equiv_static: + "static_refutational_complete_calculus Bot_F Inf_F + any_order_lifting.entails_\ empty_order_lifting.Red_Inf_\ empty_order_lifting.Red_F_\ = + static_refutational_complete_calculus Bot_F Inf_F any_order_lifting.entails_\ + any_order_lifting.Red_Inf_\ any_order_lifting.Red_F_\" + unfolding static_refutational_complete_calculus_def + by (rule iffI) (standard,(standard)[],simp)+ + +(* thm:FRedsqsubset-is-dyn-ref-compl *) +theorem static_to_dynamic: + "static_refutational_complete_calculus Bot_F Inf_F + any_order_lifting.entails_\ empty_order_lifting.Red_Inf_\ empty_order_lifting.Red_F_\ = + dynamic_refutational_complete_calculus Bot_F Inf_F + any_order_lifting.entails_\ any_order_lifting.Red_Inf_\ any_order_lifting.Red_F_\ " + (is "?static=?dynamic") +proof + assume ?static + then have static_general: + "static_refutational_complete_calculus Bot_F Inf_F any_order_lifting.entails_\ + any_order_lifting.Red_Inf_\ any_order_lifting.Red_F_\" (is "?static_gen") + using static_empty_order_equiv_static by simp + interpret static_refutational_complete_calculus Bot_F Inf_F any_order_lifting.entails_\ + any_order_lifting.Red_Inf_\ any_order_lifting.Red_F_\ + using static_general . + show "?dynamic" by standard +next + assume dynamic_gen: ?dynamic + interpret dynamic_refutational_complete_calculus Bot_F Inf_F any_order_lifting.entails_\ + any_order_lifting.Red_Inf_\ any_order_lifting.Red_F_\ + using dynamic_gen . + have "static_refutational_complete_calculus Bot_F Inf_F any_order_lifting.entails_\ + any_order_lifting.Red_Inf_\ any_order_lifting.Red_F_\" + by standard + then show "?static" using static_empty_order_equiv_static by simp +qed + +end + +subsection \Lifting with a Family of Redundancy Criteria\ + +locale standard_lifting_with_red_crit_family = Non_ground: inference_system Inf_F + + Ground_family: calculus_with_red_crit_family Bot_G Inf_G Q entails_q Red_Inf_q Red_F_q + for + Inf_F :: "'f inference set" and + Bot_G :: "'g set" and + Inf_G :: \'g inference set\ and + Q :: "'q itself" and + entails_q :: "'q \ ('g set \ 'g set \ bool)" and + Red_Inf_q :: "'q \ ('g set \ 'g inference set)" and + Red_F_q :: "'q \ ('g set \ 'g set)" + + fixes + Bot_F :: "'f set" and + \_F_q :: "'q \ 'f \ 'g set" and + \_Inf_q :: "'q \ 'f inference \ 'g inference set option" and + Prec_F_g :: "'g \ 'f \ 'f \ bool" + assumes + standard_lifting_family: "lifting_with_wf_ordering_family Bot_F Inf_F Bot_G (entails_q q) + Inf_G (Red_Inf_q q) (Red_F_q q) (\_F_q q) (\_Inf_q q) Prec_F_g" +begin + +definition \_set_q :: "'q \ 'f set \ 'g set" where + "\_set_q q N \ UNION N (\_F_q q)" + +definition Red_Inf_\_q :: "'q \ 'f set \ 'f inference set" where + "Red_Inf_\_q q N = {\ \ Inf_F. (\_Inf_q q \ \ None \ the (\_Inf_q q \) \ Red_Inf_q q (\_set_q q N)) + \ (\_Inf_q q \ = None \ \_F_q q (concl_of \) \ (\_set_q q N \ Red_F_q q (\_set_q q N)))}" + +definition Red_Inf_\_Q :: "'f set \ 'f inference set" where + "Red_Inf_\_Q N = \ {X N |X. X \ (Red_Inf_\_q ` UNIV)}" + +definition Red_F_\_empty_q :: "'q \ 'f set \ 'f set" where + "Red_F_\_empty_q q N = {C. \D \ \_F_q q C. D \ Red_F_q q (\_set_q q N) \ + (\E \ N. Empty_Order E C \ D \ \_F_q q E)}" + +definition Red_F_\_empty :: "'f set \ 'f set" where + "Red_F_\_empty N = \ {X N |X. X \ (Red_F_\_empty_q ` UNIV)}" + +definition Red_F_\_q_g :: "'q \ 'f set \ 'f set" where + "Red_F_\_q_g q N = {C. \D \ \_F_q q C. D \ Red_F_q q (\_set_q q N) \ (\E \ N. Prec_F_g D E C \ D \ \_F_q q E)}" + +definition Red_F_\_g :: "'f set \ 'f set" where + "Red_F_\_g N = \ {X N |X. X \ (Red_F_\_q_g ` UNIV)}" + +definition entails_\_q :: "'q \ 'f set \ 'f set \ bool" where + "entails_\_q q N1 N2 \ entails_q q (\_set_q q N1) (\_set_q q N2)" + +definition entails_\_Q :: "'f set \ 'f set \ bool" (infix "\\" 50) where + "entails_\_Q N1 N2 \ \q. entails_\_q q N1 N2" + +lemma red_crit_lifting_family: + "calculus_with_red_crit Bot_F Inf_F (entails_\_q q) (Red_Inf_\_q q) (Red_F_\_q_g q)" +proof - + fix q + interpret wf_lift: + lifting_with_wf_ordering_family Bot_F Inf_F Bot_G "entails_q q" Inf_G "Red_Inf_q q" "Red_F_q q" + "\_F_q q" "\_Inf_q q" Prec_F_g + using standard_lifting_family . + have "entails_\_q q = wf_lift.entails_\" + unfolding entails_\_q_def wf_lift.entails_\_def \_set_q_def by blast + moreover have "Red_Inf_\_q q = wf_lift.Red_Inf_\" + unfolding Red_Inf_\_q_def \_set_q_def wf_lift.Red_Inf_\_def by blast + moreover have "Red_F_\_q_g q = wf_lift.Red_F_\" + unfolding Red_F_\_q_g_def \_set_q_def wf_lift.Red_F_\_def by blast + ultimately show "calculus_with_red_crit Bot_F Inf_F (entails_\_q q) (Red_Inf_\_q q) (Red_F_\_q_g q)" + using wf_lift.lifted_calculus_with_red_crit.calculus_with_red_crit_axioms by simp +qed + +lemma red_crit_lifting_family_empty_ord: + "calculus_with_red_crit Bot_F Inf_F (entails_\_q q) (Red_Inf_\_q q) (Red_F_\_empty_q q)" +proof - + fix q + interpret wf_lift: + lifting_with_wf_ordering_family Bot_F Inf_F Bot_G "entails_q q" Inf_G "Red_Inf_q q" "Red_F_q q" + "\_F_q q" "\_Inf_q q" Prec_F_g + using standard_lifting_family . + have "entails_\_q q = wf_lift.entails_\" + unfolding entails_\_q_def wf_lift.entails_\_def \_set_q_def by blast + moreover have "Red_Inf_\_q q = wf_lift.Red_Inf_\" + unfolding Red_Inf_\_q_def \_set_q_def wf_lift.Red_Inf_\_def by blast + moreover have "Red_F_\_empty_q q = wf_lift.empty_order_lifting.Red_F_\" + unfolding Red_F_\_empty_q_def \_set_q_def wf_lift.empty_order_lifting.Red_F_\_def by blast + ultimately show "calculus_with_red_crit Bot_F Inf_F (entails_\_q q) (Red_Inf_\_q q) (Red_F_\_empty_q q)" + using wf_lift.empty_order_lifting.lifted_calculus_with_red_crit.calculus_with_red_crit_axioms + by simp +qed + +lemma cons_rel_fam_Q_lem: \consequence_relation_family Bot_F entails_\_q\ +proof + show "Bot_F \ {}" + using standard_lifting_family + by (meson ex_in_conv lifting_with_wf_ordering_family.axioms(1) standard_lifting.Bot_F_not_empty) +next + fix qi + show "Bot_F \ {}" + using standard_lifting_family + by (meson ex_in_conv lifting_with_wf_ordering_family.axioms(1) standard_lifting.Bot_F_not_empty) +next + fix qi B N1 + assume + B_in: "B \ Bot_F" + interpret lift: lifting_with_wf_ordering_family Bot_F Inf_F Bot_G "entails_q qi" Inf_G "Red_Inf_q qi" + "Red_F_q qi" "\_F_q qi" "\_Inf_q qi" Prec_F_g + by (rule standard_lifting_family) + have "(entails_\_q qi) = lift.entails_\" + unfolding entails_\_q_def lift.entails_\_def \_set_q_def by simp + then show "entails_\_q qi {B} N1" + using B_in lift.lifted_consequence_relation.bot_implies_all by auto +next + fix qi and N2 N1::"'f set" + assume + N_incl: "N2 \ N1" + interpret lift: lifting_with_wf_ordering_family Bot_F Inf_F Bot_G "entails_q qi" Inf_G "Red_Inf_q qi" + "Red_F_q qi" "\_F_q qi" "\_Inf_q qi" Prec_F_g + by (rule standard_lifting_family) + have "(entails_\_q qi) = lift.entails_\" + unfolding entails_\_q_def lift.entails_\_def \_set_q_def by simp + then show "entails_\_q qi N1 N2" + using N_incl by (simp add: lift.lifted_consequence_relation.subset_entailed) +next + fix qi N1 N2 + assume + all_C: "\C\ N2. entails_\_q qi N1 {C}" + interpret lift: lifting_with_wf_ordering_family Bot_F Inf_F Bot_G "entails_q qi" Inf_G "Red_Inf_q qi" + "Red_F_q qi" "\_F_q qi" "\_Inf_q qi" Prec_F_g + by (rule standard_lifting_family) + have "(entails_\_q qi) = lift.entails_\" + unfolding entails_\_q_def lift.entails_\_def \_set_q_def by simp + then show "entails_\_q qi N1 N2" + using all_C lift.lifted_consequence_relation.all_formulas_entailed by presburger +next + fix qi N1 N2 N3 + assume + entails12: "entails_\_q qi N1 N2" and + entails23: "entails_\_q qi N2 N3" + interpret lift: lifting_with_wf_ordering_family Bot_F Inf_F Bot_G "entails_q qi" Inf_G "Red_Inf_q qi" + "Red_F_q qi" "\_F_q qi" "\_Inf_q qi" Prec_F_g + by (rule standard_lifting_family) + have "(entails_\_q qi) = lift.entails_\" + unfolding entails_\_q_def lift.entails_\_def \_set_q_def by simp + then show "entails_\_q qi N1 N3" + using entails12 entails23 lift.lifted_consequence_relation.entails_trans by presburger +qed + +interpretation cons_rel_Q: consequence_relation Bot_F entails_\_Q +proof - + interpret cons_rel_fam: consequence_relation_family Bot_F Q entails_\_q + by (rule cons_rel_fam_Q_lem) + have "consequence_relation_family.entails_Q entails_\_q = entails_\_Q" + unfolding entails_\_Q_def cons_rel_fam.entails_Q_def by (simp add: entails_\_q_def) + then show "consequence_relation Bot_F entails_\_Q" + using consequence_relation_family.intersect_cons_rel_family[OF cons_rel_fam_Q_lem] by simp +qed + +sublocale lifted_calc_w_red_crit_family: + calculus_with_red_crit_family Bot_F Inf_F Q entails_\_q Red_Inf_\_q Red_F_\_q_g + using cons_rel_fam_Q_lem red_crit_lifting_family + by (simp add: calculus_with_red_crit_family.intro calculus_with_red_crit_family_axioms_def) + +lemma lifted_calc_family_is_calc: "calculus_with_red_crit Bot_F Inf_F entails_\_Q Red_Inf_\_Q Red_F_\_g" +proof - + have "lifted_calc_w_red_crit_family.entails_Q = entails_\_Q" + unfolding entails_\_Q_def lifted_calc_w_red_crit_family.entails_Q_def by simp + moreover have "lifted_calc_w_red_crit_family.Red_Inf_Q = Red_Inf_\_Q" + unfolding Red_Inf_\_Q_def lifted_calc_w_red_crit_family.Red_Inf_Q_def by simp + moreover have "lifted_calc_w_red_crit_family.Red_F_Q = Red_F_\_g" + unfolding Red_F_\_g_def lifted_calc_w_red_crit_family.Red_F_Q_def by simp + ultimately show "calculus_with_red_crit Bot_F Inf_F entails_\_Q Red_Inf_\_Q Red_F_\_g" + using lifted_calc_w_red_crit_family.inter_red_crit by simp +qed + +sublocale empty_ord_lifted_calc_w_red_crit_family: + calculus_with_red_crit_family Bot_F Inf_F Q entails_\_q Red_Inf_\_q Red_F_\_empty_q + using cons_rel_fam_Q_lem red_crit_lifting_family_empty_ord + by (simp add: calculus_with_red_crit_family.intro calculus_with_red_crit_family_axioms_def) + +lemma inter_calc: "calculus_with_red_crit Bot_F Inf_F entails_\_Q Red_Inf_\_Q Red_F_\_empty" +proof - + have "lifted_calc_w_red_crit_family.entails_Q = entails_\_Q" + unfolding entails_\_Q_def lifted_calc_w_red_crit_family.entails_Q_def by simp + moreover have "empty_ord_lifted_calc_w_red_crit_family.Red_Inf_Q = Red_Inf_\_Q" + unfolding Red_Inf_\_Q_def lifted_calc_w_red_crit_family.Red_Inf_Q_def by simp + moreover have "empty_ord_lifted_calc_w_red_crit_family.Red_F_Q = Red_F_\_empty" + unfolding Red_F_\_empty_def empty_ord_lifted_calc_w_red_crit_family.Red_F_Q_def by simp + ultimately show "calculus_with_red_crit Bot_F Inf_F entails_\_Q Red_Inf_\_Q Red_F_\_empty" + using empty_ord_lifted_calc_w_red_crit_family.inter_red_crit by simp +qed + +(* thm:intersect-finf-complete *) +theorem stat_ref_comp_to_non_ground_fam_inter: + assumes + stat_ref_G: "\q. static_refutational_complete_calculus Bot_G Inf_G (entails_q q) (Red_Inf_q q) (Red_F_q q)" and + sat_n_imp: "\N. (empty_ord_lifted_calc_w_red_crit_family.inter_red_crit_calculus.saturated N \ + \q. Ground_family.Inf_from (\_set_q q N) \ + ({\. \\'\ Non_ground.Inf_from N. \_Inf_q q \' \ None \ \ \ the (\_Inf_q q \')} \ Red_Inf_q q (\_set_q q N)))" + shows + "static_refutational_complete_calculus Bot_F Inf_F entails_\_Q Red_Inf_\_Q Red_F_\_empty" + using inter_calc + unfolding static_refutational_complete_calculus_def static_refutational_complete_calculus_axioms_def +proof (standard, clarify) + fix B N + assume + b_in: "B \ Bot_F" and + sat_n: "calculus_with_red_crit.saturated Inf_F Red_Inf_\_Q N" and + entails_bot: "N \\ {B}" + interpret calculus_with_red_crit Bot_F Inf_F entails_\_Q Red_Inf_\_Q Red_F_\_empty + using inter_calc by blast + have "empty_ord_lifted_calc_w_red_crit_family.Red_Inf_Q = Red_Inf_\_Q" + unfolding Red_Inf_\_Q_def lifted_calc_w_red_crit_family.Red_Inf_Q_def by simp + then have empty_ord_sat_n: "empty_ord_lifted_calc_w_red_crit_family.inter_red_crit_calculus.saturated N" + using sat_n + unfolding saturated_def empty_ord_lifted_calc_w_red_crit_family.inter_red_crit_calculus.saturated_def + by simp + then obtain q where inf_subs: "Ground_family.Inf_from (\_set_q q N) \ + ({\. \\'\ Non_ground.Inf_from N. \_Inf_q q \' \ None \ \ \ the (\_Inf_q q \')} \ Red_Inf_q q (\_set_q q N))" + using sat_n_imp[of N] by blast + interpret q_calc: calculus_with_red_crit Bot_F Inf_F "entails_\_q q" "Red_Inf_\_q q" "Red_F_\_q_g q" + using lifted_calc_w_red_crit_family.all_red_crit[of q] . + have n_q_sat: "q_calc.saturated N" using lifted_calc_w_red_crit_family.sat_int_to_sat_q empty_ord_sat_n by simp + interpret lifted_q_calc: lifting_with_wf_ordering_family Bot_F Inf_F Bot_G "entails_q q" Inf_G "Red_Inf_q q" "Red_F_q q" "\_F_q q" "\_Inf_q q" + by (simp add: standard_lifting_family) + have "lifted_q_calc.empty_order_lifting.lifted_calculus_with_red_crit.saturated N" + using n_q_sat unfolding Red_Inf_\_q_def \_set_q_def lifted_q_calc.empty_order_lifting.Red_Inf_\_def + lifted_q_calc.lifted_calculus_with_red_crit.saturated_def q_calc.saturated_def by auto + then have ground_sat_n: "lifted_q_calc.Ground.saturated (\_set_q q N)" + using lifted_q_calc.sat_imp_ground_sat[of N] inf_subs unfolding \_set_q_def by blast + have "entails_\_q q N {B}" using entails_bot unfolding entails_\_Q_def by simp + then have ground_n_entails_bot: "entails_q q (\_set_q q N) (\_set_q q {B})" unfolding entails_\_q_def . + interpret static_refutational_complete_calculus Bot_G Inf_G "entails_q q" "Red_Inf_q q" "Red_F_q q" + using stat_ref_G[of q] . + obtain BG where bg_in: "BG \ \_F_q q B" + using lifted_q_calc.Bot_map_not_empty[OF b_in] by blast + then have "BG \ Bot_G" using lifted_q_calc.Bot_map[OF b_in] by blast + then have "\BG'\Bot_G. BG' \ \_set_q q N" + using ground_sat_n ground_n_entails_bot static_refutational_complete[of BG, OF _ ground_sat_n] + bg_in lifted_q_calc.Ground.entail_set_all_formulas[of "\_set_q q N" "\_set_q q {B}"] unfolding \_set_q_def + by simp + then show "\B'\ Bot_F. B' \ N" using lifted_q_calc.Bot_cond unfolding \_set_q_def by blast +qed + +(* lem:intersect-saturation-indep-of-sqsubset *) +lemma sat_eq_sat_empty_order: "lifted_calc_w_red_crit_family.inter_red_crit_calculus.saturated N = + empty_ord_lifted_calc_w_red_crit_family.inter_red_crit_calculus.saturated N " + by simp + +(* lem:intersect-static-ref-compl-indep-of-sqsubset *) +lemma static_empty_ord_inter_equiv_static_inter: + "static_refutational_complete_calculus Bot_F Inf_F lifted_calc_w_red_crit_family.entails_Q + lifted_calc_w_red_crit_family.Red_Inf_Q lifted_calc_w_red_crit_family.Red_F_Q = + static_refutational_complete_calculus Bot_F Inf_F lifted_calc_w_red_crit_family.entails_Q + empty_ord_lifted_calc_w_red_crit_family.Red_Inf_Q empty_ord_lifted_calc_w_red_crit_family.Red_F_Q" + unfolding static_refutational_complete_calculus_def + by (simp add: empty_ord_lifted_calc_w_red_crit_family.inter_red_crit_calculus.calculus_with_red_crit_axioms + lifted_calc_w_red_crit_family.inter_red_crit_calculus.calculus_with_red_crit_axioms) + +(* thm:intersect-static-ref-compl-is-dyn-ref-compl-with-order *) +theorem stat_eq_dyn_ref_comp_fam_inter: "static_refutational_complete_calculus Bot_F Inf_F lifted_calc_w_red_crit_family.entails_Q + empty_ord_lifted_calc_w_red_crit_family.Red_Inf_Q empty_ord_lifted_calc_w_red_crit_family.Red_F_Q = + dynamic_refutational_complete_calculus Bot_F Inf_F lifted_calc_w_red_crit_family.entails_Q + lifted_calc_w_red_crit_family.Red_Inf_Q lifted_calc_w_red_crit_family.Red_F_Q" (is "?static=?dynamic") +proof + assume ?static + then have static_general: "static_refutational_complete_calculus Bot_F Inf_F + lifted_calc_w_red_crit_family.entails_Q lifted_calc_w_red_crit_family.Red_Inf_Q + lifted_calc_w_red_crit_family.Red_F_Q" (is "?static_gen") + using static_empty_ord_inter_equiv_static_inter + by simp + interpret static_refutational_complete_calculus Bot_F Inf_F lifted_calc_w_red_crit_family.entails_Q + lifted_calc_w_red_crit_family.Red_Inf_Q lifted_calc_w_red_crit_family.Red_F_Q + using static_general . + show "?dynamic" by standard +next + assume dynamic_gen: ?dynamic + interpret dynamic_refutational_complete_calculus Bot_F Inf_F lifted_calc_w_red_crit_family.entails_Q + lifted_calc_w_red_crit_family.Red_Inf_Q lifted_calc_w_red_crit_family.Red_F_Q + using dynamic_gen . + have "static_refutational_complete_calculus Bot_F Inf_F lifted_calc_w_red_crit_family.entails_Q + lifted_calc_w_red_crit_family.Red_Inf_Q lifted_calc_w_red_crit_family.Red_F_Q" + by standard + then show "?static" using static_empty_ord_inter_equiv_static_inter by simp +qed + +end + +end diff --git a/thys/Saturation_Framework/Prover_Architectures.thy b/thys/Saturation_Framework/Prover_Architectures.thy new file mode 100644 --- /dev/null +++ b/thys/Saturation_Framework/Prover_Architectures.thy @@ -0,0 +1,1339 @@ +(* Title: Prover Architectures of the Saturation Framework + * Author: Sophie Tourret , 2019-2020 *) + +section \Prover Architectures\ + +text \This section covers all the results presented in the section 4 of the report. + This is where abstract architectures of provers are defined and proven + dynamically refutationally complete.\ + +theory Prover_Architectures + imports Labeled_Lifting_to_Non_Ground_Calculi +begin + +subsection \Basis of the Prover Architectures\ + +locale Prover_Architecture_Basis = labeled_lifting_with_red_crit_family Bot_F Inf_F Bot_G Q entails_q Inf_G + Red_Inf_q Red_F_q \_F_q \_Inf_q l Inf_FL + for + Bot_F :: "'f set" + and Inf_F :: "'f inference set" + and Bot_G :: "'g set" + and Q :: "'q itself" + and entails_q :: "'q \ ('g set \ 'g set \ bool)" + and Inf_G :: \'g inference set\ + and Red_Inf_q :: "'q \ ('g set \ 'g inference set)" + and Red_F_q :: "'q \ ('g set \ 'g set)" + and \_F_q :: "'q \ 'f \ 'g set" + and \_Inf_q :: "'q \ 'f inference \ 'g inference set option" + and l :: "'l itself" + and Inf_FL :: \('f \ 'l) inference set\ + + fixes + Equiv_F :: "('f \ 'f) set" and + Prec_F :: "'f \ 'f \ bool" (infix "\\" 50) and + Prec_l :: "'l \ 'l \ bool" (infix "\l" 50) + assumes + equiv_F_is_equiv_rel: "equiv UNIV Equiv_F" and + wf_prec_F: "minimal_element (Prec_F) UNIV" and + wf_prec_l: "minimal_element (Prec_l) UNIV" and + compat_equiv_prec: "(C1,D1) \ equiv_F \ (C2,D2) \ equiv_F \ C1 \\ C2 \ D1 \\ D2" and + equiv_F_grounding: "(C1,C2) \ equiv_F \ \_F_q q C1 = \_F_q q C2" and + prec_F_grounding: "C1 \\ C2 \ \_F_q q C1 \ \_F_q q C2" and + static_ref_comp: "static_refutational_complete_calculus Bot_F Inf_F (\\) + no_labels.empty_ord_lifted_calc_w_red_crit_family.Red_Inf_Q + no_labels.empty_ord_lifted_calc_w_red_crit_family.Red_F_Q" +begin + +definition equiv_F_fun :: "'f \ 'f \ bool" (infix "\" 50) where + "equiv_F_fun C D \ (C,D) \ Equiv_F" + +definition Prec_eq_F :: "'f \ 'f \ bool" (infix "\\" 50) where + "Prec_eq_F C D \ ((C,D) \ Equiv_F \ C \\ D)" + +definition Prec_FL :: "('f \ 'l) \ ('f \ 'l) \ bool" (infix "\" 50) where + "Prec_FL Cl1 Cl2 \ (fst Cl1 \\ fst Cl2) \ (fst Cl1 \ fst Cl2 \ snd Cl1 \l snd Cl2)" + +lemma wf_prec_FL: "minimal_element (\) UNIV" +proof + show "po_on (\) UNIV" unfolding po_on_def + proof + show "irreflp_on (\) UNIV" unfolding irreflp_on_def Prec_FL_def + proof + fix a + assume a_in: "a \ (UNIV::('f \ 'l) set)" + have "\ (fst a \\ fst a)" using wf_prec_F minimal_element.min_elt_ex by force + moreover have "\ (snd a \l snd a)" using wf_prec_l minimal_element.min_elt_ex by force + ultimately show "\ (fst a \\ fst a \ fst a \ fst a \ snd a \l snd a)" by blast + qed + next + show "transp_on (\) UNIV" unfolding transp_on_def Prec_FL_def + proof (simp, intro allI impI) + fix a1 b1 a2 b2 a3 b3 + assume trans_hyp:"(a1 \\ a2 \ a1 \ a2 \ b1 \l b2) \ (a2 \\ a3 \ a2 \ a3 \ b2 \l b3)" + have "a1 \\ a2 \ a2 \\ a3 \ a1 \\ a3" using wf_prec_F compat_equiv_prec by blast + moreover have "a1 \\ a2 \ a2 \ a3 \ a1 \\ a3" using wf_prec_F compat_equiv_prec by blast + moreover have "a1 \ a2 \ a2 \\ a3 \ a1 \\ a3" using wf_prec_F compat_equiv_prec by blast + moreover have "b1 \l b2 \ b2 \l b3 \ b1 \l b3" + using wf_prec_l unfolding minimal_element_def po_on_def transp_on_def by (meson UNIV_I) + moreover have "a1 \ a2 \ a2 \ a3 \ a1 \ a3" + using equiv_F_is_equiv_rel equiv_class_eq unfolding equiv_F_fun_def by fastforce + ultimately show "(a1 \\ a3 \ a1 \ a3 \ b1 \l b3)" using trans_hyp by blast + qed + qed +next + show "wfp_on (\) UNIV" unfolding wfp_on_def + proof + assume contra: "\f. \i. f i \ UNIV \ f (Suc i) \ f i" + then obtain f where f_in: "\i. f i \ UNIV" and f_suc: "\i. f (Suc i) \ f i" by blast + define f_F where "f_F = (\i. fst (f i))" + define f_L where "f_L = (\i. snd (f i))" + have uni_F: "\i. f_F i \ UNIV" using f_in by simp + have uni_L: "\i. f_L i \ UNIV" using f_in by simp + have decomp: "\i. f_F (Suc i) \\ f_F i \ f_L (Suc i) \l f_L i" + using f_suc unfolding Prec_FL_def f_F_def f_L_def by blast + define I_F where "I_F = { i |i. f_F (Suc i) \\ f_F i}" + define I_L where "I_L = { i |i. f_L (Suc i) \l f_L i}" + have "I_F \ I_L = UNIV" using decomp unfolding I_F_def I_L_def by blast + then have "finite I_F \ \ finite I_L" by (metis finite_UnI infinite_UNIV_nat) + moreover have "infinite I_F \ \f. \i. f i \ UNIV \ f (Suc i) \\ f i" + using uni_F unfolding I_F_def by (meson compat_equiv_prec iso_tuple_UNIV_I not_finite_existsD) + moreover have "infinite I_L \ \f. \i. f i \ UNIV \ f (Suc i) \l f i" + using uni_L unfolding I_L_def + by (metis UNIV_I compat_equiv_prec decomp minimal_element_def wf_prec_F wfp_on_def) + ultimately show False using wf_prec_F wf_prec_l by (metis minimal_element_def wfp_on_def) + qed +qed + +lemma labeled_static_ref_comp: + "static_refutational_complete_calculus Bot_FL Inf_FL (\\L) with_labels.Red_Inf_Q with_labels.Red_F_Q" + using labeled_static_ref[OF static_ref_comp] . + +lemma standard_labeled_lifting_family: "lifting_with_wf_ordering_family Bot_FL Inf_FL Bot_G + (entails_q q) Inf_G (Red_Inf_q q) (Red_F_q q) (\_F_L_q q) (\_Inf_L_q q) (\g. Prec_FL)" +proof - + fix q + have "lifting_with_wf_ordering_family Bot_FL Inf_FL Bot_G (entails_q q) Inf_G + (Red_Inf_q q) (Red_F_q q) (\_F_L_q q) (\_Inf_L_q q) (\g. Labeled_Empty_Order)" + using ord_fam_lifted_q . + then have "standard_lifting Bot_FL Inf_FL Bot_G Inf_G (entails_q q) (Red_Inf_q q) (Red_F_q q) + (\_F_L_q q) (\_Inf_L_q q)" + using lifted_q by blast + then show "lifting_with_wf_ordering_family Bot_FL Inf_FL Bot_G (entails_q q) Inf_G (Red_Inf_q q) + (Red_F_q q) (\_F_L_q q) (\_Inf_L_q q) (\g. Prec_FL)" + using wf_prec_FL + by (simp add: lifting_with_wf_ordering_family.intro lifting_with_wf_ordering_family_axioms.intro) +qed + +sublocale labeled_ord_red_crit_fam: standard_lifting_with_red_crit_family Inf_FL Bot_G Inf_G Q + entails_q Red_Inf_q Red_F_q + Bot_FL \_F_L_q \_Inf_L_q "\g. Prec_FL" + using standard_labeled_lifting_family + no_labels.Ground_family.calculus_with_red_crit_family_axioms + by (simp add: standard_lifting_with_red_crit_family.intro + standard_lifting_with_red_crit_family_axioms.intro) + +lemma entail_equiv: + "labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.entails_Q N1 N2 = (N1 \\L N2)" + unfolding labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.entails_Q_def + entails_\_L_Q_def entails_\_L_q_def labeled_ord_red_crit_fam.entails_\_q_def + labeled_ord_red_crit_fam.\_set_q_def \_set_L_q_def + by simp + +lemma entail_equiv2: "labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.entails_Q = (\\L)" + using entail_equiv by auto + +lemma red_inf_equiv: "labeled_ord_red_crit_fam.empty_ord_lifted_calc_w_red_crit_family.Red_Inf_Q N = + with_labels.Red_Inf_Q N" + unfolding labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_Inf_Q_def + with_labels.Red_Inf_Q_def labeled_ord_red_crit_fam.Red_Inf_\_q_def Red_Inf_\_L_q_def + labeled_ord_red_crit_fam.\_set_q_def \_set_L_q_def + by simp + +lemma red_inf_equiv2: "labeled_ord_red_crit_fam.empty_ord_lifted_calc_w_red_crit_family.Red_Inf_Q = + with_labels.Red_Inf_Q" + using red_inf_equiv by auto + +lemma empty_red_f_equiv: "labeled_ord_red_crit_fam.empty_ord_lifted_calc_w_red_crit_family.Red_F_Q N = + with_labels.Red_F_Q N" + unfolding labeled_ord_red_crit_fam.empty_ord_lifted_calc_w_red_crit_family.Red_F_Q_def + with_labels.Red_F_Q_def labeled_ord_red_crit_fam.Red_F_\_empty_q_def Red_F_\_empty_L_q_def + labeled_ord_red_crit_fam.\_set_q_def \_set_L_q_def Labeled_Empty_Order_def + by simp + +lemma empty_red_f_equiv2: "labeled_ord_red_crit_fam.empty_ord_lifted_calc_w_red_crit_family.Red_F_Q = + with_labels.Red_F_Q" + using empty_red_f_equiv by auto + +lemma labeled_ordered_static_ref_comp: + "static_refutational_complete_calculus Bot_FL Inf_FL + labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.entails_Q + labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_Inf_Q + labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q" + using labeled_ord_red_crit_fam.static_empty_ord_inter_equiv_static_inter empty_red_f_equiv2 + red_inf_equiv2 entail_equiv2 labeled_static_ref_comp + by argo + +interpretation stat_ref_calc: static_refutational_complete_calculus Bot_FL Inf_FL + labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.entails_Q + labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_Inf_Q + labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q + by (rule labeled_ordered_static_ref_comp) + +lemma labeled_ordered_dynamic_ref_comp: + "dynamic_refutational_complete_calculus Bot_FL Inf_FL + labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.entails_Q + labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_Inf_Q + labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q" + by (rule stat_ref_calc.dynamic_refutational_complete_calculus_axioms) + +(* lem:redundant-labeled-inferences *) +lemma labeled_red_inf_eq_red_inf: "\ \ Inf_FL \ + \ \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_Inf_Q N \ + (to_F \) \ no_labels.empty_ord_lifted_calc_w_red_crit_family.Red_Inf_Q (fst ` N)" for \ +proof - + fix \ + assume i_in: "\ \ Inf_FL" + have "\ \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_Inf_Q N \ + (to_F \) \ no_labels.empty_ord_lifted_calc_w_red_crit_family.Red_Inf_Q (fst ` N)" + proof - + assume i_in2: "\ \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_Inf_Q N" + then have "X \ labeled_ord_red_crit_fam.Red_Inf_\_q ` UNIV \ \ \ X N" for X + unfolding labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_Inf_Q_def by blast + obtain X0 where "X0 \ labeled_ord_red_crit_fam.Red_Inf_\_q ` UNIV" by blast + then obtain q0 where x0_is: "X0 N = labeled_ord_red_crit_fam.Red_Inf_\_q q0 N" by blast + then obtain Y0 where y0_is: "Y0 (fst ` N) = to_F ` (X0 N)" by auto + have "Y0 (fst ` N) = no_labels.Red_Inf_\_q q0 (fst ` N)" + unfolding y0_is + proof + show "to_F ` X0 N \ no_labels.Red_Inf_\_q q0 (fst ` N)" + proof + fix \0 + assume i0_in: "\0 \ to_F ` X0 N" + then have i0_in2: "\0 \ to_F ` (labeled_ord_red_crit_fam.Red_Inf_\_q q0 N)" + using x0_is by argo + then obtain \0_FL where i0_FL_in: "\0_FL \ Inf_FL" and i0_to_i0_FL: "\0 = to_F \0_FL" and + subs1: "((\_Inf_L_q q0 \0_FL) \ None \ + the (\_Inf_L_q q0 \0_FL) \ Red_Inf_q q0 (labeled_ord_red_crit_fam.\_set_q q0 N)) + \ ((\_Inf_L_q q0 \0_FL = None) \ + \_F_L_q q0 (concl_of \0_FL) \ (labeled_ord_red_crit_fam.\_set_q q0 N \ + Red_F_q q0 (labeled_ord_red_crit_fam.\_set_q q0 N)))" + unfolding labeled_ord_red_crit_fam.Red_Inf_\_q_def by blast + have concl_swap: "fst (concl_of \0_FL) = concl_of \0" + unfolding concl_of_def i0_to_i0_FL to_F_def by simp + have i0_in3: "\0 \ Inf_F" + using i0_to_i0_FL Inf_FL_to_Inf_F[OF i0_FL_in] unfolding to_F_def by blast + { + assume + not_none: "\_Inf_q q0 \0 \ None" and + "the (\_Inf_q q0 \0) \ {}" + then obtain \1 where i1_in: "\1 \ the (\_Inf_q q0 \0)" by blast + have "the (\_Inf_q q0 \0) \ Red_Inf_q q0 (no_labels.\_set_q q0 (fst ` N))" + using subs1 i0_to_i0_FL not_none + unfolding no_labels.\_set_q_def labeled_ord_red_crit_fam.\_set_q_def + \_Inf_L_q_def \_F_L_q_def by auto + } + moreover { + assume + is_none: "\_Inf_q q0 \0 = None" + then have "\_F_q q0 (concl_of \0) \ no_labels.\_set_q q0 (fst ` N) + \ Red_F_q q0 (no_labels.\_set_q q0 (fst ` N))" + using subs1 i0_to_i0_FL concl_swap + unfolding no_labels.\_set_q_def labeled_ord_red_crit_fam.\_set_q_def + \_Inf_L_q_def \_F_L_q_def by simp + } + ultimately show "\0 \ no_labels.Red_Inf_\_q q0 (fst ` N)" + unfolding no_labels.Red_Inf_\_q_def using i0_in3 by auto + qed + next + show "no_labels.Red_Inf_\_q q0 (fst ` N) \ to_F ` X0 N" + proof + fix \0 + assume i0_in: "\0 \ no_labels.Red_Inf_\_q q0 (fst ` N)" + then have i0_in2: "\0 \ Inf_F" + unfolding no_labels.Red_Inf_\_q_def by blast + obtain \0_FL where i0_FL_in: "\0_FL \ Inf_FL" and i0_to_i0_FL: "\0 = to_F \0_FL" + using Inf_F_to_Inf_FL[OF i0_in2] unfolding to_F_def + by (metis Ex_list_of_length fst_conv inference.exhaust_sel inference.inject map_fst_zip) + have concl_swap: "fst (concl_of \0_FL) = concl_of \0" + unfolding concl_of_def i0_to_i0_FL to_F_def by simp + have subs1: "((\_Inf_L_q q0 \0_FL) \ None \ + the (\_Inf_L_q q0 \0_FL) \ Red_Inf_q q0 (labeled_ord_red_crit_fam.\_set_q q0 N)) + \ ((\_Inf_L_q q0 \0_FL = None) \ + \_F_L_q q0 (concl_of \0_FL) \ (labeled_ord_red_crit_fam.\_set_q q0 N \ + Red_F_q q0 (labeled_ord_red_crit_fam.\_set_q q0 N)))" + using i0_in i0_to_i0_FL concl_swap + unfolding no_labels.Red_Inf_\_q_def \_Inf_L_q_def no_labels.\_set_q_def + labeled_ord_red_crit_fam.\_set_q_def \_F_L_q_def + by simp + then have "\0_FL \ labeled_ord_red_crit_fam.Red_Inf_\_q q0 N" + using i0_FL_in unfolding labeled_ord_red_crit_fam.Red_Inf_\_q_def + by simp + then show "\0 \ to_F ` X0 N" + using x0_is i0_to_i0_FL i0_in2 by blast + qed + qed + then have "Y \ no_labels.Red_Inf_\_q ` UNIV \ (to_F \) \ Y (fst ` N)" for Y + using i_in2 no_labels.lifted_calc_w_red_crit_family.Red_Inf_Q_def + red_inf_equiv2 red_inf_impl by fastforce + then show "(to_F \) \ no_labels.empty_ord_lifted_calc_w_red_crit_family.Red_Inf_Q (fst ` N)" + unfolding labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_Inf_Q_def + no_labels.empty_ord_lifted_calc_w_red_crit_family.Red_Inf_Q_def + by blast + qed + moreover have "(to_F \) \ no_labels.empty_ord_lifted_calc_w_red_crit_family.Red_Inf_Q (fst ` N) \ + \ \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_Inf_Q N" + proof - + assume to_F_in: "to_F \ \ no_labels.empty_ord_lifted_calc_w_red_crit_family.Red_Inf_Q (fst ` N)" + have imp_to_F: "X \ no_labels.Red_Inf_\_q ` UNIV \ to_F \ \ X (fst ` N)" for X + using to_F_in unfolding no_labels.empty_ord_lifted_calc_w_red_crit_family.Red_Inf_Q_def + by blast + then have to_F_in2: "to_F \ \ no_labels.Red_Inf_\_q q (fst ` N)" for q + by fast + have "labeled_ord_red_crit_fam.Red_Inf_\_q q N = + {\0_FL \ Inf_FL. to_F \0_FL \ no_labels.Red_Inf_\_q q (fst ` N)}" for q + proof + show "labeled_ord_red_crit_fam.Red_Inf_\_q q N \ + {\0_FL \ Inf_FL. to_F \0_FL \ no_labels.Red_Inf_\_q q (fst ` N)}" + proof + fix q0 \1 + assume + i1_in: "\1 \ labeled_ord_red_crit_fam.Red_Inf_\_q q0 N" + have i1_in2: "\1 \ Inf_FL" + using i1_in unfolding labeled_ord_red_crit_fam.Red_Inf_\_q_def by blast + then have to_F_i1_in: "to_F \1 \ Inf_F" + using Inf_FL_to_Inf_F unfolding to_F_def by simp + have concl_swap: "fst (concl_of \1) = concl_of (to_F \1)" + unfolding concl_of_def to_F_def by simp + then have i1_to_F_in: "to_F \1 \ no_labels.Red_Inf_\_q q0 (fst ` N)" + using i1_in to_F_i1_in + unfolding labeled_ord_red_crit_fam.Red_Inf_\_q_def no_labels.Red_Inf_\_q_def + \_Inf_L_q_def labeled_ord_red_crit_fam.\_set_q_def no_labels.\_set_q_def \_F_L_q_def + by force + show "\1 \ {\0_FL \ Inf_FL. to_F \0_FL \ no_labels.Red_Inf_\_q q0 (fst ` N)}" + using i1_in2 i1_to_F_in by blast + qed + next + show "{\0_FL \ Inf_FL. to_F \0_FL \ no_labels.Red_Inf_\_q q (fst ` N)} \ + labeled_ord_red_crit_fam.Red_Inf_\_q q N" + proof + fix q0 \1 + assume + i1_in: "\1 \ {\0_FL \ Inf_FL. to_F \0_FL \ no_labels.Red_Inf_\_q q0 (fst ` N)}" + then have i1_in2: "\1 \ Inf_FL" by blast + then have to_F_i1_in: "to_F \1 \ Inf_F" + using Inf_FL_to_Inf_F unfolding to_F_def by simp + have concl_swap: "fst (concl_of \1) = concl_of (to_F \1)" + unfolding concl_of_def to_F_def by simp + then have "((\_Inf_L_q q0 \1) \ None \ + the (\_Inf_L_q q0 \1) \ Red_Inf_q q0 (labeled_ord_red_crit_fam.\_set_q q0 N)) + \ ((\_Inf_L_q q0 \1 = None) \ + \_F_L_q q0 (concl_of \1) \ (labeled_ord_red_crit_fam.\_set_q q0 N \ + Red_F_q q0 (labeled_ord_red_crit_fam.\_set_q q0 N)))" + using i1_in unfolding no_labels.Red_Inf_\_q_def \_Inf_L_q_def + labeled_ord_red_crit_fam.\_set_q_def no_labels.\_set_q_def \_F_L_q_def + by auto + then show "\1 \ labeled_ord_red_crit_fam.Red_Inf_\_q q0 N" + using i1_in2 unfolding labeled_ord_red_crit_fam.Red_Inf_\_q_def + by blast + qed + qed + then have "\ \ labeled_ord_red_crit_fam.Red_Inf_\_q q N" for q + using to_F_in2 i_in + unfolding labeled_ord_red_crit_fam.Red_Inf_\_q_def + no_labels.Red_Inf_\_q_def \_Inf_L_q_def labeled_ord_red_crit_fam.\_set_q_def + no_labels.\_set_q_def \_F_L_q_def + by auto + then show "\ \ labeled_ord_red_crit_fam.empty_ord_lifted_calc_w_red_crit_family.Red_Inf_Q N" + unfolding labeled_ord_red_crit_fam.empty_ord_lifted_calc_w_red_crit_family.Red_Inf_Q_def + by blast + qed + ultimately show "\ \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_Inf_Q N \ + (to_F \) \ no_labels.empty_ord_lifted_calc_w_red_crit_family.Red_Inf_Q (fst ` N)" + by argo +qed + +(* lem:redundant-labeled-formulas *) +lemma red_labeled_clauses: \C \ no_labels.Red_F_\_empty (fst ` N) \ (\C' \ (fst ` N). C \\ C') \ + (\(C',L') \ N. (L' \l L \ C \\ C')) \ + (C,L) \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q N\ +proof - + assume \C \ no_labels.Red_F_\_empty (fst ` N) \ + (\C' \ (fst ` N). C \\ C') \ (\(C',L') \ N. (L' \l L \ C \\ C'))\ + moreover have i: \C \ no_labels.Red_F_\_empty (fst ` N) \ + (C,L) \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q N\ + proof - + assume "C \ no_labels.Red_F_\_empty (fst ` N)" + then have "C \ no_labels.Red_F_\_empty_q q (fst ` N)" for q + unfolding no_labels.Red_F_\_empty_def by fast + then have g_in_red: "\_F_q q C \ Red_F_q q (no_labels.\_set_q q (fst ` N))" for q + unfolding no_labels.Red_F_\_empty_q_def by blast + have "no_labels.\_set_q q (fst ` N) = labeled_ord_red_crit_fam.\_set_q q N" for q + unfolding no_labels.\_set_q_def labeled_ord_red_crit_fam.\_set_q_def \_F_L_q_def by simp + then have "\_F_L_q q (C,L) \ Red_F_q q (labeled_ord_red_crit_fam.\_set_q q N)" for q + using g_in_red unfolding \_F_L_q_def by simp + then show "(C,L) \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q N" + unfolding labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q_def + labeled_ord_red_crit_fam.Red_F_\_q_g_def by blast + qed + moreover have ii: \\C' \ (fst ` N). C \\ C' \ + (C,L) \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q N\ + proof - + assume "\C' \ (fst ` N). C \\ C'" + then obtain C' where c'_in: "C' \ (fst ` N)" and c_prec_c': "C \\ C'" by blast + obtain L' where c'_l'_in: "(C',L') \ N" using c'_in by auto + have c'_l'_prec: "(C',L') \ (C,L)" + using c_prec_c' unfolding Prec_FL_def by (meson UNIV_I compat_equiv_prec) + have c_in_c'_g: "\_F_q q C \ \_F_q q C'" for q + using prec_F_grounding[OF c_prec_c'] by presburger + then have "\_F_L_q q (C,L) \ \_F_L_q q (C',L')" for q + unfolding no_labels.\_set_q_def labeled_ord_red_crit_fam.\_set_q_def \_F_L_q_def by auto + then have "(C,L) \ labeled_ord_red_crit_fam.Red_F_\_q_g q N" for q + unfolding labeled_ord_red_crit_fam.Red_F_\_q_g_def using c'_l'_in c'_l'_prec by blast + then show "(C,L) \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q N" + unfolding labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q_def by blast + qed + moreover have iii: \\(C',L') \ N. (L' \l L \ C \\ C') \ + (C,L) \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q N\ + proof - + assume "\(C',L') \ N. (L' \l L \ C \\ C')" + then obtain C' L' where c'_l'_in: "(C',L') \ N" and l'_sub_l: "L' \l L" and c'_sub_c: "C \\ C'" + by fast + have "(C,L) \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q N" if "C \\ C'" + using that c'_l'_in ii by fastforce + moreover { + assume equiv_c_c': "C \ C'" + then have equiv_c'_c: "C' \ C" + using equiv_F_is_equiv_rel equiv_F_fun_def equiv_class_eq_iff by fastforce + then have c'_l'_prec: "(C',L') \ (C,L)" + using l'_sub_l unfolding Prec_FL_def by simp + have "\_F_q q C = \_F_q q C'" for q + using equiv_F_grounding equiv_c'_c by blast + then have "\_F_L_q q (C,L) = \_F_L_q q (C',L')" for q + unfolding no_labels.\_set_q_def labeled_ord_red_crit_fam.\_set_q_def \_F_L_q_def by auto + then have "(C,L) \ labeled_ord_red_crit_fam.Red_F_\_q_g q N" for q + unfolding labeled_ord_red_crit_fam.Red_F_\_q_g_def using c'_l'_in c'_l'_prec by blast + then have "(C,L) \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q N" + unfolding labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q_def by blast + } + ultimately show "(C,L) \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q N" + using c'_sub_c unfolding Prec_eq_F_def equiv_F_fun_def equiv_F_is_equiv_rel by blast + qed + ultimately show \(C,L) \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q N\ + by blast +qed + +end + +subsection \Given Clause Architecture\ + +locale Given_Clause = Prover_Architecture_Basis Bot_F Inf_F Bot_G Q entails_q Inf_G Red_Inf_q + Red_F_q \_F_q \_Inf_q l Inf_FL Equiv_F Prec_F Prec_l + for + Bot_F :: "'f set" and + Inf_F :: "'f inference set" and + Bot_G :: "'g set" and + Q :: "'q itself" and + entails_q :: "'q \ ('g set \ 'g set \ bool)" and + Inf_G :: \'g inference set\ and + Red_Inf_q :: "'q \ ('g set \ 'g inference set)" and + Red_F_q :: "'q \ ('g set \ 'g set)" and + \_F_q :: "'q \ 'f \ 'g set" and + \_Inf_q :: "'q \ 'f inference \ 'g inference set option" and + l :: "'l itself" and + Inf_FL :: \('f \ 'l) inference set\ and + Equiv_F :: "('f \ 'f) set" and + Prec_F :: "'f \ 'f \ bool" (infix "\\" 50) and + Prec_l :: "'l \ 'l \ bool" (infix "\l" 50) + + fixes + active :: "'l" + assumes + inf_have_premises: "\F \ Inf_F \ length (prems_of \F) > 0" and + active_minimal: "l2 \ active \ active \l l2" and + at_least_two_labels: "\l2. active \l l2" and + inf_never_active: "\ \ Inf_FL \ snd (concl_of \) \ active" +begin + +lemma labeled_inf_have_premises: "\ \ Inf_FL \ set (prems_of \) \ {}" + using inf_have_premises Inf_FL_to_Inf_F by fastforce + +definition active_subset :: "('f \ 'l) set \ ('f \ 'l) set" where + "active_subset M = {CL \ M. snd CL = active}" + +definition non_active_subset :: "('f \ 'l) set \ ('f \ 'l) set" where + "non_active_subset M = {CL \ M. snd CL \ active}" + +inductive Given_Clause_step :: "('f \ 'l) set \ ('f \ 'l) set \ bool" (infix "\GC" 50) where + process: "N1 = N \ M \ N2 = N \ M' \ N \ M = {} \ + M \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q (N \ M') \ + active_subset M' = {} \ N1 \GC N2" | + infer: "N1 = N \ {(C,L)} \ {(C,L)} \ N = {} \ N2 = N \ {(C,active)} \ M \ L \ active \ + active_subset M = {} \ + no_labels.Non_ground.Inf_from2 (fst ` (active_subset N)) {C} \ + no_labels.lifted_calc_w_red_crit_family.Red_Inf_Q (fst ` (N \ {(C,active)} \ M)) \ + N1 \GC N2" + +abbreviation derive :: "('f \ 'l) set \ ('f \ 'l) set \ bool" (infix "\RedL" 50) where + "derive \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.inter_red_crit_calculus.derive" + +lemma one_step_equiv: "N1 \GC N2 \ N1 \RedL N2" +proof (cases N1 N2 rule: Given_Clause_step.cases) + show "N1 \GC N2 \ N1 \GC N2" by blast +next + fix N M M' + assume + gc_step: "N1 \GC N2" and + n1_is: "N1 = N \ M" and + n2_is: "N2 = N \ M'" and + empty_inter: "N \ M = {}" and + m_red: "M \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q (N \ M')" and + active_empty: "active_subset M' = {}" + have "N1 - N2 \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q N2" + using n1_is n2_is empty_inter m_red by auto + then show "labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.inter_red_crit_calculus.derive N1 N2" + unfolding labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.inter_red_crit_calculus.derive.simps by blast +next + fix N C L M + assume + gc_step: "N1 \GC N2" and + n1_is: "N1 = N \ {(C,L)}" and + not_active: "L \ active" and + n2_is: "N2 = N \ {(C, active)} \ M" and + empty_inter: "{(C,L)} \ N = {}" and + active_empty: "active_subset M = {}" + have "(C, active) \ N2" using n2_is by auto + moreover have "C \\ C" using Prec_eq_F_def equiv_F_is_equiv_rel equiv_class_eq_iff by fastforce + moreover have "active \l L" using active_minimal[OF not_active] . + ultimately have "{(C,L)} \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q N2" + using red_labeled_clauses by blast + moreover have "(C,L) \ M \ N1 - N2 = {(C,L)}" using n1_is n2_is empty_inter not_active by auto + moreover have "(C,L) \ M \ N1 - N2 = {}" using n1_is n2_is by auto + ultimately have "N1 - N2 \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q N2" + using empty_red_f_equiv[of N2] by blast + then show "labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.inter_red_crit_calculus.derive N1 N2" + unfolding labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.inter_red_crit_calculus.derive.simps + by blast +qed + +abbreviation fair :: "('f \ 'l) set llist \ bool" where + "fair \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.inter_red_crit_calculus.fair" + +(* lem:gc-derivations-are-red-derivations *) +lemma gc_to_red: "chain (\GC) D \ chain (\RedL) D" + using one_step_equiv Lazy_List_Chain.chain_mono by blast + +lemma (in-) all_ex_finite_set: "(\(j::nat)\{0..(n::nat). P j n) \ + (\n1 n2. \j\{0.. P j n2 \ n1 = n2) \ finite {n. \j \ {0.. nat \ bool" + assume + allj_exn: "\j\{0..n. P j n" and + uniq_n: "\n1 n2. \j\{0.. P j n2 \ n1 = n2" + have "{n. \j \ {0..((\j. {n. P j n}) ` {0..j\{0.. finite {n. \j \ {0..j. {n. P j n}"] by simp + have "\j\{0..!n. P j n" using allj_exn uniq_n by blast + then have "\j\{0..j \ {0..GC) D \ llength D > 0 \ active_subset (lnth D 0) = {} \ + non_active_subset (Liminf_llist D) = {} \ fair D" +proof - + assume + deriv: "chain (\GC) D" and + non_empty: "llength D > 0" and + init_state: "active_subset (lnth D 0) = {}" and + final_state: "non_active_subset (Liminf_llist D) = {}" + show "fair D" + unfolding labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.inter_red_crit_calculus.fair_def + proof + fix \ + assume i_in: "\ \ with_labels.Inf_from (Liminf_llist D)" + have i_in_inf_fl: "\ \ Inf_FL" using i_in unfolding with_labels.Inf_from_def by blast + have "Liminf_llist D = active_subset (Liminf_llist D)" + using final_state unfolding non_active_subset_def active_subset_def by blast + then have i_in2: "\ \ with_labels.Inf_from (active_subset (Liminf_llist D))" using i_in by simp + define m where "m = length (prems_of \)" + then have m_def_F: "m = length (prems_of (to_F \))" unfolding to_F_def by simp + have i_in_F: "to_F \ \ Inf_F" + using i_in Inf_FL_to_Inf_F unfolding with_labels.Inf_from_def to_F_def by blast + then have m_pos: "m > 0" using m_def_F using inf_have_premises by blast + have exist_nj: "\j \ {0..nj. enat (Suc nj) < llength D \ + (prems_of \)!j \ active_subset (lnth D nj) \ + (\k. k > nj \ enat k < llength D \ (prems_of \)!j \ active_subset (lnth D k)))" + proof clarify + fix j + assume j_in: "j \ {0..)!j" + using i_in2 unfolding m_def with_labels.Inf_from_def active_subset_def + by (smt Collect_mem_eq Collect_mono_iff atLeastLessThan_iff nth_mem old.prod.exhaust snd_conv) + then have "(C,active) \ Liminf_llist D" + using j_in i_in unfolding m_def with_labels.Inf_from_def by force + then obtain nj where nj_is: "enat nj < llength D" and + c_in2: "(C,active) \ \ (lnth D ` {k. nj \ k \ enat k < llength D})" + unfolding Liminf_llist_def using init_state by blast + then have c_in3: "\k. k \ nj \ enat k < llength D \ (C,active) \ (lnth D k)" by blast + have nj_pos: "nj > 0" using init_state c_in2 nj_is unfolding active_subset_def by fastforce + obtain nj_min where nj_min_is: "nj_min = (LEAST nj. enat nj < llength D \ + (C,active) \ \ (lnth D ` {k. nj \ k \ enat k < llength D}))" by blast + then have in_allk: "\k. k \ nj_min \ enat k < llength D \ (C,active) \ (lnth D k)" + using c_in3 nj_is c_in2 + by (metis (mono_tags, lifting) INT_E LeastI_ex mem_Collect_eq) + have njm_smaller_D: "enat nj_min < llength D" + using nj_min_is + by (smt LeastI_ex \\thesis. (\nj. \enat nj < llength D; + (C, active) \ \ (lnth D ` {k. nj \ k \ enat k < llength D})\ \ thesis) \ thesis\) + have "nj_min > 0" + using nj_is c_in2 nj_pos nj_min_is + by (metis (mono_tags, lifting) Collect_empty_eq \(C, active) \ Liminf_llist D\ + \Liminf_llist D = active_subset (Liminf_llist D)\ + \\k\nj_min. enat k < llength D \ (C, active) \ lnth D k\ active_subset_def init_state + linorder_not_less mem_Collect_eq non_empty zero_enat_def) + then obtain njm_prec where nj_prec_is: "Suc njm_prec = nj_min" using gr0_conv_Suc by auto + then have njm_prec_njm: "njm_prec < nj_min" by blast + then have njm_prec_njm_enat: "enat njm_prec < enat nj_min" by simp + have njm_prec_smaller_d: "njm_prec < llength D" + using HOL.no_atp(15)[OF njm_smaller_D njm_prec_njm_enat] . + have njm_prec_all_suc: "\k>njm_prec. enat k < llength D \ (C, active) \ lnth D k" + using nj_prec_is in_allk by simp + have notin_njm_prec: "(C, active) \ lnth D njm_prec" + proof (rule ccontr) + assume "\ (C, active) \ lnth D njm_prec" + then have absurd_hyp: "(C, active) \ lnth D njm_prec" by simp + have prec_smaller: "enat njm_prec < llength D" using nj_min_is nj_prec_is + by (smt LeastI_ex Suc_leD \\thesis. (\nj. \enat nj < llength D; + (C, active) \ \ (lnth D ` {k. nj \ k \ enat k < llength D})\ \ thesis) \ thesis\ + enat_ord_simps(1) le_eq_less_or_eq le_less_trans) + have "(C,active) \ \ (lnth D ` {k. njm_prec \ k \ enat k < llength D})" + proof - + { + fix k + assume k_in: "njm_prec \ k \ enat k < llength D" + have "k = njm_prec \ (C,active) \ lnth D k" using absurd_hyp by simp + moreover have "njm_prec < k \ (C,active) \ lnth D k" + using nj_prec_is in_allk k_in by simp + ultimately have "(C,active) \ lnth D k" using k_in by fastforce + } + then show "(C,active) \ \ (lnth D ` {k. njm_prec \ k \ enat k < llength D})" by blast + qed + then have "enat njm_prec < llength D \ + (C,active) \ \ (lnth D ` {k. njm_prec \ k \ enat k < llength D})" + using prec_smaller by blast + then show False + using nj_min_is nj_prec_is Orderings.wellorder_class.not_less_Least njm_prec_njm by blast + qed + then have notin_active_subs_njm_prec: "(C, active) \ active_subset (lnth D njm_prec)" + unfolding active_subset_def by blast + then show "\nj. enat (Suc nj) < llength D \ (prems_of \)!j \ active_subset (lnth D nj) \ + (\k. k > nj \ enat k < llength D \ (prems_of \)!j \ active_subset (lnth D k))" + using c_is njm_prec_all_suc njm_prec_smaller_d by (metis (mono_tags, lifting) + active_subset_def mem_Collect_eq nj_prec_is njm_smaller_D snd_conv) + qed + have uniq_nj: "j \ {0.. + (enat (Suc nj1) < llength D \ + (prems_of \)!j \ active_subset (lnth D nj1) \ + (\k. k > nj1 \ enat k < llength D \ (prems_of \)!j \ active_subset (lnth D k))) \ + (enat (Suc nj2) < llength D \ + (prems_of \)!j \ active_subset (lnth D nj2) \ + (\k. k > nj2 \ enat k < llength D \ (prems_of \)!j \ active_subset (lnth D k))) \ nj1=nj2" + proof (clarify, rule ccontr) + fix j nj1 nj2 + assume "j \ {0.. ! j \ active_subset (lnth D nj1)" and + k_nj1: "\k>nj1. enat k < llength D \ prems_of \ ! j \ active_subset (lnth D k)" and + nj2_notin: "prems_of \ ! j \ active_subset (lnth D nj2)" and + k_nj2: "\k>nj2. enat k < llength D \ prems_of \ ! j \ active_subset (lnth D k)" and + diff_12: "nj1 \ nj2" + have "nj1 < nj2 \ False" + proof - + assume prec_12: "nj1 < nj2" + have "enat nj2 < llength D" using nj2_d using Suc_ile_eq less_trans by blast + then have "prems_of \ ! j \ active_subset (lnth D nj2)" + using k_nj1 prec_12 by simp + then show False using nj2_notin by simp + qed + moreover have "nj1 > nj2 \ False" + proof - + assume prec_21: "nj2 < nj1" + have "enat nj1 < llength D" using nj1_d using Suc_ile_eq less_trans by blast + then have "prems_of \ ! j \ active_subset (lnth D nj1)" + using k_nj2 prec_21 + by simp + then show False using nj1_notin by simp + qed + ultimately show False using diff_12 by linarith + qed + define nj_set where "nj_set = {nj. (\j\{0.. + (prems_of \)!j \ active_subset (lnth D nj) \ + (\k. k > nj \ enat k < llength D \ (prems_of \)!j \ active_subset (lnth D k)))}" + then have nj_not_empty: "nj_set \ {}" + proof - + have zero_in: "0 \ {0.. ! 0 \ active_subset (lnth D n0)" and + "\k>n0. enat k < llength D \ prems_of \ ! 0 \ active_subset (lnth D k)" + using exist_nj by fast + then have "n0 \ nj_set" unfolding nj_set_def using zero_in by blast + then show "nj_set \ {}" by auto + qed + have nj_finite: "finite nj_set" + using uniq_nj all_ex_finite_set[OF exist_nj] + by (metis (no_types, lifting) Suc_ile_eq dual_order.strict_implies_order + linorder_neqE_nat nj_set_def) + (* the n below in the n-1 from the pen-and-paper proof *) + have "\n \ nj_set. \nj \ nj_set. nj \ n" + using nj_not_empty nj_finite using Max_ge Max_in by blast + then obtain n where n_in: "n \ nj_set" and n_bigger: "\nj \ nj_set. nj \ n" by blast + then obtain j0 where j0_in: "j0 \ {0..)!j0 \ active_subset (lnth D n)" and + j0_allin: "(\k. k > n \ enat k < llength D \ (prems_of \)!j0 \ active_subset (lnth D k))" + unfolding nj_set_def by blast + obtain C0 where C0_is: "(prems_of \)!j0 = (C0,active)" using j0_in + using i_in2 unfolding m_def with_labels.Inf_from_def active_subset_def + by (smt Collect_mem_eq Collect_mono_iff atLeastLessThan_iff nth_mem old.prod.exhaust snd_conv) + then have C0_prems_i: "(C0,active) \ set (prems_of \)" using in_set_conv_nth j0_in m_def by force + have C0_in: "(C0,active) \ (lnth D (Suc n))" + using C0_is j0_allin suc_n_length by (simp add: active_subset_def) + have C0_notin: "(C0,active) \ (lnth D n)" using C0_is j0_notin unfolding active_subset_def by simp + have step_n: "lnth D n \GC lnth D (Suc n)" + using deriv chain_lnth_rel n_in unfolding nj_set_def by blast + have "\N C L M. (lnth D n = N \ {(C,L)} \ {(C,L)} \ N = {} \ + lnth D (Suc n) = N \ {(C,active)} \ M \ L \ active \ + active_subset M = {} \ + no_labels.Non_ground.Inf_from2 (fst ` (active_subset N)) {C} \ + no_labels.lifted_calc_w_red_crit_family.Red_Inf_Q (fst ` (N \ {(C,active)} \ M)))" + proof - + have proc_or_infer: "(\N1 N M N2 M'. lnth D n = N1 \ lnth D (Suc n) = N2 \ N1 = N \ M \ + N2 = N \ M' \ N \ M = {} \ + M \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q (N \ M') \ + active_subset M' = {}) \ + (\N1 N C L N2 M. lnth D n = N1 \ lnth D (Suc n) = N2 \ N1 = N \ {(C, L)} \ + {(C, L)} \ N = {} \ N2 = N \ {(C, active)} \ M \ + L \ active \ active_subset M = {} \ + no_labels.Non_ground.Inf_from2 (fst ` (active_subset N)) {C} \ + no_labels.lifted_calc_w_red_crit_family.Red_Inf_Q (fst ` (N \ {(C,active)} \ M)))" + using Given_Clause_step.simps[of "lnth D n" "lnth D (Suc n)"] step_n by blast + show ?thesis + using C0_in C0_notin proc_or_infer j0_in C0_is + by (smt Un_iff active_subset_def mem_Collect_eq snd_conv sup_bot.right_neutral) + qed + then obtain N M L where inf_from_subs: + "no_labels.Non_ground.Inf_from2 (fst ` (active_subset N)) {C0} \ + no_labels.lifted_calc_w_red_crit_family.Red_Inf_Q (fst ` (N \ {(C0,active)} \ M))" and + nth_d_is: "lnth D n = N \ {(C0,L)}" and + suc_nth_d_is: "lnth D (Suc n) = N \ {(C0,active)} \ M" and + l_not_active: "L \ active" + using C0_in C0_notin j0_in C0_is using active_subset_def by fastforce + have "j \ {0.. (prems_of \)!j \ (prems_of \)!j0 \ (prems_of \)!j \ (active_subset N)" for j + proof - + fix j + assume j_in: "j \ {0..)!j \ (prems_of \)!j0" + obtain nj where nj_len: "enat (Suc nj) < llength D" and + nj_prems: "(prems_of \)!j \ active_subset (lnth D nj)" and + nj_greater: "(\k. k > nj \ enat k < llength D \ (prems_of \)!j \ active_subset (lnth D k))" + using exist_nj j_in by blast + then have "nj \ nj_set" unfolding nj_set_def using j_in by blast + moreover have "nj \ n" + proof (rule ccontr) + assume "\ nj \ n" + then have "(prems_of \)!j = (C0,active)" + using C0_in C0_notin Given_Clause_step.simps[of "lnth D n" "lnth D (Suc n)"] step_n + by (smt Un_iff Un_insert_right nj_greater nj_prems active_subset_def empty_Collect_eq + insertE lessI mem_Collect_eq prod.sel(2) suc_n_length) + then show False using j_not_j0 C0_is by simp + qed + ultimately have "nj < n" using n_bigger by force + then have "(prems_of \)!j \ (active_subset (lnth D n))" + using nj_greater n_in Suc_ile_eq dual_order.strict_implies_order unfolding nj_set_def by blast + then show "(prems_of \)!j \ (active_subset N)" + using nth_d_is l_not_active unfolding active_subset_def by force + qed + then have "set (prems_of \) \ active_subset N \ {(C0, active)}" + using C0_prems_i C0_is m_def by (metis Un_iff atLeast0LessThan in_set_conv_nth insertCI lessThan_iff subrelI) + moreover have "\ (set (prems_of \) \ active_subset N - {(C0, active)})" using C0_prems_i by blast + ultimately have "\ \ with_labels.Inf_from2 (active_subset N) {(C0,active)}" + using i_in_inf_fl unfolding with_labels.Inf_from2_def with_labels.Inf_from_def by blast + then have "to_F \ \ no_labels.Non_ground.Inf_from2 (fst ` (active_subset N)) {C0}" + unfolding to_F_def with_labels.Inf_from2_def with_labels.Inf_from_def + no_labels.Non_ground.Inf_from2_def no_labels.Non_ground.Inf_from_def using Inf_FL_to_Inf_F + by force + then have "to_F \ \ no_labels.lifted_calc_w_red_crit_family.Red_Inf_Q (fst ` (lnth D (Suc n)))" + using suc_nth_d_is inf_from_subs by fastforce + then have "\q. (\_Inf_q q (to_F \) \ None \ + the (\_Inf_q q (to_F \)) \ Red_Inf_q q (\ (\_F_q q ` (fst ` (lnth D (Suc n)))))) + \ (\_Inf_q q (to_F \) = None \ + \_F_q q (concl_of (to_F \)) \ (\ (\_F_q q ` (fst ` (lnth D (Suc n))))) \ + Red_F_q q (\ (\_F_q q ` (fst ` (lnth D (Suc n))))))" + unfolding to_F_def no_labels.lifted_calc_w_red_crit_family.Red_Inf_Q_def + no_labels.Red_Inf_\_q_def no_labels.\_set_q_def + by fastforce + then have "\ \ with_labels.Red_Inf_Q (lnth D (Suc n))" + unfolding to_F_def with_labels.Red_Inf_Q_def Red_Inf_\_L_q_def \_Inf_L_q_def \_set_L_q_def + \_F_L_q_def using i_in_inf_fl by auto + then show "\ \ + labeled_ord_red_crit_fam.empty_ord_lifted_calc_w_red_crit_family.inter_red_crit_calculus.Sup_Red_Inf_llist D" + unfolding + labeled_ord_red_crit_fam.empty_ord_lifted_calc_w_red_crit_family.inter_red_crit_calculus.Sup_Red_Inf_llist_def + using red_inf_equiv2 suc_n_length by auto + qed +qed + +(* thm:gc-completeness *) +theorem gc_complete: "chain (\GC) D \ llength D > 0 \ active_subset (lnth D 0) = {} \ + non_active_subset (Liminf_llist D) = {} \ B \ Bot_F \ + no_labels.entails_\_Q (fst ` (lnth D 0)) {B} \ + \i. enat i < llength D \ (\BL\ Bot_FL. BL \ (lnth D i))" +proof - + fix B + assume + deriv: "chain (\GC) D" and + not_empty_d: "llength D > 0" and + init_state: "active_subset (lnth D 0) = {}" and + final_state: "non_active_subset (Liminf_llist D) = {}" and + b_in: "B \ Bot_F" and + bot_entailed: "no_labels.entails_\_Q (fst ` (lnth D 0)) {B}" + have labeled_b_in: "(B,active) \ Bot_FL" unfolding Bot_FL_def using b_in by simp + have not_empty_d2: "\ lnull D" using not_empty_d by force + have labeled_bot_entailed: "entails_\_L_Q (lnth D 0) {(B,active)}" + using labeled_entailment_lifting bot_entailed by fastforce + have "fair D" using gc_fair[OF deriv not_empty_d init_state final_state] . + then have "\i \ {i. enat i < llength D}. \BL\Bot_FL. BL \ lnth D i" + using labeled_ordered_dynamic_ref_comp labeled_b_in not_empty_d2 gc_to_red[OF deriv] + labeled_bot_entailed entail_equiv + unfolding dynamic_refutational_complete_calculus_def + dynamic_refutational_complete_calculus_axioms_def by blast + then show ?thesis by blast +qed + +end + +subsection \Lazy Given Clause Architecture\ + +locale Lazy_Given_Clause = Prover_Architecture_Basis Bot_F Inf_F Bot_G Q entails_q Inf_G Red_Inf_q + Red_F_q \_F_q \_Inf_q l Inf_FL Equiv_F Prec_F Prec_l + for + Bot_F :: "'f set" and + Inf_F :: "'f inference set" and + Bot_G :: "'g set" and + Q :: "'q itself" and + entails_q :: "'q \ ('g set \ 'g set \ bool)" and + Inf_G :: \'g inference set\ and + Red_Inf_q :: "'q \ ('g set \ 'g inference set)" and + Red_F_q :: "'q \ ('g set \ 'g set)" and + \_F_q :: "'q \ 'f \ 'g set" and + \_Inf_q :: "'q \ 'f inference \ 'g inference set option" and + l :: "'l itself" and + Inf_FL :: \('f \ 'l) inference set\ and + Equiv_F :: "('f \ 'f) set" and + Prec_F :: "'f \ 'f \ bool" (infix "\\" 50) and + Prec_l :: "'l \ 'l \ bool" (infix "\l" 50) + + fixes + active :: "'l" + assumes + active_minimal: "l2 \ active \ active \l l2" and + at_least_two_labels: "\l2. active \l l2" and + inf_never_active: "\ \ Inf_FL \ snd (concl_of \) \ active" +begin + +definition active_subset :: "('f \ 'l) set \ ('f \ 'l) set" where + "active_subset M = {CL \ M. snd CL = active}" + +definition non_active_subset :: "('f \ 'l) set \ ('f \ 'l) set" where + "non_active_subset M = {CL \ M. snd CL \ active}" + +inductive Lazy_Given_Clause_step :: "('f inference set) \ (('f \ 'l) set) \ + ('f inference set) \ (('f \ 'l) set) \ bool" (infix "\LGC" 50) where + process: "N1 = N \ M \ N2 = N \ M' \ N \ M = {} \ + M \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q (N \ M') \ + active_subset M' = {} \ (T,N1) \LGC (T,N2)" | + schedule_infer: "T2 = T1 \ T' \ N1 = N \ {(C,L)} \ {(C,L)} \ N = {} \ N2 = N \ {(C,active)} \ + L \ active \ T' = no_labels.Non_ground.Inf_from2 (fst ` (active_subset N)) {C} \ + (T1,N1) \LGC (T2,N2)" | + compute_infer: "T1 = T2 \ {\} \ T2 \ {\} = {} \ N2 = N1 \ M \ active_subset M = {} \ + \ \ no_labels.lifted_calc_w_red_crit_family.Red_Inf_Q (fst ` (N1 \ M)) \ + (T1,N1) \LGC (T2,N2)" | + delete_orphans: "T1 = T2 \ T' \ T2 \ T' = {} \ + T' \ no_labels.Non_ground.Inf_from (fst ` (active_subset N)) = {} \ (T1,N) \LGC (T2,N)" + +abbreviation derive :: "('f \ 'l) set \ ('f \ 'l) set \ bool" (infix "\RedL" 50) where + "derive \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.inter_red_crit_calculus.derive" + +lemma premise_free_inf_always_from: "\ \ Inf_F \ length (prems_of \) = 0 \ + \ \ no_labels.Non_ground.Inf_from N" + unfolding no_labels.Non_ground.Inf_from_def by simp + +lemma one_step_equiv: "(T1,N1) \LGC (T2,N2) \ N1 \RedL N2" +proof (cases "(T1,N1)" "(T2,N2)" rule: Lazy_Given_Clause_step.cases) + show "(T1,N1) \LGC (T2,N2) \ (T1,N1) \LGC (T2,N2)" by blast +next + fix N M M' + assume + n1_is: "N1 = N \ M" and + n2_is: "N2 = N \ M'" and + empty_inter: "N \ M = {}" and + m_red: "M \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q (N \ M')" + have "N1 - N2 \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q N2" + using n1_is n2_is empty_inter m_red by auto + then show "N1 \RedL N2" + unfolding labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.inter_red_crit_calculus.derive.simps by blast +next + fix N C L M + assume + n1_is: "N1 = N \ {(C,L)}" and + not_active: "L \ active" and + n2_is: "N2 = N \ {(C, active)}" + have "(C, active) \ N2" using n2_is by auto + moreover have "C \\ C" using Prec_eq_F_def equiv_F_is_equiv_rel equiv_class_eq_iff by fastforce + moreover have "active \l L" using active_minimal[OF not_active] . + ultimately have "{(C,L)} \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q N2" + using red_labeled_clauses by blast + then have "N1 - N2 \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q N2" + using empty_red_f_equiv[of N2] using n1_is n2_is by blast + then show "N1 \RedL N2" + unfolding labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.inter_red_crit_calculus.derive.simps + by blast +next + fix M + assume + n2_is: "N2 = N1 \ M" + have "N1 - N2 \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q N2" + using n2_is by blast + then show "N1 \RedL N2" + unfolding labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.inter_red_crit_calculus.derive.simps + by blast +next + assume n2_is: "N2 = N1" + have "N1 - N2 \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.Red_F_Q N2" + using n2_is by blast + then show "N1 \RedL N2" + unfolding labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.inter_red_crit_calculus.derive.simps + by blast +qed + +abbreviation fair :: "('f \ 'l) set llist \ bool" where + "fair \ labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.inter_red_crit_calculus.fair" + +(* lem:lgc-derivations-are-red-derivations *) +lemma lgc_to_red: "chain (\LGC) D \ chain (\RedL) (lmap snd D)" + using one_step_equiv Lazy_List_Chain.chain_mono by (smt chain_lmap prod.collapse) + +(* lem:fair-lgc-derivations *) +lemma lgc_fair: "chain (\LGC) D \ llength D > 0 \ active_subset (snd (lnth D 0)) = {} \ + non_active_subset (Liminf_llist (lmap snd D)) = {} \ (\\ \ Inf_F. length (prems_of \) = 0 \ + \ \ (fst (lnth D 0))) \ + Liminf_llist (lmap fst D) = {} \ fair (lmap snd D)" +proof - + assume + deriv: "chain (\LGC) D" and + non_empty: "llength D > 0" and + init_state: "active_subset (snd (lnth D 0)) = {}" and + final_state: "non_active_subset (Liminf_llist (lmap snd D)) = {}" and + no_prems_init_active: "\\ \ Inf_F. length (prems_of \) = 0 \ \ \ (fst (lnth D 0))" and + final_schedule: "Liminf_llist (lmap fst D) = {}" + show "fair (lmap snd D)" + unfolding labeled_ord_red_crit_fam.lifted_calc_w_red_crit_family.inter_red_crit_calculus.fair_def + proof + fix \ + assume i_in: "\ \ with_labels.Inf_from (Liminf_llist (lmap snd D))" + have i_in_inf_fl: "\ \ Inf_FL" using i_in unfolding with_labels.Inf_from_def by blast + have "Liminf_llist (lmap snd D) = active_subset (Liminf_llist (lmap snd D))" + using final_state unfolding non_active_subset_def active_subset_def by blast + then have i_in2: "\ \ with_labels.Inf_from (active_subset (Liminf_llist (lmap snd D)))" + using i_in by simp + define m where "m = length (prems_of \)" + then have m_def_F: "m = length (prems_of (to_F \))" unfolding to_F_def by simp + have i_in_F: "to_F \ \ Inf_F" + using i_in Inf_FL_to_Inf_F unfolding with_labels.Inf_from_def to_F_def by blast + have exist_nj: "\j \ {0..nj. enat (Suc nj) < llength D \ + (prems_of \)!j \ active_subset (snd (lnth D nj)) \ + (\k. k > nj \ enat k < llength D \ (prems_of \)!j \ active_subset (snd (lnth D k))))" + proof clarify + fix j + assume j_in: "j \ {0..)!j" + using i_in2 unfolding m_def with_labels.Inf_from_def active_subset_def + by (smt Collect_mem_eq Collect_mono_iff atLeastLessThan_iff nth_mem old.prod.exhaust snd_conv) + then have "(C,active) \ Liminf_llist (lmap snd D)" + using j_in i_in unfolding m_def with_labels.Inf_from_def by force + then obtain nj where nj_is: "enat nj < llength D" and + c_in2: "(C,active) \ \ (snd ` (lnth D ` {k. nj \ k \ enat k < llength D}))" + unfolding Liminf_llist_def using init_state by fastforce + then have c_in3: "\k. k \ nj \ enat k < llength D \ (C,active) \ snd (lnth D k)" by blast + have nj_pos: "nj > 0" using init_state c_in2 nj_is unfolding active_subset_def by fastforce + obtain nj_min where nj_min_is: "nj_min = (LEAST nj. enat nj < llength D \ + (C,active) \ \ (snd ` (lnth D ` {k. nj \ k \ enat k < llength D})))" by blast + then have in_allk: "\k. k \ nj_min \ enat k < llength D \ (C,active) \ snd (lnth D k)" + using c_in3 nj_is c_in2 INT_E LeastI_ex + by (smt INT_iff INT_simps(10) c_is image_eqI mem_Collect_eq) + have njm_smaller_D: "enat nj_min < llength D" + using nj_min_is + by (smt LeastI_ex \\thesis. (\nj. \enat nj < llength D; + (C, active) \ \ (snd ` (lnth D ` {k. nj \ k \ enat k < llength D}))\ \ thesis) \ thesis\) + have "nj_min > 0" + using nj_is c_in2 nj_pos nj_min_is + by (metis (mono_tags, lifting) active_subset_def emptyE in_allk init_state mem_Collect_eq + non_empty not_less snd_conv zero_enat_def) + then obtain njm_prec where nj_prec_is: "Suc njm_prec = nj_min" using gr0_conv_Suc by auto + then have njm_prec_njm: "njm_prec < nj_min" by blast + then have njm_prec_njm_enat: "enat njm_prec < enat nj_min" by simp + have njm_prec_smaller_d: "njm_prec < llength D" + using HOL.no_atp(15)[OF njm_smaller_D njm_prec_njm_enat] . + have njm_prec_all_suc: "\k>njm_prec. enat k < llength D \ (C, active) \ snd (lnth D k)" + using nj_prec_is in_allk by simp + have notin_njm_prec: "(C, active) \ snd (lnth D njm_prec)" + proof (rule ccontr) + assume "\ (C, active) \ snd (lnth D njm_prec)" + then have absurd_hyp: "(C, active) \ snd (lnth D njm_prec)" by simp + have prec_smaller: "enat njm_prec < llength D" using nj_min_is nj_prec_is + by (smt LeastI_ex Suc_leD \\thesis. (\nj. \enat nj < llength D; + (C, active) \ \ (snd ` (lnth D ` {k. nj \ k \ enat k < llength D}))\ \ thesis) \ thesis\ + enat_ord_simps(1) le_eq_less_or_eq le_less_trans) + have "(C,active) \ \ (snd ` (lnth D ` {k. njm_prec \ k \ enat k < llength D}))" + proof - + { + fix k + assume k_in: "njm_prec \ k \ enat k < llength D" + have "k = njm_prec \ (C,active) \ snd (lnth D k)" using absurd_hyp by simp + moreover have "njm_prec < k \ (C,active) \ snd (lnth D k)" + using nj_prec_is in_allk k_in by simp + ultimately have "(C,active) \ snd (lnth D k)" using k_in by fastforce + } + then show "(C,active) \ \ (snd ` (lnth D ` {k. njm_prec \ k \ enat k < llength D}))" + by blast + qed + then have "enat njm_prec < llength D \ + (C,active) \ \ (snd ` (lnth D ` {k. njm_prec \ k \ enat k < llength D}))" + using prec_smaller by blast + then show False + using nj_min_is nj_prec_is Orderings.wellorder_class.not_less_Least njm_prec_njm by blast + qed + then have notin_active_subs_njm_prec: "(C, active) \ active_subset (snd (lnth D njm_prec))" + unfolding active_subset_def by blast + then show "\nj. enat (Suc nj) < llength D \ (prems_of \)!j \ active_subset (snd (lnth D nj)) \ + (\k. k > nj \ enat k < llength D \ (prems_of \)!j \ active_subset (snd (lnth D k)))" + using c_is njm_prec_all_suc njm_prec_smaller_d by (metis (mono_tags, lifting) + active_subset_def mem_Collect_eq nj_prec_is njm_smaller_D snd_conv) + qed + define nj_set where "nj_set = {nj. (\j\{0.. + (prems_of \)!j \ active_subset (snd (lnth D nj)) \ + (\k. k > nj \ enat k < llength D \ (prems_of \)!j \ active_subset (snd (lnth D k))))}" + { + assume m_null: "m = 0" + then have "enat 0 < llength D \ to_F \ \ fst (lnth D 0)" + using no_prems_init_active i_in_F non_empty m_def_F zero_enat_def by auto + then have "\n. enat n < llength D \ to_F \ \ fst (lnth D n)" + by blast + } + moreover { + assume m_pos: "m > 0" + have uniq_nj: "j \ {0.. + (enat (Suc nj1) < llength D \ + (prems_of \)!j \ active_subset (snd (lnth D nj1)) \ + (\k. k > nj1 \ enat k < llength D \ (prems_of \)!j \ active_subset (snd (lnth D k)))) \ + (enat (Suc nj2) < llength D \ + (prems_of \)!j \ active_subset (snd (lnth D nj2)) \ + (\k. k > nj2 \ enat k < llength D \ (prems_of \)!j \ active_subset (snd (lnth D k)))) \ + nj1=nj2" + proof (clarify, rule ccontr) + fix j nj1 nj2 + assume "j \ {0.. ! j \ active_subset (snd (lnth D nj1))" and + k_nj1: "\k>nj1. enat k < llength D \ prems_of \ ! j \ active_subset (snd (lnth D k))" and + nj2_notin: "prems_of \ ! j \ active_subset (snd (lnth D nj2))" and + k_nj2: "\k>nj2. enat k < llength D \ prems_of \ ! j \ active_subset (snd (lnth D k))" and + diff_12: "nj1 \ nj2" + have "nj1 < nj2 \ False" + proof - + assume prec_12: "nj1 < nj2" + have "enat nj2 < llength D" using nj2_d using Suc_ile_eq less_trans by blast + then have "prems_of \ ! j \ active_subset (snd (lnth D nj2))" + using k_nj1 prec_12 by simp + then show False using nj2_notin by simp + qed + moreover have "nj1 > nj2 \ False" + proof - + assume prec_21: "nj2 < nj1" + have "enat nj1 < llength D" using nj1_d using Suc_ile_eq less_trans by blast + then have "prems_of \ ! j \ active_subset (snd (lnth D nj1))" + using k_nj2 prec_21 + by simp + then show False using nj1_notin by simp + qed + ultimately show False using diff_12 by linarith + qed + have nj_not_empty: "nj_set \ {}" + proof - + have zero_in: "0 \ {0.. ! 0 \ active_subset (snd (lnth D n0))" and + "\k>n0. enat k < llength D \ prems_of \ ! 0 \ active_subset (snd (lnth D k))" + using exist_nj by fast + then have "n0 \ nj_set" unfolding nj_set_def using zero_in by blast + then show "nj_set \ {}" by auto + qed + have nj_finite: "finite nj_set" + using uniq_nj all_ex_finite_set[OF exist_nj] by (metis (no_types, lifting) Suc_ile_eq + dual_order.strict_implies_order linorder_neqE_nat nj_set_def) + have "\n \ nj_set. \nj \ nj_set. nj \ n" + using nj_not_empty nj_finite using Max_ge Max_in by blast + then obtain n where n_in: "n \ nj_set" and n_bigger: "\nj \ nj_set. nj \ n" by blast + then obtain j0 where j0_in: "j0 \ {0..)!j0 \ active_subset (snd (lnth D n))" and + j0_allin: "(\k. k > n \ enat k < llength D \ + (prems_of \)!j0 \ active_subset (snd (lnth D k)))" + unfolding nj_set_def by blast + obtain C0 where C0_is: "(prems_of \)!j0 = (C0,active)" + using j0_in i_in2 unfolding m_def with_labels.Inf_from_def active_subset_def + by (smt Collect_mem_eq Collect_mono_iff atLeastLessThan_iff nth_mem old.prod.exhaust snd_conv) + then have C0_prems_i: "(C0,active) \ set (prems_of \)" using in_set_conv_nth j0_in m_def by force + have C0_in: "(C0,active) \ (snd (lnth D (Suc n)))" + using C0_is j0_allin suc_n_length by (simp add: active_subset_def) + have C0_notin: "(C0,active) \ (snd (lnth D n))" + using C0_is j0_notin unfolding active_subset_def by simp + have step_n: "lnth D n \LGC lnth D (Suc n)" + using deriv chain_lnth_rel n_in unfolding nj_set_def by blast + have is_scheduled: "\T2 T1 T' N1 N C L N2. lnth D n = (T1, N1) \ lnth D (Suc n) = (T2, N2) \ + T2 = T1 \ T' \ N1 = N \ {(C, L)} \ {(C, L)} \ N = {} \ N2 = N \ {(C, active)} \ L \ active \ + T' = no_labels.Non_ground.Inf_from2 (fst ` active_subset N) {C}" + using Lazy_Given_Clause_step.simps[of "lnth D n" "lnth D (Suc n)"] step_n C0_in C0_notin + unfolding active_subset_def by fastforce + then obtain T2 T1 T' N1 N L N2 where nth_d_is: "lnth D n = (T1, N1)" and + suc_nth_d_is: "lnth D (Suc n) = (T2, N2)" and t2_is: "T2 = T1 \ T'" and + n1_is: "N1 = N \ {(C0, L)}" "{(C0, L)} \ N = {}" "N2 = N \ {(C0, active)}" and + l_not_active: "L \ active" and + tp_is: "T' = no_labels.Non_ground.Inf_from2 (fst ` active_subset N) {C0}" + using C0_in C0_notin j0_in C0_is using active_subset_def by fastforce + have "j \ {0.. (prems_of \)!j \ (prems_of \)!j0 \ (prems_of \)!j \ (active_subset N)" + for j + proof - + fix j + assume j_in: "j \ {0..)!j \ (prems_of \)!j0" + obtain nj where nj_len: "enat (Suc nj) < llength D" and + nj_prems: "(prems_of \)!j \ active_subset (snd (lnth D nj))" and + nj_greater: "(\k. k > nj \ enat k < llength D \ + (prems_of \)!j \ active_subset (snd (lnth D k)))" + using exist_nj j_in by blast + then have "nj \ nj_set" unfolding nj_set_def using j_in by blast + moreover have "nj \ n" + proof (rule ccontr) + assume "\ nj \ n" + then have "(prems_of \)!j = (C0,active)" + using C0_in C0_notin Lazy_Given_Clause_step.simps[of "lnth D n" "lnth D (Suc n)"] step_n + active_subset_def is_scheduled nj_greater nj_prems suc_n_length by auto + then show False using j_not_j0 C0_is by simp + qed + ultimately have "nj < n" using n_bigger by force + then have "(prems_of \)!j \ (active_subset (snd (lnth D n)))" + using nj_greater n_in Suc_ile_eq dual_order.strict_implies_order + unfolding nj_set_def by blast + then show "(prems_of \)!j \ (active_subset N)" + using nth_d_is l_not_active n1_is unfolding active_subset_def by force + qed + then have prems_i_active: "set (prems_of \) \ active_subset N \ {(C0, active)}" + using C0_prems_i C0_is m_def + by (metis Un_iff atLeast0LessThan in_set_conv_nth insertCI lessThan_iff subrelI) + moreover have "\ (set (prems_of \) \ active_subset N - {(C0, active)})" using C0_prems_i by blast + ultimately have "\ \ with_labels.Inf_from2 (active_subset N) {(C0,active)}" + using i_in_inf_fl prems_i_active unfolding with_labels.Inf_from2_def with_labels.Inf_from_def + by blast + then have "to_F \ \ no_labels.Non_ground.Inf_from2 (fst ` (active_subset N)) {C0}" + unfolding to_F_def with_labels.Inf_from2_def with_labels.Inf_from_def + no_labels.Non_ground.Inf_from2_def no_labels.Non_ground.Inf_from_def + using Inf_FL_to_Inf_F by force + then have i_in_t2: "to_F \ \ T2" using tp_is t2_is by simp + have "j \ {0.. (\k. k > n \ enat k < llength D \ + (prems_of \)!j \ active_subset (snd (lnth D k)))" for j + proof (cases "j = j0") + case True + assume "j = j0" + then show "(\k. k > n \ enat k < llength D \ + (prems_of \)!j \ active_subset (snd (lnth D k)))" using j0_allin by simp + next + case False + assume j_in: "j \ {0.. j0" + obtain nj where nj_len: "enat (Suc nj) < llength D" and + nj_prems: "(prems_of \)!j \ active_subset (snd (lnth D nj))" and + nj_greater: "(\k. k > nj \ enat k < llength D \ + (prems_of \)!j \ active_subset (snd (lnth D k)))" + using exist_nj j_in by blast + then have "nj \ nj_set" unfolding nj_set_def using j_in by blast + then show "(\k. k > n \ enat k < llength D \ + (prems_of \)!j \ active_subset (snd (lnth D k)))" + using nj_greater n_bigger by auto + qed + then have allj_allk: "(\c\ set (prems_of \). (\k. k > n \ enat k < llength D \ + c \ active_subset (snd (lnth D k))))" + using m_def by (metis atLeast0LessThan in_set_conv_nth lessThan_iff) + have "\c\ set (prems_of \). snd c = active" + using prems_i_active unfolding active_subset_def by auto + then have ex_n_i_in: "\n. enat (Suc n) < llength D \ to_F \ \ fst (lnth D (Suc n)) \ + (\c\ set (prems_of \). snd c = active) \ + (\c\ set (prems_of \). (\k. k > n \ enat k < llength D \ + c \ active_subset (snd (lnth D k))))" + using allj_allk i_in_t2 suc_nth_d_is fstI n_in nj_set_def + by auto + then have "\n. enat n < llength D \ to_F \ \ fst (lnth D n) \ + (\c\ set (prems_of \). snd c = active) \ (\c\ set (prems_of \). (\k. k \ n \ + enat k < llength D \ c \ active_subset (snd (lnth D k))))" + by auto + } + ultimately obtain n T2 N2 where i_in_suc_n: "to_F \ \ fst (lnth D n)" and + all_prems_active_after: "m > 0 \ (\c\ set (prems_of \). (\k. k \ n \ enat k < llength D \ + c \ active_subset (snd (lnth D k))))" and + suc_n_length: "enat n < llength D" and suc_nth_d_is: "lnth D n = (T2, N2)" + by (metis less_antisym old.prod.exhaust zero_less_Suc) + then have i_in_t2: "to_F \ \ T2" by simp + have "\p\n. enat (Suc p) < llength D \ to_F \ \ (fst (lnth D p)) \ to_F \ \ (fst (lnth D (Suc p)))" + proof (rule ccontr) + assume + contra: "\ (\p\n. enat (Suc p) < llength D \ to_F \ \ (fst (lnth D p)) \ + to_F \ \ (fst (lnth D (Suc p))))" + then have i_in_suc: "p0 \ n \ enat (Suc p0) < llength D \ to_F \ \ (fst (lnth D p0)) \ + to_F \ \ (fst (lnth D (Suc p0)))" for p0 + by blast + have "p0 \ n \ enat p0 < llength D \ to_F \ \ (fst (lnth D p0))" for p0 + proof (induction rule: nat_induct_at_least) + case base + then show ?case using i_in_t2 suc_nth_d_is + by simp + next + case (Suc p0) + assume p_bigger_n: "n \ p0" and + induct_hyp: "enat p0 < llength D \ to_F \ \ fst (lnth D p0)" and + sucsuc_smaller_d: "enat (Suc p0) < llength D" + have suc_p_bigger_n: "n \ p0" using p_bigger_n by simp + have suc_smaller_d: "enat p0 < llength D" + using sucsuc_smaller_d Suc_ile_eq dual_order.strict_implies_order by blast + then have "to_F \ \ fst (lnth D p0)" using induct_hyp by blast + then show ?case using i_in_suc[OF suc_p_bigger_n sucsuc_smaller_d] by blast + qed + then have i_in_all_bigger_n: "\j. j \ n \ enat j < llength D \ to_F \ \ (fst (lnth D j))" + by presburger + have "llength (lmap fst D) = llength D" by force + then have "to_F \ \ \ (lnth (lmap fst D) ` {j. n \ j \ enat j < llength (lmap fst D)})" + using i_in_all_bigger_n using Suc_le_D by auto + then have "to_F \ \ Liminf_llist (lmap fst D)" + unfolding Liminf_llist_def using suc_n_length by auto + then show False using final_schedule by fast + qed + then obtain p where p_greater_n: "p \ n" and p_smaller_d: "enat (Suc p) < llength D" and + i_in_p: "to_F \ \ (fst (lnth D p))" and i_notin_suc_p: "to_F \ \ (fst (lnth D (Suc p)))" + by blast + have p_neq_n: "Suc p \ n" using i_notin_suc_p i_in_suc_n by blast + have step_p: "lnth D p \LGC lnth D (Suc p)" using deriv p_smaller_d chain_lnth_rel by blast + then have "\T1 T2 \ N2 N1 M. lnth D p = (T1, N1) \ lnth D (Suc p) = (T2, N2) \ + T1 = T2 \ {\} \ T2 \ {\} = {} \ N2 = N1 \ M \ active_subset M = {} \ + \ \ no_labels.empty_ord_lifted_calc_w_red_crit_family.Red_Inf_Q (fst ` (N1 \ M))" + proof - + have ci_or_do: "(\T1 T2 \ N2 N1 M. lnth D p = (T1, N1) \ lnth D (Suc p) = (T2, N2) \ + T1 = T2 \ {\} \ T2 \ {\} = {} \ N2 = N1 \ M \ active_subset M = {} \ + \ \ no_labels.empty_ord_lifted_calc_w_red_crit_family.Red_Inf_Q (fst ` (N1 \ M))) \ + (\T1 T2 T' N. lnth D p = (T1, N) \ lnth D (Suc p) = (T2, N) \ + T1 = T2 \ T' \ T2 \ T' = {} \ + T' \ no_labels.Non_ground.Inf_from (fst ` active_subset N) = {})" + using Lazy_Given_Clause_step.simps[of "lnth D p" "lnth D (Suc p)"] step_p i_in_p i_notin_suc_p + by fastforce + then have p_greater_n_strict: "n < Suc p" + using suc_nth_d_is p_greater_n i_in_t2 i_notin_suc_p le_eq_less_or_eq by force + have "m > 0 \ j \ {0.. (prems_of (to_F \))!j \ (fst ` (active_subset (snd (lnth D p))))" + for j + proof - + fix j + assume + m_pos: "m > 0" and + j_in: "j \ {0..)!j \ (active_subset (snd (lnth D p)))" + using all_prems_active_after[OF m_pos] p_smaller_d m_def p_greater_n p_neq_n + by (meson Suc_ile_eq atLeastLessThan_iff dual_order.strict_implies_order nth_mem + p_greater_n_strict) + then have "fst ((prems_of \)!j) \ (fst ` (active_subset (snd (lnth D p))))" + by blast + then show "(prems_of (to_F \))!j \ (fst ` (active_subset (snd (lnth D p))))" + unfolding to_F_def using j_in m_def by simp + qed + then have prems_i_active_p: "m > 0 \ + to_F \ \ no_labels.Non_ground.Inf_from (fst ` active_subset (snd (lnth D p)))" + using i_in_F unfolding no_labels.Non_ground.Inf_from_def + by (smt atLeast0LessThan in_set_conv_nth lessThan_iff m_def_F mem_Collect_eq subsetI) + have "m = 0 \ (\T1 T2 \ N2 N1 M. lnth D p = (T1, N1) \ lnth D (Suc p) = (T2, N2) \ + T1 = T2 \ {\} \ T2 \ {\} = {} \ N2 = N1 \ M \ active_subset M = {} \ + \ \ no_labels.empty_ord_lifted_calc_w_red_crit_family.Red_Inf_Q (fst ` (N1 \ M)))" + using ci_or_do premise_free_inf_always_from[of "to_F \" "fst ` active_subset _", OF i_in_F] + m_def i_in_p i_notin_suc_p m_def_F by auto + then show "(\T1 T2 \ N2 N1 M. lnth D p = (T1, N1) \ lnth D (Suc p) = (T2, N2) \ + T1 = T2 \ {\} \ T2 \ {\} = {} \ N2 = N1 \ M \ active_subset M = {} \ + \ \ no_labels.empty_ord_lifted_calc_w_red_crit_family.Red_Inf_Q (fst ` (N1 \ M)))" + using ci_or_do i_in_p i_notin_suc_p prems_i_active_p unfolding active_subset_def + by force + qed + then obtain T1p T2p N1p N2p Mp where "lnth D p = (T1p, N1p)" and + suc_p_is: "lnth D (Suc p) = (T2p, N2p)" and "T1p = T2p \ {to_F \}" and "T2p \ {to_F \} = {}" and + n2p_is: "N2p = N1p \ Mp"and "active_subset Mp = {}" and + i_in_red_inf: "to_F \ \ no_labels.empty_ord_lifted_calc_w_red_crit_family.Red_Inf_Q + (fst ` (N1p \ Mp))" + using i_in_p i_notin_suc_p by fastforce + have "to_F \ \ no_labels.lifted_calc_w_red_crit_family.Red_Inf_Q (fst ` (snd (lnth D (Suc p))))" + using i_in_red_inf suc_p_is n2p_is by fastforce + then have "\q. (\_Inf_q q (to_F \) \ None \ + the (\_Inf_q q (to_F \)) \ Red_Inf_q q (\ (\_F_q q ` (fst ` (snd (lnth D (Suc p))))))) + \ (\_Inf_q q (to_F \) = None \ + \_F_q q (concl_of (to_F \)) \ (\ (\_F_q q ` (fst ` (snd (lnth D (Suc p)))))) \ + Red_F_q q (\ (\_F_q q ` (fst ` (snd (lnth D (Suc p)))))))" + unfolding to_F_def no_labels.lifted_calc_w_red_crit_family.Red_Inf_Q_def + no_labels.Red_Inf_\_q_def no_labels.\_set_q_def + by fastforce + then have "\ \ with_labels.Red_Inf_Q (snd (lnth D (Suc p)))" + unfolding to_F_def with_labels.Red_Inf_Q_def Red_Inf_\_L_q_def \_Inf_L_q_def \_set_L_q_def + \_F_L_q_def using i_in_inf_fl by auto + then show "\ \ labeled_ord_red_crit_fam.empty_ord_lifted_calc_w_red_crit_family.inter_red_crit_calculus.Sup_Red_Inf_llist (lmap snd D)" + unfolding + labeled_ord_red_crit_fam.empty_ord_lifted_calc_w_red_crit_family.inter_red_crit_calculus.Sup_Red_Inf_llist_def + using red_inf_equiv2 suc_n_length p_smaller_d by auto + qed +qed + +(* thm:lgc-completeness *) +theorem lgc_complete: "chain (\LGC) D \ llength D > 0 \ active_subset (snd (lnth D 0)) = {} \ + non_active_subset (Liminf_llist (lmap snd D)) = {} \ + (\\ \ Inf_F. length (prems_of \) = 0 \ \ \ (fst (lnth D 0))) \ + Liminf_llist (lmap fst D) = {} \ B \ Bot_F \ no_labels.entails_\_Q (fst ` (snd (lnth D 0))) {B} \ + \i. enat i < llength D \ (\BL\ Bot_FL. BL \ (snd (lnth D i)))" +proof - + fix B + assume + deriv: "chain (\LGC) D" and + not_empty_d: "llength D > 0" and + init_state: "active_subset (snd (lnth D 0)) = {}" and + final_state: "non_active_subset (Liminf_llist (lmap snd D)) = {}" and + no_prems_init_active: "\\ \ Inf_F. length (prems_of \) = 0 \ \ \ (fst (lnth D 0))" and + final_schedule: "Liminf_llist (lmap fst D) = {}" and + b_in: "B \ Bot_F" and + bot_entailed: "no_labels.entails_\_Q (fst ` (snd (lnth D 0))) {B}" + have labeled_b_in: "(B,active) \ Bot_FL" unfolding Bot_FL_def using b_in by simp + have not_empty_d2: "\ lnull (lmap snd D)" using not_empty_d by force + have simp_snd_lmap: "lnth (lmap snd D) 0 = snd (lnth D 0)" + using lnth_lmap[of 0 D snd] not_empty_d by (simp add: zero_enat_def) + have labeled_bot_entailed: "entails_\_L_Q (snd (lnth D 0)) {(B,active)}" + using labeled_entailment_lifting bot_entailed by fastforce + have "fair (lmap snd D)" + using lgc_fair[OF deriv not_empty_d init_state final_state no_prems_init_active final_schedule] . + then have "\i \ {i. enat i < llength D}. \BL\Bot_FL. BL \ (snd (lnth D i))" + using labeled_ordered_dynamic_ref_comp labeled_b_in not_empty_d2 lgc_to_red[OF deriv] + labeled_bot_entailed entail_equiv simp_snd_lmap + unfolding dynamic_refutational_complete_calculus_def + dynamic_refutational_complete_calculus_axioms_def + by (metis (mono_tags, lifting) llength_lmap lnth_lmap mem_Collect_eq) + then show ?thesis by blast +qed + +end + +end diff --git a/thys/Saturation_Framework/ROOT b/thys/Saturation_Framework/ROOT new file mode 100644 --- /dev/null +++ b/thys/Saturation_Framework/ROOT @@ -0,0 +1,15 @@ +chapter AFP + +session "Saturation_Framework" (AFP) = Ordered_Resolution_Prover + + options [timeout=300] + sessions + Well_Quasi_Orders + theories + Consequence_Relations_and_Inference_Systems + Calculi + Lifting_to_Non_Ground_Calculi + Labeled_Lifting_to_Non_Ground_Calculi + Prover_Architectures + document_files + "root.tex" + "root.tex" diff --git a/thys/Saturation_Framework/document/auto/root.el b/thys/Saturation_Framework/document/auto/root.el new file mode 100644 --- /dev/null +++ b/thys/Saturation_Framework/document/auto/root.el @@ -0,0 +1,34 @@ +(TeX-add-style-hook + "root" + (lambda () + (TeX-add-to-alist 'LaTeX-provided-class-options + '(("article" "11pt" "a4paper"))) + (TeX-add-to-alist 'LaTeX-provided-package-options + '(("inputenc" "utf8") ("fontenc" "T1") ("stmaryrd" "only" "bigsqcap") ("babel" "english"))) + (TeX-run-style-hooks + "latex2e" + "session" + "fixltx2e" + "article" + "art11" + "isabelle" + "isabellesym" + "fullpage" + "graphicx" + "comment" + "mdframed" + "inputenc" + "fontenc" + "lmodern" + "subcaption" + "amsmath" + "amssymb" + "amsthm" + "nicefrac" + "tikz" + "stmaryrd" + "wasysym" + "babel" + "pdfsetup")) + :latex) + diff --git a/thys/Saturation_Framework/document/root.tex b/thys/Saturation_Framework/document/root.tex new file mode 100644 --- /dev/null +++ b/thys/Saturation_Framework/document/root.tex @@ -0,0 +1,90 @@ +%Some LaTeX checking: no bad pratices +%\RequirePackage[l2tabu, orthodox]{nag} +%\RequirePackage[all,error]{onlyamsmath} +\RequirePackage{fixltx2e} + +\documentclass[11pt,a4paper]{article} +\usepackage{isabelle,isabellesym} + +% further packages required for unusual symbols (see also +% isabellesym.sty), use only when needed + +% lualatex +%\usepackage{spelling} +\usepackage{fullpage} +\usepackage{graphicx} +\usepackage{comment} + + +\usepackage{mdframed} +%% Saisie en UTF-8 +\usepackage[utf8]{inputenc} +\usepackage[T1]{fontenc} +\usepackage{lmodern} +\usepackage{subcaption} + +%% Pour composer des mathématiques +\usepackage{amsmath,amssymb, amsthm} +\usepackage{nicefrac} +\usepackage{tikz} +\usetikzlibrary{decorations, arrows, shapes, automata, mindmap, trees} + %for \, \, \, \, \, \, + %\, \, \, \, \, + %\, \, \ + +%\usepackage{eurosym} + %for \ + +\usepackage[only,bigsqcap]{stmaryrd} + %for \ +\usepackage{wasysym} + +%\usepackage{eufrak} + %for \ ... \, \ ... \ (also included in amssymb) + +%\usepackage{textcomp} + %for \, \, \, \, \, + %\ + +\usepackage[english]{babel} +% this should be the last package used +\usepackage{pdfsetup} + +% urls in roman style, theory text in math-similar italics +\urlstyle{rm} +\isabellestyle{it} + +\begin{document} + + +\title{Formalization of a Comprehensive Framework for Saturation Theorem Proving in Isabelle/HOL} +\author{Sophie Tourret} +\maketitle + +\begin{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 at \url{http://matryoshka.gforge.inria.fr/pubs/satur\_report.pdf}. +The names of the Isabelle lemmas and theorems corresponding to the results in the report are indicated in the margin of the report. +\end{abstract} + + +\tableofcontents + +% sane default for proof documents +\parindent 0pt\parskip 0.5ex + +% generated text of all theories +\input{session} + +% optional bibliography +%\bibliographystyle{abbrv} +%\bibliography{root} + +\end{document} + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: t +%%% End: diff --git a/thys/Sliding_Window_Algorithm/ROOT b/thys/Sliding_Window_Algorithm/ROOT new file mode 100644 --- /dev/null +++ b/thys/Sliding_Window_Algorithm/ROOT @@ -0,0 +1,9 @@ +chapter AFP + +session "Sliding_Window_Algorithm" (AFP) = HOL + + options [timeout = 300] + theories + SWA + document_files + "root.tex" + "root.bib" diff --git a/thys/Sliding_Window_Algorithm/SWA.thy b/thys/Sliding_Window_Algorithm/SWA.thy new file mode 100644 --- /dev/null +++ b/thys/Sliding_Window_Algorithm/SWA.thy @@ -0,0 +1,884 @@ +(*<*) +theory SWA + imports Main +begin +(*>*) + +section \Sliding Window Algorithm\ + +datatype 'a tree = + Leaf +| Node (l: nat) (r: nat) (val: "'a option") (lchild: "'a tree") (rchild: "'a tree") +where + "l Leaf = 0" +| "r Leaf = 0" +| "val Leaf = None" +| "lchild Leaf = Leaf" +| "rchild Leaf = Leaf" + +lemma neq_Leaf_if_l_gt0: "0 < l t \ t \ Leaf" + by auto + +primrec discharge :: "'a tree \ 'a tree" where + "discharge Leaf = Leaf" +| "discharge (Node i j _ t u) = Node i j None t u" + +instantiation option :: (semigroup_add) semigroup_add begin + +fun plus_option :: "'a option \ 'a option \ 'a option" where + "plus_option None _ = None" +| "plus_option _ None = None" +| "plus_option (Some a) (Some b) = Some (a + b)" + +instance proof + fix a b c :: "'a option" + show "a + b + c = a + (b + c)" + by (induct a b rule: plus_option.induct; cases c) + (auto simp: algebra_simps) +qed + +end + +fun combine :: "'a :: semigroup_add tree \ 'a tree \ 'a tree" where + "combine t Leaf = t" +| "combine Leaf t = t" +| "combine t u = Node (l t) (r u) (val t + val u) (discharge t) u" + +lemma combine_non_Leaves: "\t \ Leaf; u \ Leaf\ \ combine t u = Node (l t) (r u) (val t + val u) (discharge t) u" +proof - + assume assms: "t \ Leaf" "u \ Leaf" + from assms have "combine t u = Node (l (Node (l t) (r t) (val t) (lchild t) (rchild t))) (r (Node (l u) (r u) (val u) (lchild u) (rchild u))) (val (Node (l t) (r t) (val t) (lchild t) (rchild t)) + val (Node (l u) (r u) (val u) (lchild u) (rchild u))) (discharge (Node (l t) (r t) (val t) (lchild t) (rchild t))) (Node (l u) (r u) (val u) (lchild u) (rchild u))" + by (metis (no_types) combine.simps(3) tree.exhaust_sel) + with assms show ?thesis + by simp +qed + +lemma r_combine_non_Leaves: "\t \ Leaf; u \ Leaf\ \ r (combine t u) = r u" + by (simp add: combine_non_Leaves) + +type_synonym window = "nat \ nat" + +definition window :: "'a list \ window \ bool" where + "window as = (\(l, r). 0 < l \ l \ r \ r \ length as)" + +definition windows :: "'a list \ window list \ bool" where + "windows as ws = ((\w \ set ws. window as w) \ + sorted (map fst ws) \ sorted (map snd ws))" + +function reusables :: "'a tree \ window \ 'a tree list" where + "reusables t w = (if fst w > r t then [] else if fst w = l t then [t] + else let v = lchild t; u = rchild t in if fst w \ l u then + reusables u w else u # reusables v w)" + by auto +termination + by (relation "measure (\p. size (fst p))") + (auto simp: lchild_def rchild_def split: tree.splits) + +declare reusables.simps[simp del] + +lemma reusables_Leaf[simp]: "0 < fst w \ reusables Leaf w = []" + by (simp add: reusables.simps) + +primrec well_shaped :: "'a tree \ bool" where + "well_shaped Leaf = True" +| "well_shaped (Node i j _ t u) = (i \ j \ (i = j \ t = Leaf \ u = Leaf) \ + (i < j \ t \ Leaf \ u \ Leaf \ well_shaped t \ well_shaped u \ + i = l t \ j = r u \ Suc (r t) = l u))" + +lemma l_lchild_eq_l_if_well_shaped[simp]: + "\well_shaped t; l t < r t\ \ l (lchild t) = l t" + by (induct t) auto + +lemma r_rchild_eq_r_if_well_shaped[simp]: + "\well_shaped t; l t < r t\ \ r (rchild t) = r t" + by (induct t) auto + +lemma r_lchild_eq_l_rchild_if_well_shaped: + "\well_shaped t; l t < r t\ \ r (lchild t) = l (rchild t) - 1" + by (induct t) auto + +lemma r_lchild_le_r: "well_shaped t \ r (lchild t) \ r t" +proof (induct t) + case (Node i j a t1 t2) + then show ?case + by auto + (metis Suc_eq_plus1_left order.trans le_add2 tree.exhaust_sel well_shaped.simps(2)) +qed simp + +lemma well_shaped_lchild[simp]: "well_shaped t \ well_shaped (lchild t)" + by (induct t) auto + +lemma well_shaped_rchild[simp]: "well_shaped t \ well_shaped (rchild t)" + by (induct t) auto + +definition adjacent where + "adjacent w ts = (Leaf \ set ts \ + list_all2 (\t u. l t = Suc (r u)) (butlast ts) (tl ts) \ + (ts = [] \ (l (last ts) = fst w \ r (hd ts) = snd w)))" + +lemma adjacent_Nil[simp]: "adjacent w []" + unfolding adjacent_def by simp + +lemma adjacent_Cons: "adjacent w (t # ts) = + (t \ Leaf \ r t = snd w \ (case ts of [] \ l t = fst w + | u # us \ adjacent (fst w, r u) ts \ l t = Suc (r u)))" + unfolding adjacent_def by (auto split: list.splits) + +lemma adjacent_ConsI: "\t \ Leaf; r t = snd w; + (case ts of [] \ l t = fst w + | u # us \ adjacent (fst w, r u) ts \ l t = Suc (r u))\ \ + adjacent w (t # ts)" + by (simp add: adjacent_Cons) + +lemma adjacent_singleton: "t \ Leaf \ adjacent (l t, r t) [t]" + unfolding adjacent_def by simp + +lemma append_Cons_eq_append_append: "xs @ y # ys = xs @ [y] @ ys" + by simp + +lemma list_all2_append_singletonI: "\list_all2 P xs ys; P x y\ \ list_all2 P (xs @ [x]) (ys @ [y])" + by (simp add: list_all2_appendI) + +lemma list_all2_Cons_append_singletonI: "\xs \ []; list_all2 P (x # butlast xs) ys; P (last xs) y\ \ list_all2 P (x # xs) (ys @ [y])" + using list_all2_append_singletonI by fastforce + +lemma adjacent_appendI: "\0 < fst w; fst w \ snd w; + (case us of [] \ adjacent w ts + | u # us' \ adjacent (Suc (r u), snd w) ts \ adjacent (fst w, (case ts of [] \ snd w | ts \ r u)) (u # us'))\ \ + adjacent w (ts @ us)" + unfolding adjacent_def butlast_append + by (auto simp: intro: list_all2_Cons_append_singletonI + list_all2_appendI[OF list_all2_Cons_append_singletonI, simplified] split: list.splits if_splits) + +lemma adjacent_Cons_implies_adjacent: "adjacent (a, b) (t # ts) \ adjacent (a, l t - Suc 0) ts" + by (cases ts) (simp_all add: adjacent_def) + +lemma (in semigroup_add) fold_add_add: "fold (+) xs (x + y) = fold (+) xs x + y" + by (induct xs arbitrary: x) (auto simp: add_assoc[symmetric]) + +context + fixes as :: "'a :: semigroup_add list" + and ws :: "window list" +begin + +abbreviation atomic where + "atomic i \ Node i i (Some (nth as (i - 1))) Leaf Leaf" + +definition atomics :: "nat \ nat \ 'a tree list" where + "atomics i j \ map atomic (rev [i ..< Suc j])" + +definition slide :: "'a tree \ window \ 'a tree" where + "slide t w = + (let + ts = atomics (max (fst w) (Suc (r t))) (snd w); + ts' = reusables t w + in fold combine (ts @ ts') Leaf)" + +primrec iterate :: "'a tree \ window list \ 'a list" where + "iterate t [] = []" +| "iterate t (w # xs) = (let t' = slide t w in the (val t') # iterate t' xs)" + +definition sliding_window :: "'a list" where + "sliding_window = iterate Leaf ws" + + +section \Correctness\ + +abbreviation sum where + "sum i j \ fold (+) (rev (map (nth as) [i - 1 ..< j - 1])) (nth as (j - 1))" + +primrec well_valued0 :: "'a tree \ bool" where + "well_valued0 Leaf = True" +| "well_valued0 (Node i j a t u) = (0 < i \ j \ length as \ (a \ None \ a = Some (sum i j)) \ + well_valued0 t \ well_valued0 u \ (u = Leaf \ val u \ None))" + +abbreviation well_valued :: "'a tree \ bool" where + "well_valued t \ (well_valued0 t \ (t \ Leaf \ val t \ None))" + +definition valid :: "'a tree \ bool" where + "valid t = (well_shaped t \ well_valued t)" + +lemma valid_Leaf: "valid Leaf" + unfolding valid_def by auto + +lemma add_sum: + assumes "i > 0" "j \ i" "k > j" + shows "sum i j + sum (Suc j) k = sum i k" +proof - + have *: "[i - 1 ..< k - 1] = [i - 1..< j] @ [j..< k - 1]" + using assms upt_add_eq_append[of "i - 1" "j - 1" "k - j"] + by (cases j) (auto simp: upt_conv_Cons) + then show ?thesis using assms + by (cases j) (auto simp: fold_add_add) +qed + +lemma well_valued0_rchild_if_well_valued0[simp]: "well_valued0 t \ well_valued0 (rchild t)" + by (induct t) auto + +lemma well_valued0_lchild_if_well_valued0[simp]: "well_valued0 t \ well_valued0 (lchild t)" + by (induct t) auto + +lemma valid_rchild_if_valid: "valid t \ valid (rchild t)" + by (metis tree.exhaust_sel tree.sel(9) valid_def well_shaped_rchild well_valued0.simps(2)) + +lemma val_eq_Some_sum_if_valid_neq_Leaf: "\valid t; t \ Leaf\ \ val t = Some (sum (l t) (r t))" + by (auto simp: valid_def foldr_conv_fold) + (metis One_nat_def option.distinct(1) option.inject tree.exhaust_sel well_valued0.simps(2)) + + +subsection \Correctness of the Slide Function\ + +(* fact (b) part 1 *) +lemma adjacent_atomics: "adjacent (i, j) (atomics i j)" + unfolding adjacent_def atomics_def + by (auto 0 1 simp: last_map last_rev nth_tl + map_butlast[symmetric] list_all2_conv_all_nth nth_Cons' rev_nth nth_append) + +(* fact (b) part 2 *) +lemma valid_atomics: "\t \ set (atomics i j); 0 < i; j \ length as\ \ valid t" + unfolding atomics_def + by (auto simp: valid_def) + +lemma reusables_neq_Nil_if_well_shaped_and_overlapping: + "\well_shaped t; l t \ fst w; r t \ snd w; fst w \ r t\ \ reusables t w \ []" + by (induction t w rule: reusables.induct) (simp add: reusables.simps Let_def) + +lemma reusables_lchild_neq_Nil_under_some_conditions: + "\well_shaped t; l t \ fst w; r t \ snd w; fst w \ l t; r t \ fst w; l (rchild t) > fst w\ \ + reusables (lchild t) w \ []" + using r_lchild_eq_l_rchild_if_well_shaped[of "t"] r_lchild_le_r[of t] + by (intro reusables_neq_Nil_if_well_shaped_and_overlapping) auto + +(* fact (a) part 1 *) +lemma adjacent_reusables: "\0 < fst w; well_shaped t; l t \ fst w; r t \ snd w\ \ + adjacent (fst w, r t) (reusables t w)" +proof (induction t w rule: reusables.induct) + case (1 t w) + show ?case + proof (cases "fst w > r t") + case False + with 1 show ?thesis + proof (cases "fst w = l t") + case False + then show ?thesis + proof (cases "fst w \ l (rchild t)") + case True + with 1 \fst w \ l t\ show ?thesis by (subst reusables.simps) auto + next + case False + with 1 \fst w \ l t\ \\ fst w > r t\ obtain x xs where *: "reusables (lchild t) w = x # xs" + by (cases "reusables (lchild t) w") (auto simp: reusables_lchild_neq_Nil_under_some_conditions) + with 1(2-6) \fst w \ l t\ \\ fst w > r t\ \\ l (rchild t) \ fst w\ + have "adjacent (fst w, r (lchild t)) (x # xs)" + by (simp add: adjacent_Cons r_lchild_le_r dual_order.trans) + with 1 \fst w \ l t\ \\ fst w > r t\ * show ?thesis + by (subst reusables.simps) + (auto simp add: Let_def adjacent_Cons r_lchild_eq_l_rchild_if_well_shaped) + qed + qed (auto simp: reusables.simps intro!: adjacent_singleton) + qed (auto simp: reusables.simps) +qed + +lemma valid_rchild_if_well_valued0: "\well_shaped t; well_valued0 t\ \ valid (rchild t)" + by (metis tree.exhaust_sel tree.sel(9) valid_def well_shaped_rchild well_valued0.simps(2)) + +lemma valid_reusables_under_some_conditions: + "\0 < fst w; well_valued0 t; well_shaped t; l t < fst w; r t \ snd w\ \ + \t' \ set (reusables t w). valid t'" +proof (induction t w rule: reusables.induct) + case (1 t w) + show ?case + proof (cases "fst w > r t") + case False + with 1 show ?thesis + proof (cases "fst w = l t") + next + case False + then show ?thesis + proof (cases "fst w \ l (rchild t)") + case True + with 1 \fst w \ l t\ \\ fst w > r t\ have *: "Ball (set (reusables (rchild t) w)) valid" + by (metis (no_types, lifting) ball_empty dual_order.strict_trans2 leI le_neq_implies_less list.set(1) r_rchild_eq_r_if_well_shaped reusables.simps set_ConsD valid_rchild_if_well_valued0 well_shaped_rchild well_valued0_rchild_if_well_valued0) + from 1 \fst w \ l t\ \\ fst w > r t\ True have "reusables t w = reusables (rchild t) w" + by (subst reusables.simps) + simp + with 1 * show ?thesis + by simp + next + case False + with 1 \fst w \ l t\ \\ fst w > r t\ have *: "Ball (set (reusables (lchild t) w)) valid" + by (metis dual_order.strict_trans2 l_lchild_eq_l_if_well_shaped leI order_trans r_lchild_le_r well_shaped_lchild well_valued0_lchild_if_well_valued0) + with 1 have valid_rchild: "valid (rchild t)" + by (simp add: valid_rchild_if_well_valued0) + with 1 \fst w \ l t\ \\ fst w > r t\ False have "reusables t w = rchild t # reusables (lchild t) w" + by (subst reusables.simps) presburger + with 1 \fst w \ l t\ \\ fst w > r t\ False * valid_rchild show ?thesis + by (metis set_ConsD) + qed + qed (auto simp: reusables.simps) + qed (auto simp: reusables.simps) +qed + +(* fact (a) part 2 *) +lemma valid_reusables: + assumes "0 < fst w" "valid t" "l t \ fst w" "r t \ snd w" + shows "\t' \ set (reusables t w). valid t'" +proof (cases "l t < fst w") + case True + with assms show ?thesis + using valid_def valid_reusables_under_some_conditions by blast +next + case False + with assms show ?thesis + by (simp add: reusables.simps) +qed + +lemma combine_valid_Nodes_aux: + assumes prems: "0 < l a" "a \ Leaf" "z \ Leaf" "l z = Suc (r a)" "well_shaped a" "well_shaped z" + "well_valued0 a" "val a = Some va" "well_valued0 z" "val z = Some vz" + shows "va + vz = fold (+) (rev (map ((!) as) [l a - Suc 0.. 0" by simp + moreover from prems have "r a \ l a" + by (metis tree.collapse well_shaped.simps(2)) + moreover have "r z > r a" + by (metis Suc_le_lessD prems(3) prems(4) prems(6) tree.collapse well_shaped.simps(2)) + ultimately have *: "sum (l a) (r a) + sum (Suc (r a)) (r z) = sum (l a) (r z)" + by (frule add_sum) + from prems have "va = sum (l a) (r a)" + by (metis option.discI option.inject tree.collapse well_valued0.simps(2)) + moreover from prems have "vz = sum (Suc (r a)) (r z)" + by (metis option.discI option.inject prems(2) prems(3) prems(8) prems(9) tree.collapse well_valued0.simps(2)) + moreover have "fold (+) (rev (map ((!) as) [l a - Suc 0.. a = Leaf" + by (cases a) auto + +lemma well_shaped_discharge[simp]: "well_shaped a \ well_shaped (discharge a)" + by (cases a) auto + +lemma well_valued0_discharge[simp]: "well_valued0 a \ well_valued0 (discharge a)" + by (cases a) auto + +lemma l_discharge[simp]: "l (discharge a) = l a" + by (cases a) auto + +lemma r_discharge[simp]: "r (discharge a) = r a" + by (cases a) auto + +lemma well_shaped_lr: "well_shaped a \ l a \ r a" + by (cases a) auto + +lemma well_valued0_r: "well_valued0 a \ a \ Leaf \ r a \ length as" + by (cases a) auto + +lemma valid_combine_if_valid: "\0 < l a; valid a; valid z; a \ Leaf; z \ Leaf; l z = Suc (r a)\ \ + valid (combine a z)" + by (force simp add: valid_def combine_non_Leaves combine_valid_Nodes_aux + dest: well_shaped_lr well_valued0_r) + +lemma combine_neq_Leaf_if_both_non_Leaf: "\a \ Leaf; z \ Leaf\ \ + combine a z \ Leaf" + by (simp add: combine_non_Leaves) + +(* generalized version of fact (c) *) +lemma valid_fold_combine: "\0 < fst w; ts = h # ts'; \t \ set ts. valid t; adjacent (fst w, l h - 1) ts'; + valid z; z \ Leaf; l z = (case ts' of [] \ fst w | t\<^sub>1 # ts'' \ Suc (r t\<^sub>1)); r z = snd w\ \ + valid (fold combine ts' z) \ + l (fold combine ts' z) = fst w \ r (fold combine ts' z) = snd w" +proof (induction ts' arbitrary: z ts h) + case Nil + then show ?case by simp +next + case (Cons a ts') + moreover from Cons(3-4) have "valid a" by simp + moreover from Cons(5) have "adjacent (fst w, l a - Suc 0) ts'" + unfolding adjacent_Cons by (auto split: list.splits) + moreover from Cons(2-6,8) have "valid (combine a z)" + unfolding adjacent_Cons + by (intro valid_combine_if_valid) (auto split: list.splits) + moreover from Cons(5,7) have "combine a z \ Leaf" + by (intro combine_neq_Leaf_if_both_non_Leaf) (simp_all add: adjacent_Cons) + moreover from Cons(5,7) have "l (combine a z) = (case ts' of [] \ fst w | t\<^sub>1 # ts'' \ Suc (r t\<^sub>1))" + by (auto simp add: adjacent_def combine_non_Leaves split: list.splits) + moreover from Cons(5,7,9) have "r (combine a z) = snd w" + by (subst r_combine_non_Leaves) (auto simp add: adjacent_def) + ultimately show ?case + by simp +qed + +(* fact (c) *) +lemma valid_fold_combine_Leaf: + assumes "0 < fst w" "ts = h # ts'" "\t \ set ts. valid t" "adjacent w ts" + shows "valid (fold combine ts Leaf) \ + l (fold combine ts Leaf) = fst w \ r (fold combine ts Leaf) = snd w" +proof - + from assms(2) have "fold combine ts Leaf = fold combine ts' h" + by simp + moreover have "valid (fold combine ts' h) \ + l (fold combine ts' h) = fst w \ r (fold combine ts' h) = snd w" + proof (rule valid_fold_combine) + from assms show "0 < fst w" "ts = h # ts'" "\t \ set ts. valid t" "valid h" "h \ Leaf" "r h = snd w" + "l h = (case ts' of [] \ fst w | t\<^sub>1 # ts'' \ Suc (r t\<^sub>1))" + by (simp_all add: adjacent_Cons list.case_eq_if) + from assms show "adjacent (fst w, l h - 1) ts'" + by (metis One_nat_def adjacent_Cons_implies_adjacent prod.collapse) + qed + ultimately show ?thesis by simp +qed + +lemma adjacent_atomics_nonempty_reusables: + fixes x :: "'a tree" and xs :: "'a tree list" + assumes a1: "0 < fst w" + and a2: "l t \ fst w" + and a3: "r t \ snd w" + and a4: "valid t" + and a5: "reusables t w = x # xs" + shows "adjacent (Suc (r x), snd w) (atomics (max (fst w) (Suc (r t))) (snd w))" +proof - + have f6: "\p ts. adjacent p ts = ((Leaf::'a tree) \ set ts \ list_all2 (\t ta. l t = Suc (r ta)) (butlast ts) (tl ts) \ (ts = [] \ l (last ts) = fst p \ r (hd ts) = snd p))" + using adjacent_def by blast + then have f7: "Leaf \ set (atomics (max (fst w) (Suc (r t))) (snd w)) \ list_all2 (\t ta. l t = Suc (r ta)) (butlast (atomics (max (fst w) (Suc (r t))) (snd w))) (tl (atomics (max (fst w) (Suc (r t))) (snd w))) \ (atomics (max (fst w) (Suc (r t))) (snd w) = [] \ l (last (atomics (max (fst w) (Suc (r t))) (snd w))) = fst (max (fst w) (Suc (r t)), snd w) \ r (hd (atomics (max (fst w) (Suc (r t))) (snd w))) = snd (max (fst w) (Suc (r t)), snd w))" + using adjacent_atomics by presburger + have "adjacent (fst w, r t) (reusables t w)" + using a4 a3 a2 a1 by (simp add: adjacent_reusables valid_def) + then have f8: "r x = r t" + using a5 by (simp add: adjacent_Cons) + have "max (fst w) (Suc (r t)) = Suc (r t)" + using a5 by (metis (no_types) Suc_n_not_le_n list.simps(3) max.bounded_iff max_def_raw not_le_imp_less reusables.simps) + then show ?thesis + using f8 f7 f6 by presburger +qed + +lemma adjacent_Cons_r: "adjacent (a, r t) (x # xs) \ adjacent (a, r x) (x # xs)" + by (simp add: adjacent_Cons) + +lemma adjacent_Cons_r2: + "adjacent (fst w, r t) (x # xs) \ 0 < fst w \ fst w \ snd w \ r t \ snd w \ + atomics (max (fst w) (Suc (r t))) (snd w) = [] \ + adjacent w (x # xs)" + by (metis (no_types, lifting) atomics_def adjacent_def append_is_Nil_conv diff_Suc_Suc diff_zero le_Suc_eq list.simps(3) map_is_Nil_conv max_Suc_Suc max_def_raw prod.sel(1) prod.sel(2) rev_is_Nil_conv upt.simps(2)) + +lemma adjacent_append_atomics_reusables: + "\0 < fst w; fst w \ snd w; valid t; l t \ fst w; r t \ snd w\ \ + adjacent w (atomics (max (fst w) (Suc (r t))) (snd w) @ reusables t w)" + using adjacent_atomics_nonempty_reusables[of w t] reusables_neq_Nil_if_well_shaped_and_overlapping[of t w] + adjacent_atomics[of "fst w" "snd w"] adjacent_reusables[of w t] + by (intro adjacent_appendI) (auto simp: valid_def max.absorb1 atomize_not + elim: adjacent_Cons_r adjacent_Cons_r2 split: list.splits nat.splits) + +lemma valid_append_atomics_reusables: "\0 < fst w; valid t; l t \ fst w; r t \ snd w; snd w \ length as\ \ + \t \ set (atomics (max (fst w) (Suc (r t))) (snd w) @ reusables t w). valid t" + by (auto simp only: set_append valid_reusables dest: valid_atomics split: if_splits) + +lemma append_atomics_reusables_neq_Nil: "\0 < fst w; fst w \ snd w; valid t; l t \ fst w; r t \ snd w\ \ + atomics (max (fst w) (Suc (r t))) (snd w) @ reusables t w \ []" + by (simp add: reusables_neq_Nil_if_well_shaped_and_overlapping valid_def atomics_def) + +(* lemma 1 *) +lemma valid_slide: + assumes "0 < fst w" "fst w \ snd w" "valid t" "l t \ fst w" "r t \ snd w" "snd w \ length as" + shows "valid (slide t w) \ l (slide t w) = fst w \ r (slide t w) = snd w" +proof - + from assms have non_empty: "atomics (max (fst w) (Suc (r t))) (snd w) @ reusables t w \ []" + using append_atomics_reusables_neq_Nil by blast + from assms have adjacent: "adjacent w (atomics (max (fst w) (Suc (r t))) (snd w) @ reusables t w)" + using adjacent_append_atomics_reusables by blast + from assms have valid: "\t \ set (atomics (max (fst w) (Suc (r t))) (snd w) @ reusables t w). valid t" + using valid_append_atomics_reusables by blast + have *: "slide t w = fold combine (atomics (max (fst w) (Suc (r t))) (snd w) @ reusables t w) Leaf" + by (simp add: slide_def) + from assms(1) non_empty adjacent valid show "valid (slide t w) \ l (slide t w) = fst w \ r (slide t w) = snd w" + unfolding * neq_Nil_conv using valid_fold_combine_Leaf by blast +qed + + +subsection \Correctness of the Sliding Window Algorithm\ + +lemma iterate_eq_map_sum: "\valid t; windows as xs; (case xs of [] \ True | x # xs' \ l t \ fst x \ r t \ snd x)\ \ + iterate t xs = map (\w. sum (fst w) (snd w)) xs" + by (induction xs arbitrary: t) + (auto simp: valid_slide windows_def window_def val_eq_Some_sum_if_valid_neq_Leaf neq_Leaf_if_l_gt0 split: list.split) + +(* theorem 2: functional correctness *) +theorem correctness: "windows as ws \ sliding_window = map (\w. sum (fst w) (snd w)) ws" + by (auto simp only: sliding_window_def intro!: iterate_eq_map_sum) + (auto simp: valid_def split: list.split) + +end + +(*<*) +value[code] "sliding_window [2,4,5,2 :: nat] [(1, 3), (1, 4), (2, 4)]" +value[code] "slide [2,4,5,2 :: nat] Leaf (1, 3)" +(*>*) + + +subsection \Summary of the Correctness Proof\ + +text \We closely follow Basin et al.'s proof outline~\cite{BASIN2015186}. + \begin{enumerate} + \item Lemma 1, the correctness result about the function @{term SWA.slide}, is formalized + by @{thm[source] SWA.valid_slide}. It follows from the following auxiliary facts: + \begin{itemize} + \item Fact (a) is formalized by @{thm[source] SWA.adjacent_reusables} and @{thm[source] SWA.valid_reusables}. + \item Fact (b) is formalized by @{thm[source] SWA.adjacent_atomics} and @{thm[source] SWA.valid_atomics}. + \item Fact (c) is formalized by @{thm[source] SWA.valid_fold_combine_Leaf}. + \end{itemize} + \item Theorem 2, the correctness result about the function @{term SWA.sliding_window}, is formalized + by @{thm[source] SWA.correctness}. + \end{enumerate} +\ + + +section \Alternative Slide Interface and Additional Operations\ + +subsection \Alternative Slide Interface\ + +text \ + The slide operation above takes the \emph{entire} input sequence as a parameter. This is often + impractical. We provide an alternative interface to the slide operation that takes only the + \emph{new} elements as a parameter. +\ + +abbreviation atomic' where + "atomic' as b idx \ Node b b (Some (nth as idx)) Leaf Leaf" + +abbreviation atomics' :: "'a list \ nat \ nat \ nat \ 'a tree list" where + "atomics' as i j sidx \ map (\b. atomic' as b (b - sidx)) (rev [i ..< Suc j])" + +definition slide' :: "'a :: semigroup_add list \ 'a tree \ window \ 'a tree" where +"slide' as t w = + (let + ts = atomics' as (max (fst w) (Suc (r t))) (snd w) (Suc (r t)); + ts' = reusables t w + in fold combine (ts @ ts') Leaf)" + +(* examples from paper *) +(*<*) +value[code] "slide' [2,4,5,2 :: nat] Leaf (1, 3)" +value[code] "slide' [2,4,5,2 :: nat] Leaf (1, 4)" +value[code] "slide' [2,4,5,2 :: nat] Leaf (2, 4)" +value[code] "slide' [2 :: nat] (slide' [2,4,5 :: nat] Leaf (1, 3)) (1, 4)" +value[code] "slide' [] (slide' [2 :: nat] (slide' [2,4,5 :: nat] Leaf (1, 3)) (1, 4)) (2, 4)" +value[code] "slide' [2,4,5 :: nat] Leaf (1, 3)" +value[code] "slide' [2 :: nat] (slide' [2,4,5 :: nat] Leaf (1, 3)) (2, 4)" +(*>*) + +lemma slide_eq_slide': + assumes "0 < fst w" "fst w \ snd w" "valid as t" "r t = length as" "l t \ fst w" "r t \ snd w" "snd w \ length (as @ as')" + shows "slide (as @ as') t w = slide' as' t w" +proof (cases "r t = snd w") + case True + with assms have *: "atomics' (as @ as') (max (fst w) (Suc (r t))) (snd w) 1 = []" + by simp + from True assms have "atomics' as' (max (fst w) (Suc (r t))) (snd w) (Suc (r t)) = []" + by simp + with * show ?thesis + unfolding slide_def slide'_def atomics_def by simp +next + case False + with assms have "r t < snd w" + by simp + with assms have "atomic' (as @ as') (snd w) (snd w - Suc 0) = atomic' as' (snd w) (snd w - Suc (length as))" + by (simp add: leD nth_append) + with assms have *: "\i. i \ set ([max (fst w) (Suc (length as)).. atomic' (as @ as') i (i - Suc 0) = atomic' as' i (i - Suc (length as))" + by (auto simp: nth_append) + then have "map (\i. atomic' (as @ as') i (i - Suc 0)) (rev [max (fst w) (Suc (length as))..b. atomic' as' b (b - Suc (r t))) (rev [max (fst w) (Suc (r t))..0 < i; i \ j; j \ length as\ \ sum as i j = sum (as @ as') i j" +proof - + assume assms: "0 < i" "i \ j" "j \ length as" + then have *: "rev (map ((!) as) [i - Suc 0..well_shaped t; well_valued0 as t\ \ well_valued0 (as @ as') t" +proof (induction t) + case (Node i j a t1 t2) + then show ?case + using sum_eq_sum_append + by (auto 4 0) +qed simp + +lemma valid_append: "valid as t \ valid (as @ as') t" + unfolding valid_def + by (auto intro: well_valued0_append) + +lemma valid_slide_append: "\0 < fst w; fst w \ snd w; valid as t; l t \ fst w; r t \ snd w; snd w \ length as + length as'\ \ + valid (as @ as') (slide (as @ as') t w) \ l (slide (as @ as') t w) = fst w \ r (slide (as @ as') t w) = snd w" + by (auto simp: valid_append valid_slide) + +(* correctness of alternative slide interface *) +theorem valid_slide': + assumes "0 < fst w" "fst w \ snd w" "valid as t" "length as = r t" "length as' \ snd w - r t" "l t \ fst w" "r t \ snd w" + shows "valid (as @ as') (slide' as' t w) \ l (slide' as' t w) = fst w \ r (slide' as' t w) = snd w" +proof - + from assms have "valid (as @ as') (slide (as @ as') t w) \ l (slide (as @ as') t w) = fst w \ r (slide (as @ as') t w) = snd w" + using valid_slide_append by (metis add_le_cancel_left le_add_diff_inverse) + with assms show ?thesis + using slide_eq_slide' by (metis add_le_cancel_left le_add_diff_inverse length_append) +qed + + +subsection \Updating all Values in the Tree\ + +text \ + So far, we have assumed that the sequence is fixed. However, under certain conditions, + SWA can be applied even if the sequence changes. In particular, if a function that distributes + over the associative operation is mapped onto the sequence, validity of the tree can be preserved + by mapping the same function onto the tree using @{term map_tree}. +\ + +lemma map_tree_eq_Leaf_iff: "map_tree f t = Leaf \ t = Leaf" + by simp + +lemma l_map_tree_eq_l[simp]: "l (map_tree f t) = l t" + by (cases t) + (auto split: option.splits) + +lemma r_map_tree_eq_r[simp]: "r (map_tree f t) = r t" + by (cases t) + (auto split: option.splits) + +lemma val_map_tree_neq_None: "val t \ None \ val (map_tree f t) \ None" + by (cases t) auto + +lemma well_shaped_map_tree: "well_shaped t \ well_shaped (map_tree f t)" + by (induction t) + (auto split: option.split) + +lemma fold_distr: "(\x y. f (x + y) = f x + f y) \ f (fold (+) list e) = fold (+) (map f list) (f e)" + by (induction list arbitrary: e) auto + +lemma map_rev_map_nth_eq: "\x \ set xs. x < length as \ map f (rev (map ((!) as) xs)) = rev (map ((!) (map f as)) xs)" + by (simp add: rev_map) + +lemma f_nth_eq_map_f_nth: "\as \ []; length as \ n\ \ f (as ! (n - Suc 0)) = map f as ! (n - Suc 0)" + by (cases "n = length as") auto + +lemma well_valued0_map_map_tree: + "\\x y. f (x + y) = f x + f y; well_shaped t; well_valued0 as t; r t \ length as; as \ []\ \ + well_shaped (map_tree f t) \ well_valued0 (map f as) (map_tree f t)" +proof (rule conjI[OF well_shaped_map_tree], assumption, induction t) + case (Node i j a t1 t2) + then have "map f (rev (map ((!) as) [l t1 - Suc 0.. length as" + by (cases t1) auto + ultimately show ?case using Node(3-7) + by (auto simp: fold_distr[of f] val_map_tree_neq_None + well_shaped_map_tree intro!: Node(1,2)) +qed simp + +lemma valid_map_map_tree: + assumes "\x y. f (x + y) = f x + f y" "valid as t" "r t \ length as" + shows "valid (map f as) (map_tree f t)" +proof (cases "as \ []") + case True + with assms show ?thesis + by (metis map_tree_eq_Leaf_iff val_map_tree_neq_None valid_def well_valued0_map_map_tree) +next + case False + with assms show ?thesis + by (metis le_zero_eq list.size(3) tree.exhaust_sel map_tree_eq_Leaf_iff valid_Leaf valid_def well_shaped.simps(2) well_valued0.simps(2)) +qed + +lemma valid_Nil_iff: "valid [] t \ t = Leaf" + unfolding valid_def +proof + assume "well_shaped t \ well_valued [] t" + then show "t = Leaf" + by (metis le_neq_implies_less list.size(3) not_less_zero tree.collapse well_shaped.simps(2) well_valued0.simps(2)) +qed simp + + +subsection \Updating the Rightmost Leaf of the Tree\ + +text \ + We provide a function to update the rightmost leaf of the tree. This may be used in an online + setting where the input sequence is not known in advance to update the latest observed element + using the same associative operation used in SWA. We show that validity of the tree is preserved + in this case. +\ + +fun update_rightmost :: "('a \ 'a) \ 'a tree \ 'a tree" where + "update_rightmost _ Leaf = Leaf" +| "update_rightmost f (Node i j a t u) = Node i j (map_option f a) t (update_rightmost f u)" + +lemma update_rightmost_eq_Leaf_iff: "update_rightmost f t = Leaf \ t = Leaf" + by (cases t) + (auto split: option.splits) + +lemma l_update_rightmost_eq_l[simp]: "l (update_rightmost f t) = l t" + by (cases t) + (auto split: option.splits) + +lemma r_update_rightmost_eq_r[simp]: "r (update_rightmost f t) = r t" + by (cases t) + (auto split: option.splits) + +lemma val_update_rightmost_neq_None: "val t \ None \ val (update_rightmost f t) \ None" + by (cases t) auto + +lemma well_shaped_update_rightmost: "well_shaped t \ well_shaped (update_rightmost f t)" + by (induction t) + (auto simp: update_rightmost_eq_Leaf_iff split: option.split) + +lemma sum_eq_sum_prepend: "\0 < i; i \ j; length xs < i; length ys = length xs\ \ sum (xs @ as) i j = sum (ys @ as) i j" +proof - + assume assms: "0 < i" "i \ j" "length xs < i" "length ys = length xs" + then have *: "rev (map ((!) (xs @ as)) [i - Suc 0..length xs \ l t - 1; length ys = length xs; well_shaped t; well_valued0 (xs @ as) t\ \ well_valued0 (ys @ as) t" +proof (induction t) + case (Node i j a t1 t2) + then have well_valued0_t1: "well_valued0 (ys @ as) t1" + by auto + from Node have "well_valued0 (ys @ as) t2" + proof (cases a) + case None + with Node show ?thesis + by auto + (metis One_nat_def Suc_pred diff_Suc_1 le_Suc_eq le_Suc_ex trans_le_add1 tree.exhaust_sel well_shaped.simps(2)) + next + case (Some a') + with Node show ?thesis + by auto + (metis One_nat_def diff_Suc_1 diff_le_self le_trans tree.exhaust_sel well_shaped.simps(2)) + qed + with Node well_valued0_t1 show ?case + proof - + have f1: "0 < i \ j \ length (xs @ as) \ (a = None \ a = Some (SWA.sum (xs @ as) i j)) \ well_valued0 (xs @ as) t1 \ well_valued0 (xs @ as) t2 \ (t2 = Leaf \ val t2 \ None)" + by (meson \well_valued0 (xs @ as) (Node i j a t1 t2)\ well_valued0.simps(2)) + then have f2: "j \ length (ys @ as)" + by (simp add: \length ys = length xs\) + have "a = None \ a = Some (SWA.sum (ys @ as) i j)" + using f1 by (metis Node.prems(1) Node.prems(2) Node.prems(3) One_nat_def Suc_pred le_imp_less_Suc sum_eq_sum_prepend tree.sel(2) well_shaped.simps(2)) + then show ?thesis + using f2 f1 \well_valued0 (ys @ as) t2\ well_valued0.simps(2) well_valued0_t1 by blast + qed +qed simp + +lemma valid_prepend: "\length xs \ l t - 1; length ys = length xs; valid (xs @ as) t\ \ valid (ys @ as) t" + unfolding valid_def + by (auto intro: well_valued0_prepend) + +lemma take_eq_append_take_take_drop: "m \ n \ take n xs = take m xs @ take (n-m) (drop m xs)" +proof (induction xs) + case (Cons a xs) + then show ?case + by (metis le_add_diff_inverse take_add) +qed simp + +lemma well_valued0_take_r: "\well_shaped t; well_valued0 as t\ \ well_valued0 (take (r t) as) t" +proof (induction t) + case (Node i j a t1 t2) + from Node have well_valued0_t1: "well_valued0 (take j as) t1" + proof - + from Node have "r t1 \ j" + using r_lchild_le_r by (metis tree.sel(4) tree.sel(8)) + with Node have "take j as = take (r t1) as @ take (j - r t1) (drop (r t1) as)" + using take_eq_append_take_take_drop[of "r t1" j as] by simp + with Node show ?thesis + by (auto intro!: well_valued0_append) + qed + from Node have well_valued0_t2: "well_valued0 (take j as) t2" + by auto + from Node have sum_eq: "fold (+) (rev (map ((!) as) [l t1 - Suc 0.. valid (take (r t) as) t" + unfolding valid_def + by (auto intro: well_valued0_take_r) + +lemma well_valued0_butlast: "\well_shaped t; well_valued0 as t; r t < length as\ \ well_valued0 (butlast as) t" +proof (induction t) + case (Node i j a t1 t2) + then have r_le_length: "j \ length (butlast as)" + by simp + from Node have "i > 0" + by simp + with r_le_length Node have sum_eq: "sum as i j = sum (butlast as) i j" + by (metis append_butlast_last_id le_zero_eq less_imp_le_nat list.size(3) neq_iff + sum_eq_sum_append well_shaped.simps(2)) + from Node have "r t1 < length as" + by (metis dual_order.strict_trans2 r_lchild_le_r tree.sel(8)) + with Node r_le_length show ?case + by (metis (no_types, lifting) dual_order.strict_iff_order sum_eq tree.sel(10) tree.sel(4) + well_shaped.simps(2) well_shaped_rchild well_valued0.simps(2)) +qed simp + +lemma well_valued0_append_butlast_lchild: "\well_shaped t; well_valued0 as t\ \ + well_valued0 (butlast as @ [last as + x]) (lchild t)" +proof (cases t) + case (Node i j a t1 t2) + assume assms: "well_shaped t" "well_valued0 as t" + from Node assms have "r t1 < length as" + by (fastforce dest: well_shaped_lr) + with Node assms show ?thesis + by (auto simp: well_valued0_butlast well_valued0_append) +qed simp + +lemma sum_update_rightmost: "\0 < i; i \ j; length as = j\ \ + sum as i j + x = sum (butlast as @ [last as + x]) i j" + by (cases as) + (auto simp: nth_append[abs_def] fold_add_add last_conv_nth nth_Cons' nth_butlast + intro!: arg_cong2[where f="(+)"] arg_cong[where f="\xs. fold _ xs _"]) + +lemma well_valued0_update_rightmost: "\well_shaped t; well_valued0 as t; length as = r t\ \ + well_valued0 (butlast as @ [last as + x]) (update_rightmost (\a. a + x) t)" +proof (induction t) + case Leaf + then show ?case + by (auto simp add: valid_Leaf) +next + case (Node i j a t1 t2) + moreover + from Node have well_valued0_t1: "well_valued0 (butlast as @ [last as + x]) t1" + using well_valued0_append_butlast_lchild by (metis tree.sel(8)) + moreover + from Node have well_valued0_t2: + "well_valued0 (butlast as @ [last as + x]) (update_rightmost ((\a. a + x)) t2)" + by (metis \well_valued0 (butlast as @ [last as + x]) t1\ dual_order.strict_iff_order + tree.sel(4) update_rightmost.simps(1) well_shaped.simps(2) well_valued0.simps(2)) + ultimately show ?case + using sum_update_rightmost + by (cases a) (auto simp: val_update_rightmost_neq_None) +qed + +(* correctness of update_rightmost *) +lemma valid_update_rightmost: "\valid as t; length as = r t\ \ + valid (butlast as @ [last as + x]) (update_rightmost (\a. a + x) t)" + unfolding valid_def + using well_valued0_update_rightmost + by (metis update_rightmost.simps(1) val_update_rightmost_neq_None well_shaped_update_rightmost) + +(*<*) +end +(*>*) diff --git a/thys/Sliding_Window_Algorithm/document/root.bib b/thys/Sliding_Window_Algorithm/document/root.bib new file mode 100644 --- /dev/null +++ b/thys/Sliding_Window_Algorithm/document/root.bib @@ -0,0 +1,14 @@ +@article{BASIN2015186, +title = "Greedily computing associative aggregations on sliding windows", +journal = "Information Processing Letters", +volume = "115", +number = "2", +pages = "186 - 192", +year = "2015", +issn = "0020-0190", +doi = "https://doi.org/10.1016/j.ipl.2014.09.009", +url = "http://www.sciencedirect.com/science/article/pii/S0020019014001859", +author = "David Basin and Felix Klaedtke and Eugen Z{\u{a}}linescu", +keywords = "Sliding window, Associative aggregation operator, On-line algorithms, Complexity, Optimality", +abstract = "We present an algorithm for combining the elements of subsequences of a sequence with an associative operator. The subsequences are given by a sliding window of varying size. Our algorithm is greedy and computes the result with the minimal number of operator applications." +} diff --git a/thys/Sliding_Window_Algorithm/document/root.tex b/thys/Sliding_Window_Algorithm/document/root.tex new file mode 100644 --- /dev/null +++ b/thys/Sliding_Window_Algorithm/document/root.tex @@ -0,0 +1,43 @@ +\documentclass[10pt,a4paper]{article} +\usepackage{isabelle,isabellesym} + +\usepackage{a4wide} +\usepackage[english]{babel} +\usepackage{eufrak} +\usepackage{amssymb} + +% this should be the last package used +\usepackage{pdfsetup} + +% urls in roman style, theory text in math-similar italics +\urlstyle{rm} +\isabellestyle{literal} + + +\begin{document} + +\title{Formalization of an Algorithm for\\ Greedily Computing Associative Aggregations on Sliding Windows} +\author{Lukas Heimes \and Dmitriy Traytel \and Joshua Schneider} + +\maketitle + +\begin{abstract} +Basin et al.'s sliding window algorithm (SWA)~\cite{BASIN2015186} 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. +\end{abstract} + +\tableofcontents + +% sane default for proof documents +\parindent 0pt\parskip 0.5ex + +% include generated text of all theories +\input{session} + +\bibliographystyle{abbrv} +\bibliography{root} + +\end{document} diff --git a/web/entries/Applicative_Lifting.html b/web/entries/Applicative_Lifting.html --- a/web/entries/Applicative_Lifting.html +++ b/web/entries/Applicative_Lifting.html @@ -1,211 +1,211 @@ Applicative Lifting - Archive of Formal Proofs

 

 

 

 

 

 

Applicative Lifting

 

Title: Applicative Lifting
Authors: Andreas Lochbihler and - Joshua Schneider (joshua /dot/ schneider /at/ inf /dot/ ethz /dot/ ch) + Joshua Schneider
Submission date: 2015-12-22
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.

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)
BibTeX:
@article{Applicative_Lifting-AFP,
   author  = {Andreas Lochbihler and Joshua Schneider},
   title   = {Applicative Lifting},
   journal = {Archive of Formal Proofs},
   month   = dec,
   year    = 2015,
   note    = {\url{http://isa-afp.org/entries/Applicative_Lifting.html},
             Formal proof development},
   ISSN    = {2150-914x},
 }
License: BSD License
Used by: CryptHOL, Free-Groups, Locally-Nameless-Sigma, Stern_Brocot

\ No newline at end of file diff --git a/web/entries/BNF_CC.html b/web/entries/BNF_CC.html --- a/web/entries/BNF_CC.html +++ b/web/entries/BNF_CC.html @@ -1,206 +1,206 @@ Bounded Natural Functors with Covariance and Contravariance - Archive of Formal Proofs

 

 

 

 

 

 

Bounded Natural Functors with Covariance and Contravariance

 

Title: Bounded Natural Functors with Covariance and Contravariance
Authors: Andreas Lochbihler and - Joshua Schneider (joshua /dot/ schneider /at/ inf /dot/ ethz /dot/ ch) + Joshua Schneider
Submission date: 2018-04-24
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.
BibTeX:
@article{BNF_CC-AFP,
   author  = {Andreas Lochbihler and Joshua Schneider},
   title   = {Bounded Natural Functors with Covariance and Contravariance},
   journal = {Archive of Formal Proofs},
   month   = apr,
   year    = 2018,
   note    = {\url{http://isa-afp.org/entries/BNF_CC.html},
             Formal proof development},
   ISSN    = {2150-914x},
 }
License: BSD License

\ No newline at end of file diff --git a/web/entries/Containers.html b/web/entries/Containers.html --- a/web/entries/Containers.html +++ b/web/entries/Containers.html @@ -1,240 +1,240 @@ Light-weight Containers - Archive of Formal Proofs

 

 

 

 

 

 

Light-weight Containers

 

- +
Title: Light-weight Containers
Author: Andreas Lochbihler
Contributor: René Thiemann (rene /dot/ thiemann /at/ uibk /dot/ ac /dot/ at)
Submission date: 2013-04-15
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.

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)
BibTeX:
@article{Containers-AFP,
   author  = {Andreas Lochbihler},
   title   = {Light-weight Containers},
   journal = {Archive of Formal Proofs},
   month   = apr,
   year    = 2013,
   note    = {\url{http://isa-afp.org/entries/Containers.html},
             Formal proof development},
   ISSN    = {2150-914x},
 }
License: BSD License
Depends on: Automatic_Refinement, Collections, Deriving, Finger-Trees, Regular-Sets
Used by:MFOTL_Monitor
MFODL_Monitor_Optimized, MFOTL_Monitor

\ No newline at end of file diff --git a/web/entries/Furstenberg_Topology.html b/web/entries/Furstenberg_Topology.html --- a/web/entries/Furstenberg_Topology.html +++ b/web/entries/Furstenberg_Topology.html @@ -1,191 +1,191 @@ Furstenberg's topology and his proof of the infinitude of primes - Archive of Formal Proofs

 

 

 

 

 

 

Furstenberg's topology and his proof of the infinitude of primes

 

Title: Furstenberg's topology and his proof of the infinitude of primes
Author: Manuel Eberl
Submission date: 2020-03-22
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 +

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.

BibTeX:
@article{Furstenberg_Topology-AFP,
   author  = {Manuel Eberl},
   title   = {Furstenberg's topology and his proof of the infinitude of primes},
   journal = {Archive of Formal Proofs},
   month   = mar,
   year    = 2020,
   note    = {\url{http://isa-afp.org/entries/Furstenberg_Topology.html},
             Formal proof development},
   ISSN    = {2150-914x},
 }
License: BSD License

\ No newline at end of file diff --git a/web/entries/Generic_Join.html b/web/entries/Generic_Join.html --- a/web/entries/Generic_Join.html +++ b/web/entries/Generic_Join.html @@ -1,181 +1,183 @@ Formalization of Multiway-Join Algorithms - Archive of Formal Proofs

 

 

 

 

 

 

Formalization of Multiway-Join Algorithms

 

- + + +
Title: Formalization of Multiway-Join Algorithms
Author: Thibault Dardinier
Submission date: 2019-09-16
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.
BibTeX:
@article{Generic_Join-AFP,
   author  = {Thibault Dardinier},
   title   = {Formalization of Multiway-Join Algorithms},
   journal = {Archive of Formal Proofs},
   month   = sep,
   year    = 2019,
   note    = {\url{http://isa-afp.org/entries/Generic_Join.html},
             Formal proof development},
   ISSN    = {2150-914x},
 }
License: BSD License
Depends on: MFOTL_Monitor
Used by:MFODL_Monitor_Optimized

\ No newline at end of file diff --git a/web/entries/IEEE_Floating_Point.html b/web/entries/IEEE_Floating_Point.html --- a/web/entries/IEEE_Floating_Point.html +++ b/web/entries/IEEE_Floating_Point.html @@ -1,245 +1,245 @@ A Formal Model of IEEE Floating Point Arithmetic - Archive of Formal Proofs

 

 

 

 

 

 

A Formal Model of IEEE Floating Point Arithmetic

 

- +
Title: A Formal Model of IEEE Floating Point Arithmetic
Author: Lei Yu (ly271 /at/ cam /dot/ ac /dot/ uk)
Contributors: Fabian Hellauer (hellauer /at/ in /dot/ tum /dot/ de) and Fabian Immler
Submission date: 2013-07-27
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.
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.
BibTeX:
@article{IEEE_Floating_Point-AFP,
   author  = {Lei Yu},
   title   = {A Formal Model of IEEE Floating Point Arithmetic},
   journal = {Archive of Formal Proofs},
   month   = jul,
   year    = 2013,
   note    = {\url{http://isa-afp.org/entries/IEEE_Floating_Point.html},
             Formal proof development},
   ISSN    = {2150-914x},
 }
License: BSD License
Depends on: Word_Lib
Used by:CakeML
CakeML, MFODL_Monitor_Optimized

\ No newline at end of file diff --git a/web/entries/MFODL_Monitor_Optimized.html b/web/entries/MFODL_Monitor_Optimized.html new file mode 100644 --- /dev/null +++ b/web/entries/MFODL_Monitor_Optimized.html @@ -0,0 +1,213 @@ + + + + +Formalization of an Optimized Monitoring Algorithm for Metric First-Order Dynamic Logic with Aggregations - Archive of Formal Proofs + + + + + + + + + + + + + + + + + + + + + +
+

 

+ + + +

 

+

 

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

 

+

 

+
+
+

 

+

Formalization + + of + + an + + Optimized + + Monitoring + + Algorithm + + for + + Metric + + First-Order + + Dynamic + + Logic + + with + + Aggregations + +

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Title:Formalization of an Optimized Monitoring Algorithm for Metric First-Order Dynamic Logic with Aggregations
+ Authors: + + Thibault Dardinier, + Lukas Heimes, + Martin Raszyk (martin /dot/ raszyk /at/ inf /dot/ ethz /dot/ ch), + Joshua Schneider and + Dmitriy Traytel +
Submission date:2020-04-09
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.
BibTeX: +
@article{MFODL_Monitor_Optimized-AFP,
+  author  = {Thibault Dardinier and Lukas Heimes and Martin Raszyk and Joshua Schneider and Dmitriy Traytel},
+  title   = {Formalization of an Optimized Monitoring Algorithm for Metric First-Order Dynamic Logic with Aggregations},
+  journal = {Archive of Formal Proofs},
+  month   = apr,
+  year    = 2020,
+  note    = {\url{http://isa-afp.org/entries/MFODL_Monitor_Optimized.html},
+            Formal proof development},
+  ISSN    = {2150-914x},
+}
+
License:BSD License
Depends on:Containers, Generic_Join, IEEE_Floating_Point
+ +

+ + + + + + + + + + + + + + + + + + +
+
+ + + + + + \ No newline at end of file diff --git a/web/entries/MFOTL_Monitor.html b/web/entries/MFOTL_Monitor.html --- a/web/entries/MFOTL_Monitor.html +++ b/web/entries/MFOTL_Monitor.html @@ -1,202 +1,202 @@ Formalization of a Monitoring Algorithm for Metric First-Order Temporal Logic - Archive of Formal Proofs

 

 

 

 

 

 

Formalization of a Monitoring Algorithm for Metric First-Order Temporal Logic

 

Title: Formalization of a Monitoring Algorithm for Metric First-Order Temporal Logic
Authors: - Joshua Schneider (joshua /dot/ schneider /at/ inf /dot/ ethz /dot/ ch) and + Joshua Schneider and Dmitriy Traytel
Submission date: 2019-07-04
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 forthcoming 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.
BibTeX:
@article{MFOTL_Monitor-AFP,
   author  = {Joshua Schneider and Dmitriy Traytel},
   title   = {Formalization of a Monitoring Algorithm for Metric First-Order Temporal Logic},
   journal = {Archive of Formal Proofs},
   month   = jul,
   year    = 2019,
   note    = {\url{http://isa-afp.org/entries/MFOTL_Monitor.html},
             Formal proof development},
   ISSN    = {2150-914x},
 }
License: BSD License
Depends on: Containers
Used by: Generic_Join

\ No newline at end of file diff --git a/web/entries/Monad_Normalisation.html b/web/entries/Monad_Normalisation.html --- a/web/entries/Monad_Normalisation.html +++ b/web/entries/Monad_Normalisation.html @@ -1,194 +1,194 @@ Monad normalisation - Archive of Formal Proofs

 

 

 

 

 

 

Monad normalisation

 

Title: Monad normalisation
Authors: - Joshua Schneider (joshua /dot/ schneider /at/ inf /dot/ ethz /dot/ ch), + Joshua Schneider, Manuel Eberl and Andreas Lochbihler
Submission date: 2017-05-05
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.
BibTeX:
@article{Monad_Normalisation-AFP,
   author  = {Joshua Schneider and Manuel Eberl and Andreas Lochbihler},
   title   = {Monad normalisation},
   journal = {Archive of Formal Proofs},
   month   = may,
   year    = 2017,
   note    = {\url{http://isa-afp.org/entries/Monad_Normalisation.html},
             Formal proof development},
   ISSN    = {2150-914x},
 }
License: BSD License
Used by: CryptHOL, Randomised_BSTs, Skip_Lists

\ No newline at end of file diff --git a/web/entries/Ordered_Resolution_Prover.html b/web/entries/Ordered_Resolution_Prover.html --- a/web/entries/Ordered_Resolution_Prover.html +++ b/web/entries/Ordered_Resolution_Prover.html @@ -1,203 +1,203 @@ Formalization of Bachmair and Ganzinger's Ordered Resolution Prover - Archive of Formal Proofs

 

 

 

 

 

 

Formalization of Bachmair and Ganzinger's Ordered Resolution Prover

 

- +
Title: Formalization of Bachmair and Ganzinger's Ordered Resolution Prover
Authors: Anders Schlichtkrull, Jasmin Christian Blanchette (j /dot/ c /dot/ blanchette /at/ vu /dot/ nl), Dmitriy Traytel and Uwe Waldmann (uwe /at/ mpi-inf /dot/ mpg /dot/ de)
Submission date: 2018-01-18
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.
BibTeX:
@article{Ordered_Resolution_Prover-AFP,
   author  = {Anders Schlichtkrull and Jasmin Christian Blanchette and Dmitriy Traytel and Uwe Waldmann},
   title   = {Formalization of Bachmair and Ganzinger's Ordered Resolution Prover},
   journal = {Archive of Formal Proofs},
   month   = jan,
   year    = 2018,
   note    = {\url{http://isa-afp.org/entries/Ordered_Resolution_Prover.html},
             Formal proof development},
   ISSN    = {2150-914x},
 }
License: BSD License
Depends on: Coinductive, Nested_Multisets_Ordinals
Used by:Functional_Ordered_Resolution_Prover
Functional_Ordered_Resolution_Prover, Saturation_Framework

\ No newline at end of file diff --git a/web/entries/Saturation_Framework.html b/web/entries/Saturation_Framework.html new file mode 100644 --- /dev/null +++ b/web/entries/Saturation_Framework.html @@ -0,0 +1,194 @@ + + + + +A Comprehensive Framework for Saturation Theorem Proving - Archive of Formal Proofs + + + + + + + + + + + + + + + + + + + + + +
+

 

+ + + +

 

+

 

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

 

+

 

+
+
+

 

+

A + + Comprehensive + + Framework + + for + + Saturation + + Theorem + + Proving + +

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Title:A Comprehensive Framework for Saturation Theorem Proving
+ Author: + + Sophie Tourret +
Submission date:2020-04-09
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.
BibTeX: +
@article{Saturation_Framework-AFP,
+  author  = {Sophie Tourret},
+  title   = {A Comprehensive Framework for Saturation Theorem Proving},
+  journal = {Archive of Formal Proofs},
+  month   = apr,
+  year    = 2020,
+  note    = {\url{http://isa-afp.org/entries/Saturation_Framework.html},
+            Formal proof development},
+  ISSN    = {2150-914x},
+}
+
License:BSD License
Depends on:Ordered_Resolution_Prover, Well_Quasi_Orders
+ +

+ + + + + + + + + + + + + + + + + + +
+
+ + + + + + \ No newline at end of file diff --git a/web/entries/Sliding_Window_Algorithm.html b/web/entries/Sliding_Window_Algorithm.html new file mode 100644 --- /dev/null +++ b/web/entries/Sliding_Window_Algorithm.html @@ -0,0 +1,197 @@ + + + + +Formalization of an Algorithm for Greedily Computing Associative Aggregations on Sliding Windows - Archive of Formal Proofs + + + + + + + + + + + + + + + + + + + + + +
+

 

+ + + +

 

+

 

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

 

+

 

+
+
+

 

+

Formalization + + of + + an + + Algorithm + + for + + Greedily + + Computing + + Associative + + Aggregations + + on + + Sliding + + Windows + +

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Title:Formalization of an Algorithm for Greedily Computing Associative Aggregations on Sliding Windows
+ Authors: + + Lukas Heimes, + Dmitriy Traytel and + Joshua Schneider +
Submission date:2020-04-10
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.
BibTeX: +
@article{Sliding_Window_Algorithm-AFP,
+  author  = {Lukas Heimes and Dmitriy Traytel and Joshua Schneider},
+  title   = {Formalization of an Algorithm for Greedily Computing Associative Aggregations on Sliding Windows},
+  journal = {Archive of Formal Proofs},
+  month   = apr,
+  year    = 2020,
+  note    = {\url{http://isa-afp.org/entries/Sliding_Window_Algorithm.html},
+            Formal proof development},
+  ISSN    = {2150-914x},
+}
+
License:BSD License
+ +

+ + + + + + + + + + + + + + + + + + +
+
+ + + + + + \ No newline at end of file diff --git a/web/entries/Well_Quasi_Orders.html b/web/entries/Well_Quasi_Orders.html --- a/web/entries/Well_Quasi_Orders.html +++ b/web/entries/Well_Quasi_Orders.html @@ -1,246 +1,246 @@ Well-Quasi-Orders - Archive of Formal Proofs

 

 

 

 

 

 

Well-Quasi-Orders

 

- +
Title: Well-Quasi-Orders
Author: Christian Sternagel (c /dot/ sternagel /at/ gmail /dot/ com)
Submission date: 2012-04-13
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.
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.
BibTeX:
@article{Well_Quasi_Orders-AFP,
   author  = {Christian Sternagel},
   title   = {Well-Quasi-Orders},
   journal = {Archive of Formal Proofs},
   month   = apr,
   year    = 2012,
   note    = {\url{http://isa-afp.org/entries/Well_Quasi_Orders.html},
             Formal proof development},
   ISSN    = {2150-914x},
 }
License: BSD License
Depends on: Abstract-Rewriting, Open_Induction
Used by:Decreasing-Diagrams-II, Myhill-Nerode, Polynomials
Decreasing-Diagrams-II, Myhill-Nerode, Polynomials, Saturation_Framework

\ 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,4821 +1,4851 @@ 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.

 

 

+ + + + + + + + +
2020
+ 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-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,565 +1,587 @@ 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. - 25 Mar 2020 00:00:00 +0000 + 10 Apr 2020 00:00:00 +0000 + + Formalization of an Algorithm for Greedily Computing Associative Aggregations on Sliding Windows + https://www.isa-afp.org/entries/Sliding_Window_Algorithm.html + https://www.isa-afp.org/entries/Sliding_Window_Algorithm.html + Lukas Heimes, Dmitriy Traytel, Joshua Schneider + 10 Apr 2020 00:00:00 +0000 + +Basin et al.'s <a +href="https://doi.org/10.1016/j.ipl.2014.09.009">sliding +window algorithm (SWA)</a> 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. + + + A Comprehensive Framework for Saturation Theorem Proving + https://www.isa-afp.org/entries/Saturation_Framework.html + https://www.isa-afp.org/entries/Saturation_Framework.html + Sophie Tourret + 09 Apr 2020 00:00:00 +0000 + +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 <a +href="http://matryoshka.gforge.inria.fr/pubs/satur_report.pdf">on +the Matryoshka website</a>. The names of the Isabelle lemmas and +theorems corresponding to the results in the report are indicated in +the margin of the report. + + + Formalization of an Optimized Monitoring Algorithm for Metric First-Order Dynamic Logic with Aggregations + https://www.isa-afp.org/entries/MFODL_Monitor_Optimized.html + https://www.isa-afp.org/entries/MFODL_Monitor_Optimized.html + Thibault Dardinier, Lukas Heimes, Martin Raszyk, Joshua Schneider, Dmitriy Traytel + 09 Apr 2020 00:00:00 +0000 + +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 <a +href="http://people.inf.ethz.ch/trayteld/papers/ijcar20-verimonplus/verimonplus.pdf"> +forthcoming paper at IJCAR 2020</a>, significantly extends <a +href="https://www.isa-afp.org/entries/MFOTL_Monitor.html">previous +work on a verified monitor</a> for MFOTL. Apart from the +addition of regular expressions and aggregations, we implemented <a +href="https://www.isa-afp.org/entries/Generic_Join.html">multi-way +joins</a> and a specialized sliding window algorithm to further +optimize the monitor. + Strong Eventual Consistency of the Collaborative Editing Framework WOOT https://www.isa-afp.org/entries/WOOT_Strong_Eventual_Consistency.html https://www.isa-afp.org/entries/WOOT_Strong_Eventual_Consistency.html Emin Karayel, Edgar Gonzàlez 25 Mar 2020 00:00:00 +0000 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's topology and his proof of the infinitude of primes https://www.isa-afp.org/entries/Furstenberg_Topology.html https://www.isa-afp.org/entries/Furstenberg_Topology.html Manuel Eberl 22 Mar 2020 00:00:00 +0000 <p>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.</p> -<p>Apart from this, this topology is also fairly `nice' in +<p>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.</p> An Under-Approximate Relational Logic https://www.isa-afp.org/entries/Relational-Incorrectness-Logic.html https://www.isa-afp.org/entries/Relational-Incorrectness-Logic.html Toby Murray 12 Mar 2020 00:00:00 +0000 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. Hello World https://www.isa-afp.org/entries/Hello_World.html https://www.isa-afp.org/entries/Hello_World.html Cornelius Diekmann, Lars Hupel 07 Mar 2020 00:00:00 +0000 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. Implementing the Goodstein Function in λ-Calculus https://www.isa-afp.org/entries/Goodstein_Lambda.html https://www.isa-afp.org/entries/Goodstein_Lambda.html Bertram Felgenhauer 21 Feb 2020 00:00:00 +0000 In this formalization, we develop an implementation of the Goodstein function G in plain &lambda;-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. A Generic Framework for Verified Compilers https://www.isa-afp.org/entries/VeriComp.html https://www.isa-afp.org/entries/VeriComp.html Martin Desharnais 10 Feb 2020 00:00:00 +0000 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. Arithmetic progressions and relative primes https://www.isa-afp.org/entries/Arith_Prog_Rel_Primes.html https://www.isa-afp.org/entries/Arith_Prog_Rel_Primes.html José Manuel Rodríguez Caballero 01 Feb 2020 00:00:00 +0000 This article provides a formalization of the solution obtained by the author of the Problem “ARITHMETIC PROGRESSIONS” from the <a href="https://www.ocf.berkeley.edu/~wwu/riddles/putnam.shtml"> Putnam exam problems of 2002</a>. The statement of the problem is as follows: For which integers <em>n</em> > 1 does the set of positive integers less than and relatively prime to <em>n</em> constitute an arithmetic progression? A Hierarchy of Algebras for Boolean Subsets https://www.isa-afp.org/entries/Subset_Boolean_Algebras.html https://www.isa-afp.org/entries/Subset_Boolean_Algebras.html Walter Guttmann, Bernhard Möller 31 Jan 2020 00:00:00 +0000 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. Mersenne primes and the Lucas–Lehmer test https://www.isa-afp.org/entries/Mersenne_Primes.html https://www.isa-afp.org/entries/Mersenne_Primes.html Manuel Eberl 17 Jan 2020 00:00:00 +0000 <p>This article provides formal proofs of basic properties of Mersenne numbers, i. e. numbers of the form 2<sup><em>n</em></sup> - 1, and especially of Mersenne primes.</p> <p>In particular, an efficient, verified, and executable version of the Lucas&ndash;Lehmer test is developed. This test decides primality for Mersenne numbers in time polynomial in <em>n</em>.</p> Verified Approximation Algorithms https://www.isa-afp.org/entries/Approximation_Algorithms.html https://www.isa-afp.org/entries/Approximation_Algorithms.html Robin Eßmann, Tobias Nipkow, Simon Robillard 16 Jan 2020 00:00:00 +0000 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. Closest Pair of Points Algorithms https://www.isa-afp.org/entries/Closest_Pair_Points.html https://www.isa-afp.org/entries/Closest_Pair_Points.html Martin Rau, Tobias Nipkow 13 Jan 2020 00:00:00 +0000 This entry provides two related verified divide-and-conquer algorithms solving the fundamental <em>Closest Pair of Points</em> problem in Computational Geometry. Functional correctness and the optimal running time of <em>O</em>(<em>n</em> log <em>n</em>) are proved. Executable code is generated which is empirically competitive with handwritten reference implementations. Skip Lists https://www.isa-afp.org/entries/Skip_Lists.html https://www.isa-afp.org/entries/Skip_Lists.html Max W. Haslbeck, Manuel Eberl 09 Jan 2020 00:00:00 +0000 <p> 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. </p> <p> 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. </p> Bicategories https://www.isa-afp.org/entries/Bicategory.html https://www.isa-afp.org/entries/Bicategory.html Eugene W. Stark 06 Jan 2020 00:00:00 +0000 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. The Irrationality of ζ(3) https://www.isa-afp.org/entries/Zeta_3_Irrational.html https://www.isa-afp.org/entries/Zeta_3_Irrational.html Manuel Eberl 27 Dec 2019 00:00:00 +0000 <p>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 <a href="http://people.math.sc.edu/filaseta/gradcourses/Math785/Math785Notes4.pdf">Filaseta's presentation</a> of Beukers's proof.</p> Formalizing a Seligman-Style Tableau System for Hybrid Logic https://www.isa-afp.org/entries/Hybrid_Logic.html https://www.isa-afp.org/entries/Hybrid_Logic.html Asta Halkjær From 20 Dec 2019 00:00:00 +0000 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 the cited 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 the general ones admissible. Finally, the GoTo rule is restricted using a notion of coins such that each application consumes a coin and coins are 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 coin. These restrictions are imposed to rule out some means of nontermination. The Poincaré-Bendixson Theorem https://www.isa-afp.org/entries/Poincare_Bendixson.html https://www.isa-afp.org/entries/Poincare_Bendixson.html Fabian Immler, Yong Kiam Tan 18 Dec 2019 00:00:00 +0000 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. Poincaré Disc Model https://www.isa-afp.org/entries/Poincare_Disc.html https://www.isa-afp.org/entries/Poincare_Disc.html Danijela Simić, Filip Marić, Pierre Boutry 16 Dec 2019 00:00:00 +0000 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 &#8450;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). Complex Geometry https://www.isa-afp.org/entries/Complex_Geometry.html https://www.isa-afp.org/entries/Complex_Geometry.html Filip Marić, Danijela Simić 16 Dec 2019 00:00:00 +0000 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. Gauss Sums and the Pólya–Vinogradov Inequality https://www.isa-afp.org/entries/Gauss_Sums.html https://www.isa-afp.org/entries/Gauss_Sums.html Rodrigo Raya, Manuel Eberl 10 Dec 2019 00:00:00 +0000 <p>This article provides a full formalisation of Chapter 8 of Apostol's <em><a href="https://www.springer.com/de/book/9780387901633">Introduction to Analytic Number Theory</a></em>. Subjects that are covered are:</p> <ul> <li>periodic arithmetic functions and their finite Fourier series</li> <li>(generalised) Ramanujan sums</li> <li>Gauss sums and separable characters</li> <li>induced moduli and primitive characters</li> <li>the Pólya&mdash;Vinogradov inequality</li> </ul> An Efficient Generalization of Counting Sort for Large, possibly Infinite Key Ranges https://www.isa-afp.org/entries/Generalized_Counting_Sort.html https://www.isa-afp.org/entries/Generalized_Counting_Sort.html Pasquale Noce 04 Dec 2019 00:00:00 +0000 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. Interval Arithmetic on 32-bit Words https://www.isa-afp.org/entries/Interval_Arithmetic_Word32.html https://www.isa-afp.org/entries/Interval_Arithmetic_Word32.html Brandon Bohrer 27 Nov 2019 00:00:00 +0000 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 <a href="https://www.isa-afp.org/entries/Differential_Dynamic_Logic.html">Differential_Dynamic_Logic</a> article, where a Euclidean space indexed by identifiers demands that identifiers are finitely many. Zermelo Fraenkel Set Theory in Higher-Order Logic https://www.isa-afp.org/entries/ZFC_in_HOL.html https://www.isa-afp.org/entries/ZFC_in_HOL.html Lawrence C. Paulson 24 Oct 2019 00:00:00 +0000 <p>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.</p> <p>There is a type <em>V</em> of sets and a function <em>elts :: V =&gt; V set</em> mapping a set to its elements. Classes simply have type <em>V set</em>, 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.</p> <p>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.</p> <p>The theory provides two type classes with the aim of facilitating developments that combine <em>V</em> with other Isabelle/HOL types: <em>embeddable</em>, the class of types that can be injected into <em>V</em> (including <em>V</em> itself as well as <em>V*V</em>, etc.), and <em>small</em>, the class of types that correspond to some ZF set.</p> 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) Isabelle/C https://www.isa-afp.org/entries/Isabelle_C.html https://www.isa-afp.org/entries/Isabelle_C.html Frédéric Tuong, Burkhart Wolff 22 Oct 2019 00:00:00 +0000 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. VerifyThis 2019 -- Polished Isabelle Solutions https://www.isa-afp.org/entries/VerifyThis2019.html https://www.isa-afp.org/entries/VerifyThis2019.html Peter Lammich, Simon Wimmer 16 Oct 2019 00:00:00 +0000 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. Aristotle's Assertoric Syllogistic https://www.isa-afp.org/entries/Aristotles_Assertoric_Syllogistic.html https://www.isa-afp.org/entries/Aristotles_Assertoric_Syllogistic.html Angeliki Koutsoukou-Argyraki 08 Oct 2019 00:00:00 +0000 We formalise with Isabelle/HOL some basic elements of Aristotle's assertoric syllogistic following the <a href="https://plato.stanford.edu/entries/aristotle-logic/">article from the Stanford Encyclopedia of Philosophy by Robin Smith.</a> 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. Sigma Protocols and Commitment Schemes https://www.isa-afp.org/entries/Sigma_Commit_Crypto.html https://www.isa-afp.org/entries/Sigma_Commit_Crypto.html David Butler, Andreas Lochbihler 07 Oct 2019 00:00:00 +0000 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. Clean - An Abstract Imperative Programming Language and its Theory https://www.isa-afp.org/entries/Clean.html https://www.isa-afp.org/entries/Clean.html Frédéric Tuong, Burkhart Wolff 04 Oct 2019 00:00:00 +0000 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. - - Formalization of Multiway-Join Algorithms - https://www.isa-afp.org/entries/Generic_Join.html - https://www.isa-afp.org/entries/Generic_Join.html - Thibault Dardinier - 16 Sep 2019 00:00:00 +0000 - -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, <a -href="https://doi.org/10.1145/2590989.2590991">Ngo, Ré, -and Rudra</a> 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. - - - Verification Components for Hybrid Systems - https://www.isa-afp.org/entries/Hybrid_Systems_VCs.html - https://www.isa-afp.org/entries/Hybrid_Systems_VCs.html - Jonathan Julian Huerta y Munive - 10 Sep 2019 00:00:00 +0000 - -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. - - - Fourier Series - https://www.isa-afp.org/entries/Fourier.html - https://www.isa-afp.org/entries/Fourier.html - Lawrence C Paulson - 06 Sep 2019 00:00:00 +0000 - -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 - diff --git a/web/statistics.html b/web/statistics.html --- a/web/statistics.html +++ b/web/statistics.html @@ -1,303 +1,303 @@ Archive of Formal Proofs

 

 

 

 

 

 

Statistics

 

Statistics

- - - - + + + +
Number of Articles:524
Number of Authors:344
Number of lemmas:~142,100
Lines of Code:~2,467,600
Number of Articles:527
Number of Authors:347
Number of lemmas:~143,000
Lines of Code:~2,483,100

Most used AFP articles:

NameUsed by ? articles
1. List-Index 14
2. Coinductive 12
Collections 12
Regular-Sets 12
3. Landau_Symbols 11
4. Show 10
5. Abstract-Rewriting 9
Automatic_Refinement 9
Deriving 9
6. Jordan_Normal_Form 8
Native_Word 8

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,845 +1,871 @@ Archive of Formal Proofs

 

 

 

 

 

 

Index by Topic

 

Computer Science

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   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   Distributed: DiskPaxos   GenClock   ClockSynchInst   Heard_Of   Consensus_Refined   Abortable_Linearizable_Modules   IMAP-CRDT   CRDT   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   Optimization: Simplex  

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   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   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  

Security

Semantics

System Description Languages

Logic

-

Philosophy

+

Philosophical aspects

+

General logic

+
+ Classical propositional logic: + Free-Boolean-Algebra   + Classical first-order logic: + FOL-Fitting   + Decidability of theories: + MSO_Regex_Equivalence   + Formula_Derivatives   + Presburger-Automata   + LinearQuantifierElim   + Nat-Interval-Logic   + Mechanization of proofs: + Boolean_Expression_Checkers   + Verified-Prover   + Sort_Encodings   + PropResPI   + Resolution_FOL   + FOL_Harrison   + Ordered_Resolution_Prover   + Functional_Ordered_Resolution_Prover   + Binding_Syntax_Theory   + Saturation_Framework   + Lambda calculus: + LambdaMu   + Logics of knowledge and belief: + Epistemic_Logic   + Temporal logic: + LTL   + HyperCTL   + Allen_Calculus   + MFOTL_Monitor   + Modal logic: + Modal_Logics_for_NTS   + Differential_Dynamic_Logic   + Hybrid_Multi_Lane_Spatial_Logic   + Hybrid_Logic   + MFODL_Monitor_Optimized   + Paraconsistent logics: + Paraconsistency   +
+

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

Set Theory

Misc

Tools

\ No newline at end of file