diff --git a/metadata/metadata b/metadata/metadata --- a/metadata/metadata +++ b/metadata/metadata @@ -1,12306 +1,12426 @@ [Arith_Prog_Rel_Primes] title = Arithmetic progressions and relative primes author = José Manuel Rodríguez Caballero topic = Mathematics/Number theory date = 2020-02-01 notify = jose.manuel.rodriguez.caballero@ut.ee abstract = This article provides a formalization of the solution obtained by the author of the Problem “ARITHMETIC PROGRESSIONS” from the Putnam exam problems of 2002. The statement of the problem is as follows: For which integers n > 1 does the set of positive integers less than and relatively prime to n constitute an arithmetic progression? [Banach_Steinhaus] title = Banach-Steinhaus Theorem author = Dominique Unruh , Jose Manuel Rodriguez Caballero topic = Mathematics/Analysis date = 2020-05-02 notify = jose.manuel.rodriguez.caballero@ut.ee, unruh@ut.ee abstract = We formalize in Isabelle/HOL a result due to S. Banach and H. Steinhaus known as the Banach-Steinhaus theorem or Uniform boundedness principle: a pointwise-bounded family of continuous linear operators from a Banach space to a normed space is uniformly bounded. Our approach is an adaptation to Isabelle/HOL of a proof due to A. Sokal. [Complex_Geometry] title = Complex Geometry author = Filip Marić , Danijela Simić topic = Mathematics/Geometry date = 2019-12-16 notify = danijela@matf.bg.ac.rs, filip@matf.bg.ac.rs, boutry@unistra.fr abstract = A formalization of geometry of complex numbers is presented. Fundamental objects that are investigated are the complex plane extended by a single infinite point, its objects (points, lines and circles), and groups of transformations that act on them (e.g., inversions and Möbius transformations). Most objects are defined algebraically, but correspondence with classical geometric definitions is shown. [Digit_Expansions] title = Digit Expansions -author = Jonas Bayer , Marco David , Abhik Pal , Benedikt Stock +author = Jonas Bayer <>, Marco David <>, Abhik Pal <>, Benedikt Stock <> topic = Mathematics/Number theory date = 2022-04-20 notify = jonas.bayer999@gmail.com, marco.david@hotmail.de, benedikt1999@freenet.de abstract = We formalize how a natural number can be expanded into its digits in some base and prove properties about functions that operate on digit expansions. This includes the formalization of concepts such as digit shifts and carries. For a base that is a power of 2 we formalize the binary AND, binary orthogonality and binary masking of two natural numbers. This library on digit expansions builds the basis for the formalization of the DPRM theorem. +[DPRM_Theorem] +title = Diophantine Equations and the DPRM Theorem +author = Jonas Bayer <>, Marco David <>, Benedikt Stock <>, Abhik Pal <>, Yuri Matiyasevich <>, Dierk Schleicher <> +topic = Logic/Computability, Mathematics/Number theory +date = 2022-06-06 +notify = jonas.bayer999@gmail.com, marco.david@hotmail.de, benedikt1999@freenet.de +abstract = + We present a formalization of Matiyasevich's proof of the DPRM + theorem, which states that every recursively enumerable set of natural + numbers is Diophantine. This result from 1970 yields a negative + solution to Hilbert's 10th problem over the integers. To + represent recursively enumerable sets in equations, we implement and + arithmetize register machines. We formalize a general theory of + Diophantine sets and relations to reason about them abstractly. Using + several number-theoretic lemmas, we prove that exponentiation has a + Diophantine representation. + [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 = manuel@pruvisto.org 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.

[Sophomores_Dream] title = The Sophomore's Dream author = Manuel Eberl topic = Mathematics/Analysis date = 2022-04-10 notify = manuel@pruvisto.org abstract =

This article provides a brief formalisation of the two equations known as the Sophomore's Dream, first discovered by Johann Bernoulli in 1697:

\[\int_0^1 x^{-x}\,\text{d}x = \sum_{n=1}^\infty n^{-n} \quad\text{and}\quad \int_0^1 x^x\,\text{d}x = -\sum_{n=1}^\infty (-n)^{-n}\] [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 = manuel@pruvisto.org abstract =

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

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

The entry contains a proof of both theorems.

[Name_Carrying_Type_Inference] title = Verified Metatheory and Type Inference for a Name-Carrying Simply-Typed Lambda Calculus author = Michael Rawson topic = Computer science/Programming languages/Type systems date = 2017-07-09 notify = mr644@cam.ac.uk, michaelrawson76@gmail.com abstract = I formalise a Church-style simply-typed \(\lambda\)-calculus, extended with pairs, a unit value, and projection functions, and show some metatheory of the calculus, such as the subject reduction property. Particular attention is paid to the treatment of names in the calculus. A nominal style of binding is used, but I use a manual approach over Nominal Isabelle in order to extract an executable type inference algorithm. More information can be found in my undergraduate dissertation. [Propositional_Proof_Systems] title = Propositional Proof Systems author = Julius Michaelis , Tobias Nipkow topic = Logic/Proof theory date = 2017-06-21 notify = maintainafpppt@liftm.de abstract = We formalize a range of proof systems for classical propositional logic (sequent calculus, natural deduction, Hilbert systems, resolution) and prove the most important meta-theoretic results about semantics and proofs: compactness, soundness, completeness, translations between proof systems, cut-elimination, interpolation and model existence. [Optics] title = Optics author = Simon Foster , Frank Zeyda topic = Computer science/Functional programming, Mathematics/Algebra date = 2017-05-25 notify = simon.foster@york.ac.uk abstract = Lenses provide an abstract interface for manipulating data types through spatially-separated views. They are defined abstractly in terms of two functions, get, the return a value from the source type, and put that updates the value. We mechanise the underlying theory of lenses, in terms of an algebraic hierarchy of lenses, including well-behaved and very well-behaved lenses, each lens class being characterised by a set of lens laws. We also mechanise a lens algebra in Isabelle that enables their composition and comparison, so as to allow construction of complex lenses. This is accompanied by a large library of algebraic laws. Moreover we also show how the lens classes can be applied by instantiating them with a number of Isabelle data types. extra-history = Change history: [2020-03-02]: Added partial bijective and symmetric lenses. Improved alphabet command generating additional lenses and results. Several additional lens relations, including observational equivalence. Additional theorems throughout. Adaptations for Isabelle 2020. (revision 44e2e5c)
[2021-01-27] Addition of new theorems throughout, particularly for prisms. New "chantype" command allows the definition of an algebraic datatype with generated prisms. New "dataspace" command allows the definition of a local-based state space, including lenses and prisms. Addition of various examples for the above. (revision 89cf045a)
[2021-11-15] Improvement of alphabet and chantype commands to support code generation. Addition of a tactic "rename_alpha_vars" that removes the subscript vs in proof goals. Bug fixes and improvements to alphabet command ML implementation. Additional laws for scenes. (revisions 9f8bcd71c121 and c061bf9f46f3)
[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 = manuel@pruvisto.org 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 = manuel@pruvisto.org 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 = manuel@pruvisto.org 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 = manuel@pruvisto.org 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 = manuel@pruvisto.org 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 = manuel@pruvisto.org 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.

[Hermite_Lindemann] title = The Hermite–Lindemann–Weierstraß Transcendence Theorem author = Manuel Eberl topic = Mathematics/Number theory date = 2021-03-03 notify = manuel@pruvisto.org abstract =

This article provides a formalisation of the Hermite-Lindemann-Weierstraß Theorem (also known as simply Hermite-Lindemann or Lindemann-Weierstraß). This theorem is one of the crowning achievements of 19th century number theory.

The theorem states that if $\alpha_1, \ldots, \alpha_n\in\mathbb{C}$ are algebraic numbers that are linearly independent over $\mathbb{Z}$, then $e^{\alpha_1},\ldots,e^{\alpha_n}$ are algebraically independent over $\mathbb{Q}$.

Like the previous formalisation in Coq by Bernard, I proceeded by formalising Baker's version of the theorem and proof and then deriving the original one from that. Baker's version states that for any algebraic numbers $\beta_1, \ldots, \beta_n\in\mathbb{C}$ and distinct algebraic numbers $\alpha_i, \ldots, \alpha_n\in\mathbb{C}$, we have $\beta_1 e^{\alpha_1} + \ldots + \beta_n e^{\alpha_n} = 0$ if and only if all the $\beta_i$ are zero.

This has a number of direct corollaries, e.g.:

  • $e$ and $\pi$ are transcendental
  • $e^z$, $\sin z$, $\tan z$, etc. are transcendental for algebraic $z\in\mathbb{C}\setminus\{0\}$
  • $\ln z$ is transcendental for algebraic $z\in\mathbb{C}\setminus\{0, 1\}$
[DFS_Framework] title = A Framework for Verifying Depth-First Search Algorithms author = Peter Lammich , René Neumann notify = lammich@in.tum.de date = 2016-07-05 topic = Computer science/Algorithms/Graph abstract =

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

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

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

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

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

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

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

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

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

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

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

[Posix-Lexing] title = POSIX Lexing with Derivatives of Regular Expressions author = Fahad Ausaf , Roy Dyckhoff , Christian Urban notify = christian.urban@kcl.ac.uk extra-history = Change history: [2022-06-17]: Christian Urban added a theory about the Posix definition by Okui and Suzuki.
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. Their algorithm generates POSIX values which encode the information of how a regular expression matches a string--—that is, which part of the string is matched by which part of the regular expression. In this paper 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). This holds also when optimisations are included. Finally we show that (iii) our inductive definition of a POSIX value is equivalent to an alternative definition by Okui and Suzuki which identifies POSIX values as least elements according to an ordering of values.

[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 operation on discrete distributions from finite version of the max-flow min-cut theorem (revision a7a198f5bab0)
[2020-12-19]: simpler proof of linkability for bounded unhindered bipartite webs, leading to a simpler proof for networks with bounded out-capacities (revision 93ca33f4d915)
[2021-08-13]: generalize the derivation of the characterisation for the relator of discrete probability distributions to work for the bounded and unbounded MFMC theorem (revision 3c85bb52bbe6)
[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 = manuel@pruvisto.org [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 = manuel@pruvisto.org [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 = manuel@pruvisto.org [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 = manuel@pruvisto.org [Euler_MacLaurin] title = The Euler–MacLaurin Formula author = Manuel Eberl topic = Mathematics/Analysis date = 2017-03-10 notify = manuel@pruvisto.org abstract =

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

An earlier version of this work was the subject of the author's MSc thesis, which contains natural-language explanations of some of the more interesting proofs. notify = tjm1983@gmail.com [IsaGeoCoq] title = Tarski's Parallel Postulate implies the 5th Postulate of Euclid, the Postulate of Playfair and the original Parallel Postulate of Euclid author = Roland Coghetto topic = Mathematics/Geometry license = LGPL date = 2021-01-31 notify = roland_coghetto@hotmail.com abstract =

The GeoCoq library contains a formalization of geometry using the Coq proof assistant. It contains both proofs about the foundations of geometry and high-level proofs in the same style as in high school. We port a part of the GeoCoq 2.4.0 library to Isabelle/HOL: more precisely, the files Chap02.v to Chap13_3.v, suma.v as well as the associated definitions and some useful files for the demonstration of certain parallel postulates. The synthetic approach of the demonstrations is directly inspired by those contained in GeoCoq. The names of the lemmas and theorems used are kept as far as possible as well as the definitions.

It should be noted that T.J.M. Makarios has done some proofs in Tarski's Geometry. It uses a definition that does not quite coincide with the definition used in Geocoq and here. Furthermore, corresponding definitions in the Poincaré Disc Model development are not identical to those defined in GeoCoq.

In the last part, it is formalized that, in the neutral/absolute space, the axiom of the parallels of Tarski's system implies the Playfair axiom, the 5th postulate of Euclid and Euclid's original parallel postulate. These proofs, which are not constructive, are directly inspired by Pierre Boutry, Charly Gries, Julien Narboux and Pascal Schreck.

[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 , Christian Urban topic = Computer science/Automata and formal languages date = 2010-05-12 abstract = This is a library of constructions on regular expressions and languages. It provides the operations of concatenation, Kleene star and derivative on languages. Regular expressions and their meaning are defined. An executable equivalence checker for regular expressions is verified; it does not need automata but works directly on regular expressions. By mapping regular expressions to binary relations, an automatic and complete proof method for (in)equalities of binary relations over union, concatenation and (reflexive) transitive closure is obtained.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

The development employs a formalization of many-sorted first-order logic in clausal form (clauses, structures and the basic properties of the satisfaction relation), which could be of interest as the starting point for other formalizations of first-order logic metatheory. notify = uuomul@yahoo.com [Lambda_Free_RPOs] title = Formalization of Recursive Path Orders for Lambda-Free Higher-Order Terms author = Jasmin Christian Blanchette , Uwe Waldmann , Daniel Wand date = 2016-09-23 topic = Logic/Rewriting abstract = This Isabelle/HOL formalization defines recursive path orders (RPOs) for higher-order terms without lambda-abstraction and proves many useful properties about them. The main order fully coincides with the standard RPO on first-order terms also in the presence of currying, distinguishing it from previous work. An optimized variant is formalized as well. It appears promising as the basis of a higher-order superposition calculus. notify = jasmin.blanchette@gmail.com [Lambda_Free_KBOs] title = Formalization of Knuth–Bendix Orders for Lambda-Free Higher-Order Terms author = Heiko Becker , Jasmin Christian Blanchette , Uwe Waldmann , Daniel Wand date = 2016-11-12 topic = Logic/Rewriting abstract = This Isabelle/HOL formalization defines Knuth–Bendix orders for higher-order terms without lambda-abstraction and proves many useful properties about them. The main order fully coincides with the standard transfinite KBO with subterm coefficients on first-order terms. It appears promising as the basis of a higher-order superposition calculus. notify = jasmin.blanchette@gmail.com [Lambda_Free_EPO] title = Formalization of the Embedding Path Order for Lambda-Free Higher-Order Terms author = Alexander Bentkamp topic = Logic/Rewriting date = 2018-10-19 notify = a.bentkamp@vu.nl abstract = This Isabelle/HOL formalization defines the Embedding Path Order (EPO) for higher-order terms without lambda-abstraction and proves many useful properties about it. In contrast to the lambda-free recursive path orders, it does not fully coincide with RPO on first-order terms, but it is compatible with arbitrary higher-order contexts. [Nested_Multisets_Ordinals] title = Formalization of Nested Multisets, Hereditary Multisets, and Syntactic Ordinals author = Jasmin Christian Blanchette , Mathias Fleury , Dmitriy Traytel date = 2016-11-12 topic = Logic/Rewriting abstract = This Isabelle/HOL formalization introduces a nested multiset datatype and defines Dershowitz and Manna's nested multiset order. The order is proved well founded and linear. By removing one constructor, we transform the nested multisets into hereditary multisets. These are isomorphic to the syntactic ordinals—the ordinals can be recursively expressed in Cantor normal form. Addition, subtraction, multiplication, and linear orders are provided on this type. notify = jasmin.blanchette@gmail.com [Abstract-Rewriting] title = Abstract Rewriting topic = Logic/Rewriting date = 2010-06-14 author = Christian Sternagel , René Thiemann license = LGPL abstract = We present an Isabelle formalization of abstract rewriting (see, e.g., the book by Baader and Nipkow). First, we define standard relations like joinability, meetability, conversion, etc. Then, we formalize important properties of abstract rewrite systems, e.g., confluence and strong normalization. Our main concern is on strong normalization, since this formalization is the basis of CeTA (which is mainly about strong normalization of term rewrite systems). Hence lemmas involving strong normalization constitute by far the biggest part of this theory. One of those is Newman's lemma. extra-history = Change history: [2010-09-17]: Added theories defining several (ordered) semirings related to strong normalization and giving some standard instances.
[2013-10-16]: Generalized delta-orders from rationals to Archimedean fields. notify = christian.sternagel@uibk.ac.at, rene.thiemann@uibk.ac.at [First_Order_Terms] title = First-Order Terms author = Christian Sternagel , René Thiemann topic = Logic/Rewriting, Computer science/Algorithms license = LGPL date = 2018-02-06 notify = c.sternagel@gmail.com, rene.thiemann@uibk.ac.at abstract = We formalize basic results on first-order terms, including matching and a first-order unification algorithm, as well as well-foundedness of the subsumption order. This entry is part of the Isabelle Formalization of Rewriting IsaFoR, where first-order terms are omni-present: the unification algorithm is used to certify several confluence and termination techniques, like critical-pair computation and dependency graph approximations; and the subsumption order is a crucial ingredient for completion. [Free-Groups] title = Free Groups author = Joachim Breitner date = 2010-06-24 topic = Mathematics/Algebra abstract = Free Groups are, in a sense, the most generic kind of group. They are defined over a set of generators with no additional relations in between them. They play an important role in the definition of group presentations and in other fields. This theory provides the definition of Free Group as the set of fully canceled words in the generators. The universal property is proven, as well as some isomorphisms results about Free Groups. extra-history = Change history: [2011-12-11]: Added the Ping Pong Lemma. notify = [CofGroups] title = An Example of a Cofinitary Group in Isabelle/HOL author = Bart Kastermans date = 2009-08-04 topic = Mathematics/Algebra abstract = We formalize the usual proof that the group generated by the function k -> k + 1 on the integers gives rise to a cofinitary group. notify = nipkow@in.tum.de [Finitely_Generated_Abelian_Groups] title = Finitely Generated Abelian Groups author = Joseph Thommes<>, Manuel Eberl topic = Mathematics/Algebra date = 2021-07-07 notify = joseph-thommes@gmx.de, manuel@pruvisto.org abstract = This article deals with the formalisation of some group-theoretic results including the fundamental theorem of finitely generated abelian groups characterising the structure of these groups as a uniquely determined product of cyclic groups. Both the invariant factor decomposition and the primary decomposition are covered. Additional work includes results about the direct product, the internal direct product and more group-theoretic lemmas. [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 = manuel@pruvisto.org [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 [MDP-Rewards] title = Markov Decision Processes with Rewards author = Maximilian Schäffeler , Mohammad Abdulaziz topic = Mathematics/Probability theory date = 2021-12-16 notify = schaeffm@in.tum.de, mansour@in.tum.de abstract = We present a formalization of Markov Decision Processes with rewards. In particular we first build on Hölzl's formalization of MDPs (AFP entry: Markov_Models) and extend them with rewards. We proceed with an analysis of the expected total discounted reward criterion for infinite horizon MDPs. The central result is the construction of the iteration rule for the Bellman operator. We prove the optimality equations for this operator and show the existence of an optimal stationary deterministic solution. The analysis can be used to obtain dynamic programming algorithms such as value iteration and policy iteration to solve MDPs with formal guarantees. Our formalization is based on chapters 5 and 6 in Puterman's book "Markov Decision Processes: Discrete Stochastic Dynamic Programming". [MDP-Algorithms] title = Verified Algorithms for Solving Markov Decision Processes author = Maximilian Schäffeler , Mohammad Abdulaziz topic = Mathematics/Probability theory, Computer science/Algorithms date = 2021-12-16 notify = schaeffm@in.tum.de, mansour@in.tum.de abstract = We present a formalization of algorithms for solving Markov Decision Processes (MDPs) with formal guarantees on the optimality of their solutions. In particular we build on our analysis of the Bellman operator for discounted infinite horizon MDPs. From the iterator rule on the Bellman operator we directly derive executable value iteration and policy iteration algorithms to iteratively solve finite MDPs. We also prove correct optimized versions of value iteration that use matrix splittings to improve the convergence rate. In particular, we formally verify Gauss-Seidel value iteration and modified policy iteration. The algorithms are evaluated on two standard examples from the literature, namely, inventory management and gridworld. Our formalization covers most of chapter 6 in Puterman's book "Markov Decision Processes: Discrete Stochastic Dynamic Programming". [Probabilistic_System_Zoo] title = A Zoo of Probabilistic Systems author = Johannes Hölzl , Andreas Lochbihler , Dmitriy Traytel date = 2015-05-27 topic = Computer science/Automata and formal languages abstract = Numerous models of probabilistic systems are studied in the literature. Coalgebra has been used to classify them into system types and compare their expressiveness. We formalize the resulting hierarchy of probabilistic system types by modeling the semantics of the different systems as codatatypes. This approach yields simple and concise proofs, as bisimilarity coincides with equality for codatatypes.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[Van_der_Waerden] title = Van der Waerden's Theorem author = Katharina Kreuzer , Manuel Eberl topic = Mathematics/Combinatorics date = 2021-06-22 notify = kreuzerk@in.tum.de, manuel@pruvisto.org abstract = This article formalises the proof of Van der Waerden's Theorem from Ramsey theory. Van der Waerden's Theorem states that for integers $k$ and $l$ there exists a number $N$ which guarantees that if an integer interval of length at least $N$ is coloured with $k$ colours, there will always be an arithmetic progression of length $l$ of the same colour in said interval. The proof goes along the lines of \cite{Swan}. The smallest number $N_{k,l}$ fulfilling Van der Waerden's Theorem is then called the Van der Waerden Number. Finding the Van der Waerden Number is still an open problem for most values of $k$ and $l$. [Lambert_W] title = The Lambert W Function on the Reals author = Manuel Eberl topic = Mathematics/Analysis date = 2020-04-24 notify = manuel@pruvisto.org abstract =

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

As side products, we developed division algorithms for polynomials over integral domains, as well as primality-testing and prime-factorization algorithms for integers. notify = rene.thiemann@uibk.ac.at, ayamada@trs.cm.is.nagoya-u.ac.jp [Cubic_Quartic_Equations] title = Solving Cubic and Quartic Equations author = René Thiemann topic = Mathematics/Analysis date = 2021-09-03 notify = rene.thiemann@uibk.ac.at abstract =

We formalize Cardano's formula to solve a cubic equation $$ax^3 + bx^2 + cx + d = 0,$$ as well as Ferrari's formula to solve a quartic equation. We further turn both formulas into executable algorithms based on the algebraic number implementation in the AFP. To this end we also slightly extended this library, namely by making the minimal polynomial of an algebraic number executable, and by defining and implementing $n$-th roots of complex numbers.

[Perron_Frobenius] title = Perron-Frobenius Theorem for Spectral Radius Analysis author = Jose Divasón , Ondřej Kunčar , René Thiemann , Akihisa Yamada notify = rene.thiemann@uibk.ac.at date = 2016-05-20 topic = Mathematics/Algebra abstract =

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[ROBDD] title = Algorithms for Reduced Ordered Binary Decision Diagrams author = Julius Michaelis , Maximilian Haslbeck , Peter Lammich , Lars Hupel date = 2016-04-27 topic = Computer science/Algorithms, Computer science/Data structures abstract = We present a verified and executable implementation of ROBDDs in Isabelle/HOL. Our implementation relates pointer-based computation in the Heap monad to operations on an abstract definition of boolean functions. Internally, we implemented the if-then-else combinator in a recursive fashion, following the Shannon decomposition of the argument functions. The implementation mixes and adapts known techniques and is built with efficiency in mind. notify = bdd@liftm.de, haslbecm@in.tum.de [No_FTL_observers] title = No Faster-Than-Light Observers author = Mike Stannett , István Németi date = 2016-04-28 topic = Mathematics/Physics abstract = We provide a formal proof within First Order Relativity Theory that no observer can travel faster than the speed of light. Originally reported in Stannett & Németi (2014) "Using Isabelle/HOL to verify first-order relativity theory", Journal of Automated Reasoning 52(4), pp. 361-378. notify = m.stannett@sheffield.ac.uk [Schutz_Spacetime] title = Schutz' Independent Axioms for Minkowski Spacetime author = Richard Schmoetten , Jake Palmer , Jacques Fleuriot topic = Mathematics/Physics, Mathematics/Geometry date = 2021-07-27 notify = s1311325@sms.ed.ac.uk abstract = This is a formalisation of Schutz' system of axioms for Minkowski spacetime published under the name "Independent axioms for Minkowski space-time" in 1997, as well as most of the results in the third chapter ("Temporal Order on a Path") of the above monograph. Many results are proven here that cannot be found in Schutz, either preceding the theorem they are needed for, or within their own thematic section. [Real_Power] title = Real Exponents as the Limits of Sequences of Rational Exponents author = Jacques D. Fleuriot topic = Mathematics/Analysis date = 2021-11-08 notify = jdf@ed.ac.uk abstract = In this formalisation, we construct real exponents as the limits of sequences of rational exponents. In particular, if $a \ge 1$ and $x \in \mathbb{R}$, we choose an increasing rational sequence $r_n$ such that $\lim_{n\to\infty} {r_n} = x$. Then the sequence $a^{r_n}$ is increasing and if $r$ is any rational number such that $r > x$, $a^{r_n}$ is bounded above by $a^r$. By the convergence criterion for monotone sequences, $a^{r_n}$ converges. We define $a^ x = \lim_{n\to\infty} a^{r_n}$ and show that it has the expected properties (for $a \ge 0$). This particular construction of real exponents is needed instead of the usual one using the natural logarithm and exponential functions (which already exists in Isabelle) to support our mechanical derivation of Euler's exponential series as an ``infinite polynomial". Aside from helping us avoid circular reasoning, this is, as far as we are aware, the first time real exponents are mechanised in this way within a proof assistant. [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 = manuel@pruvisto.org [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 = manuel@pruvisto.org [Median_Of_Medians_Selection] title = The Median-of-Medians Selection Algorithm author = Manuel Eberl topic = Computer science/Algorithms date = 2017-12-21 notify = manuel@pruvisto.org 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 = manuel@pruvisto.org abstract =

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[KD_Tree] title = Multidimensional Binary Search Trees author = Martin Rau<> topic = Computer science/Data structures date = 2019-05-30 notify = martin.rau@tum.de, mrtnrau@googlemail.com abstract = This entry provides a formalization of multidimensional binary trees, also known as k-d trees. It includes a balanced build algorithm as well as the nearest neighbor algorithm and the range search algorithm. It is based on the papers Multidimensional binary search trees used for associative searching and An Algorithm for Finding Best Matches in Logarithmic Expected Time. extra-history = Change history: [2020-15-04]: Change representation of k-dimensional points from 'list' to HOL-Analysis.Finite_Cartesian_Product 'vec'. Update proofs to incorporate HOL-Analysis 'dist' and 'cbox' primitives. [Closest_Pair_Points] title = Closest Pair of Points Algorithms author = Martin Rau , Tobias Nipkow topic = Computer science/Algorithms/Geometry date = 2020-01-13 notify = martin.rau@tum.de, nipkow@in.tum.de abstract = This entry provides two related verified divide-and-conquer algorithms solving the fundamental Closest Pair of Points problem in Computational Geometry. Functional correctness and the optimal running time of O(n log n) are proved. Executable code is generated which is empirically competitive with handwritten reference implementations. extra-history = Change history: [2020-14-04]: Incorporate Time_Monad of the AFP entry Root_Balanced_Tree. [Approximation_Algorithms] title = Verified Approximation Algorithms author = Robin Eßmann , Tobias Nipkow , Simon Robillard , Ujkan Sulejmani<> 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, set cover, independent set, center selection, load balancing, and bin packing. The proofs correct incompletenesses in existing proofs and improve the approximation ratio in one case. A detailed description of our work (excluding center selection) has been published in the proceedings of IJCAR 2020. extra-history = Change history: [2021-02-08]: added theory Approx_SC_Hoare (Set Cover) by Robin Eßmann
[2021-06-29]: added theory Center_Selection by Ujkan Sulejmani [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 various shapes (e.g., rectangle, circle and 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). extra-history = Change history: [2021-10-26]: resolved the roots-on-the-border problem in the rectangular case (revision 82a159e398cf). [Buchi_Complementation] title = Büchi Complementation author = Julian Brunner topic = Computer science/Automata and formal languages date = 2017-10-19 notify = brunnerj@in.tum.de abstract = This entry provides a verified implementation of rank-based Büchi Complementation. The verification is done in three steps:
  1. Definition of odd rankings and proof that an automaton rejects a word iff there exists an odd ranking for it.
  2. Definition of the complement automaton and proof that it accepts exactly those words for which there is an odd ranking.
  3. Verified implementation of the complement automaton using the Isabelle Collections Framework.
[Transition_Systems_and_Automata] title = Transition Systems and Automata author = Julian Brunner topic = Computer science/Automata and formal languages date = 2017-10-19 notify = brunnerj@in.tum.de abstract = This entry provides a very abstract theory of transition systems that can be instantiated to express various types of automata. A transition system is typically instantiated by providing a set of initial states, a predicate for enabled transitions, and a transition execution function. From this, it defines the concepts of finite and infinite paths as well as the set of reachable states, among other things. Many useful theorems, from basic path manipulation rules to coinduction and run construction rules, are proven in this abstract transition system context. The library comes with instantiations for DFAs, NFAs, and Büchi automata. [Kuratowski_Closure_Complement] title = The Kuratowski Closure-Complement Theorem author = Peter Gammie , Gianpaolo Gioiosa<> topic = Mathematics/Topology date = 2017-10-26 notify = peteg42@gmail.com abstract = We discuss a topological curiosity discovered by Kuratowski (1922): the fact that the number of distinct operators on a topological space generated by compositions of closure and complement never exceeds 14, and is exactly 14 in the case of R. In addition, we prove a theorem due to Chagrov (1982) that classifies topological spaces according to the number of such operators they support. [Hybrid_Multi_Lane_Spatial_Logic] title = Hybrid Multi-Lane Spatial Logic author = Sven Linker topic = Logic/General logic/Modal logic date = 2017-11-06 notify = s.linker@liverpool.ac.uk abstract = We present a semantic embedding of a spatio-temporal multi-modal logic, specifically defined to reason about motorway traffic, into Isabelle/HOL. The semantic model is an abstraction of a motorway, emphasising local spatial properties, and parameterised by the types of sensors deployed in the vehicles. We use the logic to define controller constraints to ensure safety, i.e., the absence of collisions on the motorway. After proving safety with a restrictive definition of sensors, we relax these assumptions and show how to amend the controller constraints to still guarantee safety. [Dirichlet_L] title = Dirichlet L-Functions and Dirichlet's Theorem author = Manuel Eberl topic = Mathematics/Number theory, Mathematics/Algebra date = 2017-12-21 notify = manuel@pruvisto.org 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 = manuel@pruvisto.org abstract =

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[1] Javier Esparza, Jan Kretínský, Salomon Sickert. One Theorem to Rule Them All: A Unified Translation of LTL into ω-Automata. LICS 2018 [LambdaAuth] title = Formalization of Generic Authenticated Data Structures author = Matthias Brun<>, Dmitriy Traytel topic = Computer science/Security, Computer science/Programming languages/Lambda calculi date = 2019-05-14 notify = traytel@inf.ethz.ch abstract = Authenticated data structures are a technique for outsourcing data storage and maintenance to an untrusted server. The server is required to produce an efficiently checkable and cryptographically secure proof that it carried out precisely the requested computation. Miller et al. introduced λ• (pronounced lambda auth)—a functional programming language with a built-in primitive authentication construct, which supports a wide range of user-specified authenticated data structures while guaranteeing certain correctness and security properties for all well-typed programs. We formalize λ• and prove its correctness and security properties. With Isabelle's help, we uncover and repair several mistakes in the informal proofs and lemma statements. Our findings are summarized in an ITP'19 paper. [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. [BenOr_Kozen_Reif] title = The BKR Decision Procedure for Univariate Real Arithmetic author = Katherine Cordwell , Yong Kiam Tan , André Platzer topic = Computer science/Algorithms/Mathematical date = 2021-04-24 notify = kcordwel@cs.cmu.edu, yongkiat@cs.cmu.edu, aplatzer@cs.cmu.edu abstract = We formalize the univariate case of Ben-Or, Kozen, and Reif's decision procedure for first-order real arithmetic (the BKR algorithm). We also formalize the univariate case of Renegar's variation of the BKR algorithm. The two formalizations differ mathematically in minor ways (that have significant impact on the multivariate case), but are quite similar in proof structure. Both rely on sign-determination (finding the set of consistent sign assignments for a set of polynomials). The method used for sign-determination is similar to Tarski's original quantifier elimination algorithm (it stores key information in a matrix equation), but with a reduction step to keep complexity low. [Complete_Non_Orders] title = Complete Non-Orders and Fixed Points author = Akihisa Yamada , Jérémy Dubut topic = Mathematics/Order date = 2019-06-27 notify = akihisayamada@nii.ac.jp, dubut@nii.ac.jp abstract = We develop an Isabelle/HOL library of order-theoretic concepts, such as various completeness conditions and fixed-point theorems. We keep our formalization as general as possible: we reprove several well-known results about complete orders, often without any properties of ordering, thus complete non-orders. In particular, we generalize the Knaster–Tarski theorem so that we ensure the existence of a quasi-fixed point of monotone maps over complete non-orders, and show that the set of quasi-fixed points is complete under a mild condition—attractivity—which is implied by either antisymmetry or transitivity. This result generalizes and strengthens a result by Stauti and Maaden. Finally, we recover Kleene’s fixed-point theorem for omega-complete non-orders, again using attractivity to prove that Kleene’s fixed points are least quasi-fixed points. [Priority_Search_Trees] title = Priority Search Trees author = Peter Lammich , Tobias Nipkow topic = Computer science/Data structures date = 2019-06-25 notify = lammich@in.tum.de abstract = We present a new, purely functional, simple and efficient data structure combining a search tree and a priority queue, which we call a priority search tree. The salient feature of priority search trees is that they offer a decrease-key operation, something that is missing from other simple, purely functional priority queue implementations. Priority search trees can be implemented on top of any search tree. This entry does the implementation for red-black trees. This entry formalizes the first part of our ITP-2019 proof pearl Purely Functional, Simple and Efficient Priority Search Trees and Applications to Prim and Dijkstra. [Prim_Dijkstra_Simple] title = Purely Functional, Simple, and Efficient Implementation of Prim and Dijkstra author = Peter Lammich , Tobias Nipkow topic = Computer science/Algorithms/Graph date = 2019-06-25 notify = lammich@in.tum.de abstract = We verify purely functional, simple and efficient implementations of Prim's and Dijkstra's algorithms. This constitutes the first verification of an executable and even efficient version of Prim's algorithm. This entry formalizes the second part of our ITP-2019 proof pearl Purely Functional, Simple and Efficient Priority Search Trees and Applications to Prim and Dijkstra. [MFOTL_Monitor] title = Formalization of a Monitoring Algorithm for Metric First-Order Temporal Logic author = Joshua Schneider , Dmitriy Traytel topic = Computer science/Algorithms, Logic/General logic/Temporal logic, Computer science/Automata and formal languages date = 2019-07-04 notify = joshua.schneider@inf.ethz.ch, traytel@inf.ethz.ch abstract = A monitor is a runtime verification tool that solves the following problem: Given a stream of time-stamped events and a policy formulated in a specification language, decide whether the policy is satisfied at every point in the stream. We verify the correctness of an executable monitor for specifications given as formulas in metric first-order temporal logic (MFOTL), an expressive extension of linear temporal logic with real-time constraints and first-order quantification. The verified monitor implements a simplified variant of the algorithm used in the efficient MonPoly monitoring tool. The formalization is presented in a RV 2019 paper, which also compares the output of the verified monitor to that of other monitoring tools on randomly generated inputs. This case study revealed several errors in the optimized but unverified tools. extra-history = Change history: [2020-08-13]: added the formalization of the abstract slicing framework and joint data slicer (revision b1639ed541b7)
[FOL_Seq_Calc1] title = A Sequent Calculus for First-Order Logic author = Asta Halkjær From contributors = Alexander Birch Jensen , Anders Schlichtkrull , Jørgen Villadsen topic = Logic/Proof theory date = 2019-07-18 notify = ahfrom@dtu.dk abstract = This work formalizes soundness and completeness of a one-sided sequent calculus for first-order logic. The completeness is shown via a translation from a complete semantic tableau calculus, the proof of which is based on the First-Order Logic According to Fitting theory. The calculi and proof techniques are taken from Ben-Ari's Mathematical Logic for Computer Science. Paper: http://ceur-ws.org/Vol-3002/paper7.pdf. [FOL_Seq_Calc2] title = A Sequent Calculus Prover for First-Order Logic with Functions author = Asta Halkjær From , Frederik Krogsdal Jacobsen topic = Logic/General logic/Classical first-order logic, Logic/Proof theory, Logic/General logic/Mechanization of proofs date = 2022-01-31 notify = ahfrom@dtu.dk, fkjac@dtu.dk abstract = We formalize an automated theorem prover for first-order logic with functions. The proof search procedure is based on sequent calculus and we verify its soundness and completeness using the Abstract Soundness and Abstract Completeness theories. Our analytic completeness proof covers both open and closed formulas. Since our deterministic prover considers only the subset of terms relevant to proving a given sequent, we do so as well when building a countermodel from a failed proof. We formally connect our prover with the proof system and semantics of the existing SeCaV system. In particular, the prover's output can be post-processed in Haskell to generate human-readable SeCaV proofs which are also machine-verifiable proof certificates. [Szpilrajn] title = Order Extension and Szpilrajn's Extension Theorem author = Peter Zeller , Lukas Stevens topic = Mathematics/Order date = 2019-07-27 notify = p_zeller@cs.uni-kl.de abstract = This entry is concerned with the principle of order extension, i.e. the extension of an order relation to a total order relation. To this end, we prove a more general version of Szpilrajn's extension theorem employing terminology from the book "Consistency, Choice, and Rationality" by Bossert and Suzumura. We also formalize theorem 2.7 of their book. extra-history = Change history: [2021-03-22]: (by Lukas Stevens) generalise Szpilrajn's extension theorem and add material from the book "Consistency, Choice, and Rationality" [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 = manuel@pruvisto.org abstract =

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

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

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

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

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

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

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

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

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

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

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

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

extra-history = Change history: [2020-02-15]: Move ConcreteCategory.thy from Bicategory to Category3 and use it systematically. Make other minor improvements throughout. (revision a51840d36867)
[2020-11-04]: Added new material on equivalence of bicategories, with associated changes. (revision 472cb2268826)
[2021-07-22]: Added new material: "concrete bicategories" and "bicategory of categories". (revision 49d3aa43c180)
[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 = edgargip@google.com, me@eminkarayel.de abstract = Commutative Replicated Data Types (CRDTs) are a promising new class of data structures for large-scale shared mutable content in applications that only require eventual consistency. The WithOut Operational Transforms (WOOT) framework is a CRDT for collaborative text editing introduced by Oster et al. (CSCW 2006) for which the eventual consistency property was verified only for a bounded model to date. We contribute a formal proof for WOOTs strong eventual consistency. [Furstenberg_Topology] title = Furstenberg's topology and his proof of the infinitude of primes author = Manuel Eberl topic = Mathematics/Number theory date = 2020-03-22 notify = manuel.eberl@tum.de abstract =

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

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

[Saturation_Framework] title = A Comprehensive Framework for Saturation Theorem Proving author = Sophie Tourret topic = Logic/General logic/Mechanization of proofs date = 2020-04-09 notify = stourret@mpi-inf.mpg.de abstract = This Isabelle/HOL formalization is the companion of the technical report “A comprehensive framework for saturation theorem proving”, itself companion of the eponym IJCAR 2020 paper, written by Uwe Waldmann, Sophie Tourret, Simon Robillard and Jasmin Blanchette. It verifies a framework for formal refutational completeness proofs of abstract provers that implement saturation calculi, such as ordered resolution or superposition, and allows to model entire prover architectures in such a way that the static refutational completeness of a calculus immediately implies the dynamic refutational completeness of a prover implementing the calculus using a variant of the given clause loop. The technical report “A comprehensive framework for saturation theorem proving” is available on the Matryoshka website. The names of the Isabelle lemmas and theorems corresponding to the results in the report are indicated in the margin of the report. [Saturation_Framework_Extensions] title = Extensions to the Comprehensive Framework for Saturation Theorem Proving author = Jasmin Blanchette , Sophie Tourret topic = Logic/General logic/Mechanization of proofs date = 2020-08-25 notify = jasmin.blanchette@gmail.com abstract = This Isabelle/HOL formalization extends the AFP entry Saturation_Framework with the following contributions:
  • an application of the framework to prove Bachmair and Ganzinger's resolution prover RP refutationally complete, which was formalized in a more ad hoc fashion by Schlichtkrull et al. in the AFP entry Ordered_Resultion_Prover;
  • generalizations of various basic concepts formalized by Schlichtkrull et al., which were needed to verify RP and could be useful to formalize other calculi, such as superposition;
  • alternative proofs of fairness (and hence saturation and ultimately refutational completeness) for the given clause procedures GC and LGC, based on invariance.
[MFODL_Monitor_Optimized] title = Formalization of an Optimized Monitoring Algorithm for Metric First-Order Dynamic Logic with Aggregations author = Thibault Dardinier<>, Lukas Heimes<>, Martin Raszyk , Joshua Schneider , Dmitriy Traytel topic = Computer science/Algorithms, Logic/General logic/Modal logic, Computer science/Automata and formal languages date = 2020-04-09 notify = martin.raszyk@inf.ethz.ch, joshua.schneider@inf.ethz.ch, traytel@inf.ethz.ch abstract = A monitor is a runtime verification tool that solves the following problem: Given a stream of time-stamped events and a policy formulated in a specification language, decide whether the policy is satisfied at every point in the stream. We verify the correctness of an executable monitor for specifications given as formulas in metric first-order dynamic logic (MFODL), which combines the features of metric first-order temporal logic (MFOTL) and metric dynamic logic. Thus, MFODL supports real-time constraints, first-order parameters, and regular expressions. Additionally, the monitor supports aggregation operations such as count and sum. This formalization, which is - described in a + 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. extra-history = Change history: [2021-10-19]: corrected a mistake in the calculation of median aggregations (reported by Nicolas Kaletsch, revision 02b14c9bf3da)
+[Package_logic] +title = Formalization of a Framework for the Sound Automation of Magic Wands +author = Thibault Dardinier +topic = Computer science/Programming languages/Logics +date = 2022-05-18 +notify = thibault.dardinier@inf.ethz.ch +abstract = + The magic wand $\mathbin{-\!\!*}$ (also called separating + implication) is a separation logic connective commonly used to specify + properties of partial data structures, for instance during iterative + traversals. A footprint of a magic wand formula + $$A \mathbin{-\!\!*} B$$ is a state that, combined with any state in + which $A$ holds, yields a state in which $B$ holds. The key + challenge of proving a magic wand (also called + packaging a wand) is to find such a footprint. + Existing package algorithms either have a high annotation overhead or + are unsound. In this entry, we formally define a framework for the + sound automation of magic wands, described in an upcoming + paper at CAV 2022, and prove that it is sound and complete. + This framework, called the package logic, + precisely characterises a wide design space of possible package + algorithms applicable to a large class of separation logics. + +[Combinable_Wands] +title = A Restricted Definition of the Magic Wand to Soundly Combine Fractions of a Wand +author = Thibault Dardinier +topic = Computer science/Programming languages/Logics +date = 2022-05-30 +notify = thibault.dardinier@inf.ethz.ch +abstract = + Many separation logics support fractional + permissions to distinguish between read and write access to + a heap location, for instance, to allow concurrent reads while + enforcing exclusive writes. The concept has been generalized to + fractional assertions. $A^p$ (where $A$ is a separation logic + assertion and $p$ a fraction between $0$ and $1$) represents a + fraction $p$ of $A$. $A^p$ holds in a state $\sigma$ iff there exists + a state $\sigma_A$ in which $A$ holds and $\sigma$ is obtained from + $\sigma_A$ by multiplying all permission amounts held by $p$. While + $A^{p + q}$ can always be split into $A^p * A^q$, recombining $A^p * + A^q$ into $A^{p+q}$ is not always sound. We say that $A$ is + combinable iff the entailment $A^p * A^q \models + A^{p+q}$ holds for any two positive fractions $p$ and $q$ such that $p + + q \le 1$. Combinable assertions are particularly useful to reason + about concurrent programs, for instance, to combine the postconditions + of parallel branches when they terminate. Unfortunately, the magic + wand assertion $A \mathbin{-\!\!*} B$, commonly used to specify properties of + partial data structures, is typically not + combinable. In this entry, we formalize a novel, restricted + definition of the magic wand, described in a paper at CAV + 22, which we call the combinable wand. + We prove some key properties of the combinable wand; in particular, a + combinable wand is combinable if its right-hand side is combinable. + [Sliding_Window_Algorithm] title = Formalization of an Algorithm for Greedily Computing Associative Aggregations on Sliding Windows author = Lukas Heimes<>, Dmitriy Traytel , Joshua Schneider<> topic = Computer science/Algorithms date = 2020-04-10 notify = heimesl@student.ethz.ch, traytel@inf.ethz.ch, joshua.schneider@inf.ethz.ch abstract = Basin et al.'s sliding window algorithm (SWA) is an algorithm for combining the elements of subsequences of a sequence with an associative operator. It is greedy and minimizes the number of operator applications. We formalize the algorithm and verify its functional correctness. We extend the algorithm with additional operations and provide an alternative interface to the slide operation that does not require the entire input sequence. [Lucas_Theorem] title = Lucas's Theorem author = Chelsea Edmonds topic = Mathematics/Number theory date = 2020-04-07 notify = cle47@cam.ac.uk abstract = This work presents a formalisation of a generating function proof for Lucas's theorem. We first outline extensions to the existing Formal Power Series (FPS) library, including an equivalence relation for coefficients modulo n, an alternate binomial theorem statement, and a formalised proof of the Freshman's dream (mod p) lemma. The second part of the work presents the formal proof of Lucas's Theorem. Working backwards, the formalisation first proves a well known corollary of the theorem which is easier to formalise, and then applies induction to prove the original theorem statement. The proof of the corollary aims to provide a good example of a formalised generating function equivalence proof using the FPS library. The final theorem statement is intended to be integrated into the formalised proof of Hilbert's 10th Problem. [ADS_Functor] title = Authenticated Data Structures As Functors author = Andreas Lochbihler , Ognjen Marić topic = Computer science/Data structures date = 2020-04-16 notify = andreas.lochbihler@digitalasset.com, mail@andreas-lochbihler.de abstract = Authenticated data structures allow several systems to convince each other that they are referring to the same data structure, even if each of them knows only a part of the data structure. Using inclusion proofs, knowledgeable systems can selectively share their knowledge with other systems and the latter can verify the authenticity of what is being shared. In this article, we show how to modularly define authenticated data structures, their inclusion proofs, and operations thereon as datatypes in Isabelle/HOL, using a shallow embedding. Modularity allows us to construct complicated trees from reusable building blocks, which we call Merkle functors. Merkle functors include sums, products, and function spaces and are closed under composition and least fixpoints. As a practical application, we model the hierarchical transactions of Canton, a practical interoperability protocol for distributed ledgers, as authenticated data structures. This is a first step towards formalizing the Canton protocol and verifying its integrity and security guarantees. [Power_Sum_Polynomials] title = Power Sum Polynomials author = Manuel Eberl topic = Mathematics/Algebra date = 2020-04-24 notify = manuel@pruvisto.org abstract =

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

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

[Formal_Puiseux_Series] title = Formal Puiseux Series author = Manuel Eberl topic = Mathematics/Algebra date = 2021-02-17 notify = manuel@pruvisto.org abstract =

Formal Puiseux series are generalisations of formal power series and formal Laurent series that also allow for fractional exponents. They have the following general form: \[\sum_{i=N}^\infty a_{i/d} X^{i/d}\] where N is an integer and d is a positive integer.

This entry defines these series including their basic algebraic properties. Furthermore, it proves the Newton–Puiseux Theorem, namely that the Puiseux series over an algebraically closed field of characteristic 0 are also algebraically closed.

[Gaussian_Integers] title = Gaussian Integers author = Manuel Eberl topic = Mathematics/Number theory date = 2020-04-24 notify = manuel@pruvisto.org abstract =

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

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

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

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

[Forcing] title = Formalization of Forcing in Isabelle/ZF author = Emmanuel Gunther , Miguel Pagano , Pedro Sánchez Terraf topic = Logic/Set theory date = 2020-05-06 notify = gunther@famaf.unc.edu.ar, pagano@famaf.unc.edu.ar, sterraf@famaf.unc.edu.ar abstract = We formalize the theory of forcing in the set theory framework of Isabelle/ZF. Under the assumption of the existence of a countable transitive model of ZFC, we construct a proper generic extension and show that the latter also satisfies ZFC. [Delta_System_Lemma] title = Cofinality and the Delta System Lemma author = Pedro Sánchez Terraf topic = Mathematics/Combinatorics, Logic/Set theory date = 2020-12-27 notify = sterraf@famaf.unc.edu.ar abstract = We formalize the basic results on cofinality of linearly ordered sets and ordinals and Šanin’s Lemma for uncountable families of finite sets. This last result is used to prove the countable chain condition for Cohen posets. We work in the set theory framework of Isabelle/ZF, using the Axiom of Choice as needed. [Transitive_Models] title = Transitive Models of Fragments of ZFC author = Emmanuel Gunther , Miguel Pagano , Pedro Sánchez Terraf , Matías Steinberg topic = Logic/Set theory date = 2022-03-03 notify = sterraf@famaf.unc.edu.ar, miguel.pagano@unc.edu.ar abstract = We extend the ZF-Constructibility library by relativizing theories of the Isabelle/ZF and Delta System Lemma sessions to a transitive class. We also relativize Paulson's work on Aleph and our former treatment of the Axiom of Dependent Choices. This work is a prerrequisite to our formalization of the independence of the Continuum Hypothesis. [Independence_CH] title = The Independence of the Continuum Hypothesis in Isabelle/ZF author = Emmanuel Gunther , Miguel Pagano , Pedro Sánchez Terraf , Matías Steinberg topic = Logic/Set theory date = 2022-03-06 notify = sterraf@famaf.unc.edu.ar, psterraf@unc.edu.ar, miguel.pagano@unc.edu.ar abstract = We redeveloped our formalization of forcing in the set theory framework of Isabelle/ZF. Under the assumption of the existence of a countable transitive model of ZFC, we construct proper generic extensions that satisfy the Continuum Hypothesis and its negation. [Recursion-Addition] title = Recursion Theorem in ZF author = Georgy Dunaev topic = Logic/Set theory date = 2020-05-11 notify = georgedunaev@gmail.com abstract = This document contains a proof of the recursion theorem. This is a mechanization of the proof of the recursion theorem from the text Introduction to Set Theory, by Karel Hrbacek and Thomas Jech. This implementation may be used as the basis for a model of Peano arithmetic in ZF. While recursion and the natural numbers are already available in Isabelle/ZF, this clean development is much easier to follow. [LTL_Normal_Form] title = An Efficient Normalisation Procedure for Linear Temporal Logic: Isabelle/HOL Formalisation author = Salomon Sickert topic = Computer science/Automata and formal languages, Logic/General logic/Temporal logic date = 2020-05-08 notify = s.sickert@tum.de abstract = In the mid 80s, Lichtenstein, Pnueli, and Zuck proved a classical theorem stating that every formula of Past LTL (the extension of LTL with past operators) is equivalent to a formula of the form $\bigwedge_{i=1}^n \mathbf{G}\mathbf{F} \varphi_i \vee \mathbf{F}\mathbf{G} \psi_i$, where $\varphi_i$ and $\psi_i$ contain only past operators. Some years later, Chang, Manna, and Pnueli built on this result to derive a similar normal form for LTL. Both normalisation procedures have a non-elementary worst-case blow-up, and follow an involved path from formulas to counter-free automata to star-free regular expressions and back to formulas. We improve on both points. We present an executable formalisation of a direct and purely syntactic normalisation procedure for LTL yielding a normal form, comparable to the one by Chang, Manna, and Pnueli, that has only a single exponential blow-up. [Matrices_for_ODEs] title = Matrices for ODEs author = Jonathan Julian Huerta y Munive topic = Mathematics/Analysis, Mathematics/Algebra date = 2020-04-19 notify = jonjulian23@gmail.com abstract = Our theories formalise various matrix properties that serve to establish existence, uniqueness and characterisation of the solution to affine systems of ordinary differential equations (ODEs). In particular, we formalise the operator and maximum norm of matrices. Then we use them to prove that square matrices form a Banach space, and in this setting, we show an instance of Picard-Lindelöf’s theorem for affine systems of ODEs. Finally, we use this formalisation to verify three simple hybrid programs. [Irrational_Series_Erdos_Straus] title = Irrationality Criteria for Series by Erdős and Straus author = Angeliki Koutsoukou-Argyraki , Wenda Li topic = Mathematics/Number theory, Mathematics/Analysis date = 2020-05-12 notify = ak2110@cam.ac.uk, wl302@cam.ac.uk, liwenda1990@hotmail.com abstract = We formalise certain irrationality criteria for infinite series of the form: \[\sum_{n=1}^\infty \frac{b_n}{\prod_{i=1}^n a_i} \] where $\{b_n\}$ is a sequence of integers and $\{a_n\}$ a sequence of positive integers with $a_n >1$ for all large n. The results are due to P. Erdős and E. G. Straus [1]. In particular, we formalise Theorem 2.1, Corollary 2.10 and Theorem 3.1. The latter is an application of Theorem 2.1 involving the prime numbers. [Knuth_Bendix_Order] title = A Formalization of Knuth–Bendix Orders author = Christian Sternagel , René Thiemann topic = Logic/Rewriting date = 2020-05-13 notify = c.sternagel@gmail.com, rene.thiemann@uibk.ac.at abstract = We define a generalized version of Knuth–Bendix orders, including subterm coefficient functions. For these orders we formalize several properties such as strong normalization, the subterm property, closure properties under substitutions and contexts, as well as ground totality. [Stateful_Protocol_Composition_and_Typing] title = Stateful Protocol Composition and Typing author = Andreas V. Hess , Sebastian Mödersheim , Achim D. Brucker topic = Computer science/Security date = 2020-04-08 notify = avhe@dtu.dk, andreasvhess@gmail.com, samo@dtu.dk, brucker@spamfence.net, andschl@dtu.dk abstract = We provide in this AFP entry several relative soundness results for security protocols. In particular, we prove typing and compositionality results for stateful protocols (i.e., protocols with mutable state that may span several sessions), and that focuses on reachability properties. Such results are useful to simplify protocol verification by reducing it to a simpler problem: Typing results give conditions under which it is safe to verify a protocol in a typed model where only "well-typed" attacks can occur whereas compositionality results allow us to verify a composed protocol by only verifying the component protocols in isolation. The conditions on the protocols under which the results hold are furthermore syntactic in nature allowing for full automation. The foundation presented here is used in another entry to provide fully automated and formalized security proofs of stateful protocols. [Automated_Stateful_Protocol_Verification] title = Automated Stateful Protocol Verification author = Andreas V. Hess , Sebastian Mödersheim , Achim D. Brucker , Anders Schlichtkrull topic = Computer science/Security, Tools date = 2020-04-08 notify = avhe@dtu.dk, andreasvhess@gmail.com, samo@dtu.dk, brucker@spamfence.net, andschl@dtu.dk abstract = In protocol verification we observe a wide spectrum from fully automated methods to interactive theorem proving with proof assistants like Isabelle/HOL. In this AFP entry, we present a fully-automated approach for verifying stateful security protocols, i.e., protocols with mutable state that may span several sessions. The approach supports reachability goals like secrecy and authentication. We also include a simple user-friendly transaction-based protocol specification language that is embedded into Isabelle. [Smith_Normal_Form] title = A verified algorithm for computing the Smith normal form of a matrix author = Jose Divasón topic = Mathematics/Algebra, Computer science/Algorithms/Mathematical date = 2020-05-23 notify = jose.divason@unirioja.es abstract = This work presents a formal proof in Isabelle/HOL of an algorithm to transform a matrix into its Smith normal form, a canonical matrix form, in a general setting: the algorithm is parameterized by operations to prove its existence over elementary divisor rings, while execution is guaranteed over Euclidean domains. We also provide a formal proof on some results about the generality of this algorithm as well as the uniqueness of the Smith normal form. Since Isabelle/HOL does not feature dependent types, the development is carried out switching conveniently between two different existing libraries: the Hermite normal form (based on HOL Analysis) and the Jordan normal form AFP entries. This permits to reuse results from both developments and it is done by means of the lifting and transfer package together with the use of local type definitions. [Nash_Williams] title = The Nash-Williams Partition Theorem author = Lawrence C. Paulson topic = Mathematics/Combinatorics date = 2020-05-16 notify = lp15@cam.ac.uk abstract = In 1965, Nash-Williams discovered a generalisation of the infinite form of Ramsey's theorem. Where the latter concerns infinite sets of n-element sets for some fixed n, the Nash-Williams theorem concerns infinite sets of finite sets (or lists) subject to a “no initial segment” condition. The present formalisation follows a monograph on Ramsey Spaces by Todorčević. [Safe_Distance] title = A Formally Verified Checker of the Safe Distance Traffic Rules for Autonomous Vehicles author = Albert Rizaldi , Fabian Immler topic = Computer science/Algorithms/Mathematical, Mathematics/Physics date = 2020-06-01 notify = albert.rizaldi@ntu.edu.sg, fimmler@andrew.cmu.edu, martin.rau@tum.de abstract = The Vienna Convention on Road Traffic defines the safe distance traffic rules informally. This could make autonomous vehicle liable for safe-distance-related accidents because there is no clear definition of how large a safe distance is. We provide a formally proven prescriptive definition of a safe distance, and checkers which can decide whether an autonomous vehicle is obeying the safe distance rule. Not only does our work apply to the domain of law, but it also serves as a specification for autonomous vehicle manufacturers and for online verification of path planners. [Relational_Paths] title = Relational Characterisations of Paths author = Walter Guttmann , Peter Höfner topic = Mathematics/Graph theory date = 2020-07-13 notify = walter.guttmann@canterbury.ac.nz, peter@hoefner-online.de abstract = Binary relations are one of the standard ways to encode, characterise and reason about graphs. Relation algebras provide equational axioms for a large fragment of the calculus of binary relations. Although relations are standard tools in many areas of mathematics and computing, researchers usually fall back to point-wise reasoning when it comes to arguments about paths in a graph. We present a purely algebraic way to specify different kinds of paths in Kleene relation algebras, which are relation algebras equipped with an operation for reflexive transitive closure. We study the relationship between paths with a designated root vertex and paths without such a vertex. Since we stay in first-order logic this development helps with mechanising proofs. To demonstrate the applicability of the algebraic framework we verify the correctness of three basic graph algorithms. [Amicable_Numbers] title = Amicable Numbers author = Angeliki Koutsoukou-Argyraki topic = Mathematics/Number theory date = 2020-08-04 notify = ak2110@cam.ac.uk abstract = This is a formalisation of Amicable Numbers, involving some relevant material including Euler's sigma function, some relevant definitions, results and examples as well as rules such as Thābit ibn Qurra's Rule, Euler's Rule, te Riele's Rule and Borho's Rule with breeders. [Ordinal_Partitions] title = Ordinal Partitions author = Lawrence C. Paulson topic = Mathematics/Combinatorics, Logic/Set theory date = 2020-08-03 notify = lp15@cam.ac.uk abstract = The theory of partition relations concerns generalisations of Ramsey's theorem. For any ordinal $\alpha$, write $\alpha \to (\alpha, m)^2$ if for each function $f$ from unordered pairs of elements of $\alpha$ into $\{0,1\}$, either there is a subset $X\subseteq \alpha$ order-isomorphic to $\alpha$ such that $f\{x,y\}=0$ for all $\{x,y\}\subseteq X$, or there is an $m$ element set $Y\subseteq \alpha$ such that $f\{x,y\}=1$ for all $\{x,y\}\subseteq Y$. (In both cases, with $\{x,y\}$ we require $x\not=y$.) In particular, the infinite Ramsey theorem can be written in this notation as $\omega \to (\omega, \omega)^2$, or if we restrict $m$ to the positive integers as above, then $\omega \to (\omega, m)^2$ for all $m$. This entry formalises Larson's proof of $\omega^\omega \to (\omega^\omega, m)^2$ along with a similar proof of a result due to Specker: $\omega^2 \to (\omega^2, m)^2$. Also proved is a necessary result by Erdős and Milner: $\omega^{1+\alpha\cdot n} \to (\omega^{1+\alpha}, 2^n)^2$. [Relational_Disjoint_Set_Forests] title = Relational Disjoint-Set Forests author = Walter Guttmann topic = Computer science/Data structures date = 2020-08-26 notify = walter.guttmann@canterbury.ac.nz abstract = We give a simple relation-algebraic semantics of read and write operations on associative arrays. The array operations seamlessly integrate with assignments in the Hoare-logic library. Using relation algebras and Kleene algebras we verify the correctness of an array-based implementation of disjoint-set forests with a naive union operation and a find operation with path compression. extra-history = Change history: [2021-06-19]: added path halving, path splitting, relational Peano structures, union by rank (revision 98c7aa03457d) [PAC_Checker] title = Practical Algebraic Calculus Checker author = Mathias Fleury , Daniela Kaufmann topic = Computer science/Algorithms date = 2020-08-31 notify = mathias.fleury@jku.at abstract = Generating and checking proof certificates is important to increase the trust in automated reasoning tools. In recent years formal verification using computer algebra became more important and is heavily used in automated circuit verification. An existing proof format which covers algebraic reasoning and allows efficient proof checking is the practical algebraic calculus (PAC). In this development, we present the verified checker Pastèque that is obtained by synthesis via the Refinement Framework. This is the formalization going with our FMCAD'20 tool presentation. [BirdKMP] title = Putting the `K' into Bird's derivation of Knuth-Morris-Pratt string matching author = Peter Gammie topic = Computer science/Functional programming date = 2020-08-25 notify = peteg42@gmail.com abstract = Richard Bird and collaborators have proposed a derivation of an intricate cyclic program that implements the Morris-Pratt string matching algorithm. Here we provide a proof of total correctness for Bird's derivation and complete it by adding Knuth's optimisation. [Extended_Finite_State_Machines] title = A Formal Model of Extended Finite State Machines author = Michael Foster , Achim D. Brucker , Ramsay G. Taylor , John Derrick topic = Computer science/Automata and formal languages date = 2020-09-07 notify = m.foster@sheffield.ac.uk, adbrucker@0x5f.org abstract = In this AFP entry, we provide a formalisation of extended finite state machines (EFSMs) where models are represented as finite sets of transitions between states. EFSMs execute traces to produce observable outputs. We also define various simulation and equality metrics for EFSMs in terms of traces and prove their strengths in relation to each other. Another key contribution is a framework of function definitions such that LTL properties can be phrased over EFSMs. Finally, we provide a simple example case study in the form of a drinks machine. [Extended_Finite_State_Machine_Inference] title = Inference of Extended Finite State Machines author = Michael Foster , Achim D. Brucker , Ramsay G. Taylor , John Derrick topic = Computer science/Automata and formal languages date = 2020-09-07 notify = m.foster@sheffield.ac.uk, adbrucker@0x5f.org abstract = In this AFP entry, we provide a formal implementation of a state-merging technique to infer extended finite state machines (EFSMs), complete with output and update functions, from black-box traces. In particular, we define the subsumption in context relation as a means of determining whether one transition is able to account for the behaviour of another. Building on this, we define the direct subsumption relation, which lifts the subsumption in context relation to EFSM level such that we can use it to determine whether it is safe to merge a given pair of transitions. Key proofs include the conditions necessary for subsumption to occur and that subsumption and direct subsumption are preorder relations. We also provide a number of different heuristics which can be used to abstract away concrete values into registers so that more states and transitions can be merged and provide proofs of the various conditions which must hold for these abstractions to subsume their ungeneralised counterparts. A Code Generator setup to create executable Scala code is also defined. [Physical_Quantities] title = A Sound Type System for Physical Quantities, Units, and Measurements author = Simon Foster , Burkhart Wolff topic = Mathematics/Physics, Computer science/Programming languages/Type systems date = 2020-10-20 notify = simon.foster@york.ac.uk, wolff@lri.fr abstract = The present Isabelle theory builds a formal model for both the International System of Quantities (ISQ) and the International System of Units (SI), which are both fundamental for physics and engineering. Both the ISQ and the SI are deeply integrated into Isabelle's type system. Quantities are parameterised by dimension types, which correspond to base vectors, and thus only quantities of the same dimension can be equated. Since the underlying "algebra of quantities" induces congruences on quantity and SI types, specific tactic support is developed to capture these. Our construction is validated by a test-set of known equivalences between both quantities and SI units. Moreover, the presented theory can be used for type-safe conversions between the SI system and others, like the British Imperial System (BIS). [Shadow_DOM] title = A Formal Model of the Document Object Model with Shadow Roots author = Achim D. Brucker , Michael Herzberg topic = Computer science/Data structures date = 2020-09-28 notify = adbrucker@0x5f.org, mail@michael-herzberg.de abstract = In this AFP entry, we extend our formalization of the core DOM with Shadow Roots. Shadow roots are a recent proposal of the web community to support a component-based development approach for client-side web applications. Shadow roots are a significant extension to the DOM standard and, as web standards are condemned to be backward compatible, such extensions often result in complex specification that may contain unwanted subtleties that can be detected by a formalization. Our Isabelle/HOL formalization is, in the sense of object-orientation, an extension of our formalization of the core DOM and enjoys the same basic properties, i.e., it is extensible, i.e., can be extended without the need of re-proving already proven properties and executable, i.e., we can generate executable code from our specification. We exploit the executability to show that our formalization complies to the official standard of the W3C, respectively, the WHATWG. [DOM_Components] title = A Formalization of Web Components author = Achim D. Brucker , Michael Herzberg topic = Computer science/Data structures date = 2020-09-28 notify = adbrucker@0x5f.org, mail@michael-herzberg.de abstract = While the DOM with shadow trees provide the technical basis for defining web components, the DOM standard neither defines the concept of web components nor specifies the safety properties that web components should guarantee. Consequently, the standard also does not discuss how or even if the methods for modifying the DOM respect component boundaries. In AFP entry, we present a formally verified model of web components and define safety properties which ensure that different web components can only interact with each other using well-defined interfaces. Moreover, our verification of the application programming interface (API) of the DOM revealed numerous invariants that implementations of the DOM API need to preserve to ensure the integrity of components. [Interpreter_Optimizations] title = Inline Caching and Unboxing Optimization for Interpreters author = Martin Desharnais topic = Computer science/Programming languages/Misc date = 2020-12-07 notify = martin.desharnais@unibw.de abstract = This Isabelle/HOL formalization builds on the VeriComp entry of the Archive of Formal Proofs to provide the following contributions:
  • an operational semantics for a realistic virtual machine (Std) for dynamically typed programming languages;
  • the formalization of an inline caching optimization (Inca), a proof of bisimulation with (Std), and a compilation function;
  • the formalization of an unboxing optimization (Ubx), a proof of bisimulation with (Inca), and a simple compilation function.
This formalization was described in the CPP 2021 paper Towards Efficient and Verified Virtual Machines for Dynamic Languages extra-history = Change history: [2021-06-14]: refactored function definitions to contain explicit basic blocks
[2021-06-25]: proved conditional completeness of compilation
[Isabelle_Marries_Dirac] title = Isabelle Marries Dirac: a Library for Quantum Computation and Quantum Information author = Anthony Bordg , Hanna Lachnitt, Yijun He topic = Computer science/Algorithms/Quantum computing, Mathematics/Physics/Quantum information date = 2020-11-22 notify = apdb3@cam.ac.uk, lachnitt@stanford.edu abstract = This work is an effort to formalise some quantum algorithms and results in quantum information theory. Formal methods being critical for the safety and security of algorithms and protocols, we foresee their widespread use for quantum computing in the future. We have developed a large library for quantum computing in Isabelle based on a matrix representation for quantum circuits, successfully formalising the no-cloning theorem, quantum teleportation, Deutsch's algorithm, the Deutsch-Jozsa algorithm and the quantum Prisoner's Dilemma. [Projective_Measurements] title = Quantum projective measurements and the CHSH inequality author = Mnacho Echenim topic = Computer science/Algorithms/Quantum computing, Mathematics/Physics/Quantum information date = 2021-03-03 notify = mnacho.echenim@univ-grenoble-alpes.fr abstract = This work contains a formalization of quantum projective measurements, also known as von Neumann measurements, which are based on elements of spectral theory. We also formalized the CHSH inequality, an inequality involving expectations in a probability space that is violated by quantum measurements, thus proving that quantum mechanics cannot be modeled with an underlying local hidden-variable theory. [Finite-Map-Extras] title = Finite Map Extras author = Javier Díaz topic = Computer science/Data structures date = 2020-10-12 notify = javier.diaz.manzi@gmail.com abstract = This entry includes useful syntactic sugar, new operators and functions, and their associated lemmas for finite maps which currently are not present in the standard Finite_Map theory. [Relational_Minimum_Spanning_Trees] title = Relational Minimum Spanning Tree Algorithms author = Walter Guttmann , Nicolas Robinson-O'Brien<> topic = Computer science/Algorithms/Graph date = 2020-12-08 notify = walter.guttmann@canterbury.ac.nz abstract = We verify the correctness of Prim's, Kruskal's and Borůvka's minimum spanning tree algorithms based on algebras for aggregation and minimisation. [Topological_Semantics] title = Topological semantics for paraconsistent and paracomplete logics author = David Fuenmayor topic = Logic/General logic date = 2020-12-17 notify = davfuenmayor@gmail.com abstract = We introduce a generalized topological semantics for paraconsistent and paracomplete logics by drawing upon early works on topological Boolean algebras (cf. works by Kuratowski, Zarycki, McKinsey & Tarski, etc.). In particular, this work exemplarily illustrates the shallow semantical embeddings approach (SSE) employing the proof assistant Isabelle/HOL. By means of the SSE technique we can effectively harness theorem provers, model finders and 'hammers' for reasoning with quantified non-classical logics. [CSP_RefTK] title = The HOL-CSP Refinement Toolkit author = Safouan Taha , Burkhart Wolff , Lina Ye topic = Computer science/Concurrency/Process calculi, Computer science/Semantics date = 2020-11-19 notify = wolff@lri.fr abstract = We use a formal development for CSP, called HOL-CSP2.0, to analyse a family of refinement notions, comprising classic and new ones. This analysis enables to derive a number of properties that allow to deepen the understanding of these notions, in particular with respect to specification decomposition principles for the case of infinite sets of events. The established relations between the refinement relations help to clarify some obscure points in the CSP literature, but also provide a weapon for shorter refinement proofs. Furthermore, we provide a framework for state-normalisation allowing to formally reason on parameterised process architectures. As a result, we have a modern environment for formal proofs of concurrent systems that allow for the combination of general infinite processes with locally finite ones in a logically safe way. We demonstrate these verification-techniques for classical, generalised examples: The CopyBuffer for arbitrary data and the Dijkstra's Dining Philosopher Problem of arbitrary size. [Hood_Melville_Queue] title = Hood-Melville Queue author = Alejandro Gómez-Londoño topic = Computer science/Data structures date = 2021-01-18 notify = nipkow@in.tum.de abstract = This is a verified implementation of a constant time queue. The original design is due to Hood and Melville. This formalization follows the presentation in Purely Functional Data Structuresby Okasaki. [JinjaDCI] title = JinjaDCI: a Java semantics with dynamic class initialization author = Susannah Mansky topic = Computer science/Programming languages/Language definitions date = 2021-01-11 notify = sjohnsn2@illinois.edu, susannahej@gmail.com abstract = We extend Jinja to include static fields, methods, and instructions, and dynamic class initialization, based on the Java SE 8 specification. This includes extension of definitions and proofs. This work is partially described in Mansky and Gunter's paper at CPP 2019 and Mansky's doctoral thesis (UIUC, 2020). [Blue_Eyes] title = Solution to the xkcd Blue Eyes puzzle author = Jakub Kądziołka topic = Logic/General logic/Logics of knowledge and belief date = 2021-01-30 notify = kuba@kadziolka.net abstract = In a puzzle published by Randall Munroe, perfect logicians forbidden from communicating are stranded on an island, and may only leave once they have figured out their own eye color. We present a method of modeling the behavior of perfect logicians and formalize a solution of the puzzle. [Laws_of_Large_Numbers] title = The Laws of Large Numbers author = Manuel Eberl topic = Mathematics/Probability theory date = 2021-02-10 notify = manuel@pruvisto.org abstract =

The Law of Large Numbers states that, informally, if one performs a random experiment $X$ many times and takes the average of the results, that average will be very close to the expected value $E[X]$.

More formally, let $(X_i)_{i\in\mathbb{N}}$ be a sequence of independently identically distributed random variables whose expected value $E[X_1]$ exists. Denote the running average of $X_1, \ldots, X_n$ as $\overline{X}_n$. Then:

  • The Weak Law of Large Numbers states that $\overline{X}_{n} \longrightarrow E[X_1]$ in probability for $n\to\infty$, i.e. $\mathcal{P}(|\overline{X}_{n} - E[X_1]| > \varepsilon) \longrightarrow 0$ as $n\to\infty$ for any $\varepsilon > 0$.
  • The Strong Law of Large Numbers states that $\overline{X}_{n} \longrightarrow E[X_1]$ almost surely for $n\to\infty$, i.e. $\mathcal{P}(\overline{X}_{n} \longrightarrow E[X_1]) = 1$.

In this entry, I formally prove the strong law and from it the weak law. The approach used for the proof of the strong law is a particularly quick and slick one based on ergodic theory, which was formalised by Gouëzel in another AFP entry.

[Cotangent_PFD_Formula] title = A Proof from THE BOOK: The Partial Fraction Expansion of the Cotangent author = Manuel Eberl topic = Mathematics/Analysis date = 2022-03-15 notify = manuel@pruvisto.org abstract =

In this article, I formalise a proof from THE BOOK; namely a formula that was called ‘one of the most beautiful formulas involving elementary functions’:

\[\pi \cot(\pi z) = \frac{1}{z} + \sum_{n=1}^\infty\left(\frac{1}{z+n} + \frac{1}{z-n}\right)\]

The proof uses Herglotz's trick to show the real case and analytic continuation for the complex case.

[BTree] title = A Verified Imperative Implementation of B-Trees author = Niels Mündler topic = Computer science/Data structures date = 2021-02-24 notify = n.muendler@tum.de abstract = In this work, we use the interactive theorem prover Isabelle/HOL to verify an imperative implementation of the classical B-tree data structure invented by Bayer and McCreight [ACM 1970]. The implementation supports set membership, insertion and deletion queries with efficient binary search for intra-node navigation. This is accomplished by first specifying the structure abstractly in the functional modeling language HOL and proving functional correctness. Using manual refinement, we derive an imperative implementation in Imperative/HOL. We show the validity of this refinement using the separation logic utilities from the Isabelle Refinement Framework . The code can be exported to the programming languages SML, OCaml and Scala. We examine the runtime of all operations indirectly by reproducing results of the logarithmic relationship between height and the number of nodes. The results are discussed in greater detail in the corresponding Bachelor's Thesis. extra-history = Change history: [2021-05-02]: Add implementation and proof of correctness of imperative deletion operations. Further add the option to export code to OCaml.
[Sunflowers] title = The Sunflower Lemma of Erdős and Rado author = René Thiemann topic = Mathematics/Combinatorics date = 2021-02-25 notify = rene.thiemann@uibk.ac.at abstract = We formally define sunflowers and provide a formalization of the sunflower lemma of Erdős and Rado: whenever a set of size-k-sets has a larger cardinality than (r - 1)k · k!, then it contains a sunflower of cardinality r. [Mereology] title = Mereology author = Ben Blumson topic = Logic/Philosophical aspects date = 2021-03-01 notify = benblumson@gmail.com abstract = We use Isabelle/HOL to verify elementary theorems and alternative axiomatizations of classical extensional mereology. [Modular_arithmetic_LLL_and_HNF_algorithms] title = Two algorithms based on modular arithmetic: lattice basis reduction and Hermite normal form computation author = Ralph Bottesch <>, Jose Divasón , René Thiemann topic = Computer science/Algorithms/Mathematical date = 2021-03-12 notify = rene.thiemann@uibk.ac.at abstract = We verify two algorithms for which modular arithmetic plays an essential role: Storjohann's variant of the LLL lattice basis reduction algorithm and Kopparty's algorithm for computing the Hermite normal form of a matrix. To do this, we also formalize some facts about the modulo operation with symmetric range. Our implementations are based on the original papers, but are otherwise efficient. For basis reduction we formalize two versions: one that includes all of the optimizations/heuristics from Storjohann's paper, and one excluding a heuristic that we observed to often decrease efficiency. We also provide a fast, self-contained certifier for basis reduction, based on the efficient Hermite normal form algorithm. [Constructive_Cryptography_CM] title = Constructive Cryptography in HOL: the Communication Modeling Aspect author = Andreas Lochbihler , S. Reza Sefidgar <> topic = Computer science/Security/Cryptography, Mathematics/Probability theory date = 2021-03-17 notify = mail@andreas-lochbihler.de, reza.sefidgar@inf.ethz.ch abstract = Constructive Cryptography (CC) [ICS 2011, TOSCA 2011, TCC 2016] introduces an abstract approach to composable security statements that allows one to focus on a particular aspect of security proofs at a time. Instead of proving the properties of concrete systems, CC studies system classes, i.e., the shared behavior of similar systems, and their transformations. Modeling of systems communication plays a crucial role in composability and reusability of security statements; yet, this aspect has not been studied in any of the existing CC results. We extend our previous CC formalization [Constructive_Cryptography, CSF 2019] with a new semantic domain called Fused Resource Templates (FRT) that abstracts over the systems communication patterns in CC proofs. This widens the scope of cryptography proof formalizations in the CryptHOL library [CryptHOL, ESOP 2016, J Cryptol 2020]. This formalization is described in Abstract Modeling of Systems Communication in Constructive Cryptography using CryptHOL. [IFC_Tracking] title = Information Flow Control via Dependency Tracking author = Benedikt Nordhoff topic = Computer science/Security date = 2021-04-01 notify = b.n@wwu.de abstract = We provide a characterisation of how information is propagated by program executions based on the tracking data and control dependencies within executions themselves. The characterisation might be used for deriving approximative safety properties to be targeted by static analyses or checked at runtime. We utilise a simple yet versatile control flow graph model as a program representation. As our model is not assumed to be finite it can be instantiated for a broad class of programs. The targeted security property is indistinguishable security where executions produce sequences of observations and only non-terminating executions are allowed to drop a tail of those. A very crude approximation of our characterisation is slicing based on program dependence graphs, which we use as a minimal example and derive a corresponding soundness result. For further details and applications refer to the authors upcoming dissertation. [Grothendieck_Schemes] title = Grothendieck's Schemes in Algebraic Geometry author = Anthony Bordg , Lawrence Paulson , Wenda Li topic = Mathematics/Algebra, Mathematics/Geometry date = 2021-03-29 notify = apdb3@cam.ac.uk, lp15@cam.ac.uk abstract = We formalize mainstream structures in algebraic geometry culminating in Grothendieck's schemes: presheaves of rings, sheaves of rings, ringed spaces, locally ringed spaces, affine schemes and schemes. We prove that the spectrum of a ring is a locally ringed space, hence an affine scheme. Finally, we prove that any affine scheme is a scheme. [Progress_Tracking] title = Formalization of Timely Dataflow's Progress Tracking Protocol author = Matthias Brun<>, Sára Decova<>, Andrea Lattuada, Dmitriy Traytel topic = Computer science/Algorithms/Distributed date = 2021-04-13 notify = matthias.brun@inf.ethz.ch, traytel@di.ku.dk abstract = Large-scale stream processing systems often follow the dataflow paradigm, which enforces a program structure that exposes a high degree of parallelism. The Timely Dataflow distributed system supports expressive cyclic dataflows for which it offers low-latency data- and pipeline-parallel stream processing. To achieve high expressiveness and performance, Timely Dataflow uses an intricate distributed protocol for tracking the computation’s progress. We formalize this progress tracking protocol and verify its safety. Our formalization is described in detail in our forthcoming ITP'21 paper. [GaleStewart_Games] title = Gale-Stewart Games author = Sebastiaan Joosten topic = Mathematics/Games and economics date = 2021-04-23 notify = sjcjoosten@gmail.com abstract = This is a formalisation of the main result of Gale and Stewart from 1953, showing that closed finite games are determined. This property is now known as the Gale Stewart Theorem. While the original paper shows some additional theorems as well, we only formalize this main result, but do so in a somewhat general way. We formalize games of a fixed arbitrary length, including infinite length, using co-inductive lists, and show that defensive strategies exist unless the other player is winning. For closed games, defensive strategies are winning for the closed player, proving that such games are determined. For finite games, which are a special case in our formalisation, all games are closed. [Metalogic_ProofChecker] title = Isabelle's Metalogic: Formalization and Proof Checker author = Tobias Nipkow , Simon Roßkopf topic = Logic/General logic date = 2021-04-27 notify = rosskops@in.tum.de abstract = In this entry we formalize Isabelle's metalogic in Isabelle/HOL. Furthermore, we define a language of proof terms and an executable proof checker and prove its soundness wrt. the metalogic. The formalization is intentionally kept close to the Isabelle implementation(for example using de Brujin indices) to enable easy integration of generated code with the Isabelle system without a complicated translation layer. The formalization is described in our CADE 28 paper. [Regression_Test_Selection] title = Regression Test Selection author = Susannah Mansky topic = Computer science/Algorithms date = 2021-04-30 notify = sjohnsn2@illinois.edu, susannahej@gmail.com abstract = This development provides a general definition for safe Regression Test Selection (RTS) algorithms. RTS algorithms select which tests to rerun on revised code, reducing the time required to check for newly introduced errors. An RTS algorithm is considered safe if and only if all deselected tests would have unchanged results. This definition is instantiated with two class-collection-based RTS algorithms run over the JVM as modeled by JinjaDCI. This is achieved with a general definition for Collection Semantics, small-step semantics instrumented to collect information during execution. As the RTS definition mandates safety, these instantiations include proofs of safety. This work is described in Mansky and Gunter's LSFA 2020 paper and Mansky's doctoral thesis (UIUC, 2020). [Padic_Ints] title = Hensel's Lemma for the p-adic Integers author = Aaron Crighton topic = Mathematics/Number theory date = 2021-03-23 notify = crightoa@mcmaster.ca abstract = We formalize the ring of p-adic integers within the framework of the HOL-Algebra library. The carrier of the ring is formalized as the inverse limit of quotients of the integers by powers of a fixed prime p. We define an integer-valued valuation, as well as an extended-integer valued valuation which sends 0 to the infinite element. Basic topological facts about the p-adic integers are formalized, including completeness and sequential compactness. Taylor expansions of polynomials over a commutative ring are defined, culminating in the formalization of Hensel's Lemma based on a proof due to Keith Conrad. [Combinatorics_Words] title = Combinatorics on Words Basics author = Štěpán Holub , Martin Raška<>, Štěpán Starosta topic = Computer science/Automata and formal languages date = 2021-05-24 notify = holub@karlin.mff.cuni.cz, stepan.starosta@fit.cvut.cz abstract = We formalize basics of Combinatorics on Words. This is an extension of existing theories on lists. We provide additional properties related to prefix, suffix, factor, length and rotation. The topics include prefix and suffix comparability, mismatch, word power, total and reversed morphisms, border, periods, primitivity and roots. We also formalize basic, mostly folklore results related to word equations: equidivisibility, commutation and conjugation. Slightly advanced properties include the Periodicity lemma (often cited as the Fine and Wilf theorem) and the variant of the Lyndon-Schützenberger theorem for words. We support the algebraic point of view which sees words as generators of submonoids of a free monoid. This leads to the concepts of the (free) hull, the (free) basis (or code). [Combinatorics_Words_Lyndon] title = Lyndon words author = Štěpán Holub , Štěpán Starosta topic = Computer science/Automata and formal languages date = 2021-05-24 notify = holub@karlin.mff.cuni.cz, stepan.starosta@fit.cvut.cz abstract = Lyndon words are words lexicographically minimal in their conjugacy class. We formalize their basic properties and characterizations, in particular the concepts of the longest Lyndon suffix and the Lyndon factorization. Most of the work assumes a fixed lexicographical order. Nevertheless we also define the smallest relation guaranteeing lexicographical minimality of a given word (in its conjugacy class). [Combinatorics_Words_Graph_Lemma] title = Graph Lemma author = Štěpán Holub , Štěpán Starosta topic = Computer science/Automata and formal languages date = 2021-05-24 notify = holub@karlin.mff.cuni.cz, stepan.starosta@fit.cvut.cz abstract = Graph lemma quantifies the defect effect of a system of word equations. That is, it provides an upper bound on the rank of the system. We formalize the proof based on the decomposition of a solution into its free basis. A direct application is an alternative proof of the fact that two noncommuting words form a code. [Lifting_the_Exponent] title = Lifting the Exponent author = Jakub Kądziołka topic = Mathematics/Number theory date = 2021-04-27 notify = kuba@kadziolka.net abstract = We formalize the Lifting the Exponent Lemma, which shows how to find the largest power of $p$ dividing $a^n \pm b^n$, for a prime $p$ and positive integers $a$ and $b$. The proof follows Amir Hossein Parvardi's. [IMP_Compiler] title = A Shorter Compiler Correctness Proof for Language IMP author = Pasquale Noce topic = Computer science/Programming languages/Compiling date = 2021-06-04 notify = pasquale.noce.lavoro@gmail.com abstract = This paper presents a compiler correctness proof for the didactic imperative programming language IMP, introduced in Nipkow and Klein's book on formal programming language semantics (version of March 2021), whose size is just two thirds of the book's proof in the number of formal text lines. As such, it promises to constitute a further enhanced reference for the formal verification of compilers meant for larger, real-world programming languages. The presented proof does not depend on language determinism, so that the proposed approach can be applied to non-deterministic languages as well. As a confirmation, this paper extends IMP with an additional non-deterministic choice command, and proves compiler correctness, viz. the simulation of compiled code execution by source code, for such extended language. [Public_Announcement_Logic] title = Public Announcement Logic author = Asta Halkjær From topic = Logic/General logic/Logics of knowledge and belief date = 2021-06-17 notify = ahfrom@dtu.dk abstract = This work is a formalization of public announcement logic with countably many agents. It includes proofs of soundness and completeness for a variant of the axiom system PA + DIST! + NEC!. The completeness proof builds on the Epistemic Logic theory. Paper: https://doi.org/10.1007/978-3-030-90138-7_2. [MiniSail] title = MiniSail - A kernel language for the ISA specification language SAIL author = Mark Wassell topic = Computer science/Programming languages/Type systems date = 2021-06-18 notify = mpwassell@gmail.com abstract = MiniSail is a kernel language for Sail, an instruction set architecture (ISA) specification language. Sail is an imperative language with a light-weight dependent type system similar to refinement type systems. From an ISA specification, the Sail compiler can generate theorem prover code and C (or OCaml) to give an executable emulator for an architecture. The idea behind MiniSail is to capture the key and novel features of Sail in terms of their syntax, typing rules and operational semantics, and to confirm that they work together by proving progress and preservation lemmas. We use the Nominal2 library to handle binding. [SpecCheck] title = SpecCheck - Specification-Based Testing for Isabelle/ML author = Kevin Kappelmann , Lukas Bulwahn , Sebastian Willenbrink topic = Tools date = 2021-07-01 notify = kevin.kappelmann@tum.de abstract = SpecCheck is a QuickCheck-like testing framework for Isabelle/ML. You can use it to write specifications for ML functions. SpecCheck then checks whether your specification holds by testing your function against a given number of generated inputs. It helps you to identify bugs by printing counterexamples on failure and provides you timing information. SpecCheck is customisable and allows you to specify your own input generators, test output formats, as well as pretty printers and shrinking functions for counterexamples among other things. [Relational_Forests] title = Relational Forests author = Walter Guttmann topic = Mathematics/Graph theory date = 2021-08-03 notify = walter.guttmann@canterbury.ac.nz abstract = We study second-order formalisations of graph properties expressed as first-order formulas in relation algebras extended with a Kleene star. The formulas quantify over relations while still avoiding quantification over elements of the base set. We formalise the property of undirected graphs being acyclic this way. This involves a study of various kinds of orientation of graphs. We also verify basic algorithms to constructively prove several second-order properties. [Fresh_Identifiers] title = Fresh identifiers author = Andrei Popescu , Thomas Bauereiss topic = Computer science/Data structures date = 2021-08-16 notify = thomas@bauereiss.name, a.popescu@sheffield.ac.uk abstract = This entry defines a type class with an operator returning a fresh identifier, given a set of already used identifiers and a preferred identifier. The entry provides a default instantiation for any infinite type, as well as executable instantiations for natural numbers and strings. [CoCon] title = CoCon: A Confidentiality-Verified Conference Management System author = Andrei Popescu , Peter Lammich , Thomas Bauereiss topic = Computer science/Security date = 2021-08-16 notify = thomas@bauereiss.name, a.popescu@sheffield.ac.uk abstract = This entry contains the confidentiality verification of the (functional kernel of) the CoCon conference management system [1, 2]. The confidentiality properties refer to the documents managed by the system, namely papers, reviews, discussion logs and acceptance/rejection decisions, and also to the assignment of reviewers to papers. They have all been formulated as instances of BD Security [3, 4] and verified using the BD Security unwinding technique. [BD_Security_Compositional] title = Compositional BD Security author = Thomas Bauereiss , Andrei Popescu topic = Computer science/Security date = 2021-08-16 notify = thomas@bauereiss.name, a.popescu@sheffield.ac.uk abstract = Building on a previous AFP entry that formalizes the Bounded-Deducibility Security (BD Security) framework [1], we formalize compositionality and transport theorems for information flow security. These results allow lifting BD Security properties from individual components specified as transition systems, to a composition of systems specified as communicating products of transition systems. The underlying ideas of these results are presented in the papers [1] and [2]. The latter paper also describes a major case study where these results have been used: on verifying the CoSMeDis distributed social media platform (itself formalized as an AFP entry that builds on this entry). [CoSMed] title = CoSMed: A confidentiality-verified social media platform author = Thomas Bauereiss , Andrei Popescu topic = Computer science/Security date = 2021-08-16 notify = thomas@bauereiss.name, a.popescu@sheffield.ac.uk abstract = This entry contains the confidentiality verification of the (functional kernel of) the CoSMed social media platform. The confidentiality properties are formalized as instances of BD Security [1, 2]. An innovation in the deployment of BD Security compared to previous work is the use of dynamic declassification triggers, incorporated as part of inductive bounds, for providing stronger guarantees that account for the repeated opening and closing of access windows. To further strengthen the confidentiality guarantees, we also prove "traceback" properties about the accessibility decisions affecting the information managed by the system. [CoSMeDis] title = CoSMeDis: A confidentiality-verified distributed social media platform author = Thomas Bauereiss , Andrei Popescu topic = Computer science/Security date = 2021-08-16 notify = thomas@bauereiss.name, a.popescu@sheffield.ac.uk abstract = This entry contains the confidentiality verification of the (functional kernel of) the CoSMeDis distributed social media platform presented in [1]. CoSMeDis is a multi-node extension the CoSMed prototype social media platform [2, 3, 4]. The confidentiality properties are formalized as instances of BD Security [5, 6]. The lifting of confidentiality properties from single nodes to the entire CoSMeDis network is performed using compositionality and transport theorems for BD Security, which are described in [1] and formalized in a separate AFP entry. [Three_Circles] title = The Theorem of Three Circles author = Fox Thomson , Wenda Li topic = Mathematics/Analysis date = 2021-08-21 notify = foxthomson0@gmail.com, wl302@cam.ac.uk abstract = The Descartes test based on Bernstein coefficients and Descartes’ rule of signs effectively (over-)approximates the number of real roots of a univariate polynomial over an interval. In this entry we formalise the theorem of three circles, which gives sufficient conditions for when the Descartes test returns 0 or 1. This is the first step for efficient root isolation. [Design_Theory] title = Combinatorial Design Theory author = Chelsea Edmonds , Lawrence Paulson topic = Mathematics/Combinatorics date = 2021-08-13 notify = cle47@cam.ac.uk abstract = Combinatorial design theory studies incidence set systems with certain balance and symmetry properties. It is closely related to hypergraph theory. This formalisation presents a general library for formal reasoning on incidence set systems, designs and their applications, including formal definitions and proofs for many key properties, operations, and theorems on the construction and existence of designs. Notably, this includes formalising t-designs, balanced incomplete block designs (BIBD), group divisible designs (GDD), pairwise balanced designs (PBD), design isomorphisms, and the relationship between graphs and designs. A locale-centric approach has been used to manage the relationships between the many different types of designs. Theorems of particular interest include the necessary conditions for existence of a BIBD, Wilson's construction on GDDs, and Bose's inequality on resolvable designs. Parts of this formalisation are explored in the paper "A Modular First Formalisation of Combinatorial Design Theory", presented at CICM 2021. [Logging_Independent_Anonymity] title = Logging-independent Message Anonymity in the Relational Method author = Pasquale Noce topic = Computer science/Security date = 2021-08-26 notify = pasquale.noce.lavoro@gmail.com abstract = In the context of formal cryptographic protocol verification, logging-independent message anonymity is the property for a given message to remain anonymous despite the attacker's capability of mapping messages of that sort to agents based on some intrinsic feature of such messages, rather than by logging the messages exchanged by legitimate agents as with logging-dependent message anonymity. This paper illustrates how logging-independent message anonymity can be formalized according to the relational method for formal protocol verification by considering a real-world protocol, namely the Restricted Identification one by the BSI. This sample model is used to verify that the pseudonymous identifiers output by user identification tokens remain anonymous under the expected conditions. [Dominance_CHK] title = A data flow analysis algorithm for computing dominators author = Nan Jiang<> topic = Computer science/Programming languages/Static analysis date = 2021-09-05 notify = nanjiang@whu.edu.cn abstract = This entry formalises the fast iterative algorithm for computing dominators due to Cooper, Harvey and Kennedy. It gives a specification of computing dominators on a control flow graph where each node refers to its reverse post order number. A semilattice of reversed-ordered list which represents dominators is built and a Kildall-style algorithm on the semilattice is defined for computing dominators. Finally the soundness and completeness of the algorithm are proved w.r.t. the specification. [Conditional_Simplification] title = Conditional Simplification author = Mihails Milehins topic = Tools date = 2021-09-06 notify = mihailsmilehins@gmail.com abstract = The article provides a collection of experimental general-purpose proof methods for the object logic Isabelle/HOL of the formal proof assistant Isabelle. The methods in the collection offer functionality that is similar to certain aspects of the functionality provided by the standard proof methods of Isabelle that combine classical reasoning and rewriting, such as the method auto, but use a different approach for rewriting. More specifically, these methods allow for the side conditions of the rewrite rules to be solved via intro-resolution. extra-history = Change history: [2022-01-07]: added a switch for backtracking (revision 241da1cdeabf)
[Intro_Dest_Elim] title = IDE: Introduction, Destruction, Elimination author = Mihails Milehins topic = Tools date = 2021-09-06 notify = mihailsmilehins@gmail.com abstract = The article provides the command mk_ide for the object logic Isabelle/HOL of the formal proof assistant Isabelle. The command mk_ide enables the automated synthesis of the introduction, destruction and elimination rules from arbitrary definitions of constant predicates stated in Isabelle/HOL. [CZH_Foundations] title = Category Theory for ZFC in HOL I: Foundations: Design Patterns, Set Theory, Digraphs, Semicategories author = Mihails Milehins topic = Mathematics/Category theory, Logic/Set theory date = 2021-09-06 notify = mihailsmilehins@gmail.com abstract = This article provides a foundational framework for the formalization of category theory in the object logic ZFC in HOL of the formal proof assistant Isabelle. More specifically, this article provides a formalization of canonical set-theoretic constructions internalized in the type V associated with the ZFC in HOL, establishes a design pattern for the formalization of mathematical structures using sequences and locales, and showcases the developed infrastructure by providing formalizations of the elementary theories of digraphs and semicategories. The methodology chosen for the formalization of the theories of digraphs and semicategories (and categories in future articles) rests on the ideas that were originally expressed in the article Set-Theoretical Foundations of Category Theory written by Solomon Feferman and Georg Kreisel. Thus, in the context of this work, each of the aforementioned mathematical structures is represented as a term of the type V embedded into a stage of the von Neumann hierarchy. [CZH_Elementary_Categories] title = Category Theory for ZFC in HOL II: Elementary Theory of 1-Categories author = Mihails Milehins topic = Mathematics/Category theory date = 2021-09-06 notify = mihailsmilehins@gmail.com abstract = This article provides a formalization of the foundations of the theory of 1-categories in the object logic ZFC in HOL of the formal proof assistant Isabelle. The article builds upon the foundations that were established in the AFP entry Category Theory for ZFC in HOL I: Foundations: Design Patterns, Set Theory, Digraphs, Semicategories. extra-history = Change history: [2021-11-07]: added a definition of a dagger monoidal category (revision c9ed46c09de9)
[CZH_Universal_Constructions] title = Category Theory for ZFC in HOL III: Universal Constructions author = Mihails Milehins topic = Mathematics/Category theory date = 2021-09-06 notify = mihailsmilehins@gmail.com abstract = The article provides a formalization of elements of the theory of universal constructions for 1-categories (such as limits, adjoints and Kan extensions) in the object logic ZFC in HOL of the formal proof assistant Isabelle. The article builds upon the foundations established in the AFP entry Category Theory for ZFC in HOL II: Elementary Theory of 1-Categories. extra-history = Change history: [2022-05-16]: creation and preservation of limits (revision 68412a363595)
[Conditional_Transfer_Rule] title = Conditional Transfer Rule author = Mihails Milehins topic = Tools date = 2021-09-06 notify = mihailsmilehins@gmail.com abstract = This article provides a collection of experimental utilities for unoverloading of definitions and synthesis of conditional transfer rules for the object logic Isabelle/HOL of the formal proof assistant Isabelle written in Isabelle/ML. [Types_To_Sets_Extension] title = Extension of Types-To-Sets author = Mihails Milehins topic = Tools date = 2021-09-06 notify = mihailsmilehins@gmail.com abstract = In their article titled From Types to Sets by Local Type Definitions in Higher-Order Logic and published in the proceedings of the conference Interactive Theorem Proving in 2016, Ondřej Kunčar and Andrei Popescu propose an extension of the logic Isabelle/HOL and an associated algorithm for the relativization of the type-based theorems to more flexible set-based theorems, collectively referred to as Types-To-Sets. One of the aims of their work was to open an opportunity for the development of a software tool for applied relativization in the implementation of the logic Isabelle/HOL of the proof assistant Isabelle. In this article, we provide a prototype of a software framework for the interactive automated relativization of theorems in Isabelle/HOL, developed as an extension of the proof language Isabelle/Isar. The software framework incorporates the implementation of the proposed extension of the logic, and builds upon some of the ideas for further work expressed in the original article on Types-To-Sets by Ondřej Kunčar and Andrei Popescu and the subsequent article Smooth Manifolds and Types to Sets for Linear Algebra in Isabelle/HOL that was written by Fabian Immler and Bohua Zhan and published in the proceedings of the International Conference on Certified Programs and Proofs in 2019. extra-history = Change history: [2021-11-15]: integration with SpecCheck (revision 61e152c118d4)
[Complex_Bounded_Operators] title = Complex Bounded Operators author = Jose Manuel Rodriguez Caballero , Dominique Unruh topic = Mathematics/Analysis date = 2021-09-18 notify = unruh@ut.ee abstract = We present a formalization of bounded operators on complex vector spaces. Our formalization contains material on complex vector spaces (normed spaces, Banach spaces, Hilbert spaces) that complements and goes beyond the developments of real vectors spaces in the Isabelle/HOL standard library. We define the type of bounded operators between complex vector spaces (cblinfun) and develop the theory of unitaries, projectors, extension of bounded linear functions (BLT theorem), adjoints, Loewner order, closed subspaces and more. For the finite-dimensional case, we provide code generation support by identifying finite-dimensional operators with matrices as formalized in the Jordan_Normal_Form AFP entry. [Weighted_Path_Order] title = A Formalization of Weighted Path Orders and Recursive Path Orders author = Christian Sternagel , René Thiemann , Akihisa Yamada topic = Logic/Rewriting date = 2021-09-16 notify = rene.thiemann@uibk.ac.at abstract = We define the weighted path order (WPO) and formalize several properties such as strong normalization, the subterm property, and closure properties under substitutions and contexts. Our definition of WPO extends the original definition by also permitting multiset comparisons of arguments instead of just lexicographic extensions. Therefore, our WPO not only subsumes lexicographic path orders (LPO), but also recursive path orders (RPO). We formally prove these subsumptions and therefore all of the mentioned properties of WPO are automatically transferable to LPO and RPO as well. Such a transformation is not required for Knuth–Bendix orders (KBO), since they have already been formalized. Nevertheless, we still provide a proof that WPO subsumes KBO and thereby underline the generality of WPO. [FOL_Axiomatic] title = Soundness and Completeness of an Axiomatic System for First-Order Logic author = Asta Halkjær From topic = Logic/General logic/Classical first-order logic, Logic/Proof theory date = 2021-09-24 notify = ahfrom@dtu.dk abstract = This work is a formalization of the soundness and completeness of an axiomatic system for first-order logic. The proof system is based on System Q1 by Smullyan and the completeness proof follows his textbook "First-Order Logic" (Springer-Verlag 1968). The completeness proof is in the Henkin style where a consistent set is extended to a maximal consistent set using Lindenbaum's construction and Henkin witnesses are added during the construction to ensure saturation as well. The resulting set is a Hintikka set which, by the model existence theorem, is satisfiable in the Herbrand universe. [Virtual_Substitution] title = Verified Quadratic Virtual Substitution for Real Arithmetic author = Matias Scharager , Katherine Cordwell , Stefan Mitsch , André Platzer topic = Computer science/Algorithms/Mathematical date = 2021-10-02 notify = mscharag@cs.cmu.edu, kcordwel@cs.cmu.edu, smitsch@cs.cmu.edu, aplatzer@cs.cmu.edu abstract = This paper presents a formally verified quantifier elimination (QE) algorithm for first-order real arithmetic by linear and quadratic virtual substitution (VS) in Isabelle/HOL. The Tarski-Seidenberg theorem established that the first-order logic of real arithmetic is decidable by QE. However, in practice, QE algorithms are highly complicated and often combine multiple methods for performance. VS is a practically successful method for QE that targets formulas with low-degree polynomials. To our knowledge, this is the first work to formalize VS for quadratic real arithmetic including inequalities. The proofs necessitate various contributions to the existing multivariate polynomial libraries in Isabelle/HOL. Our framework is modularized and easily expandable (to facilitate integrating future optimizations), and could serve as a basis for developing practical general-purpose QE algorithms. Further, as our formalization is designed with practicality in mind, we export our development to SML and test the resulting code on 378 benchmarks from the literature, comparing to Redlog, Z3, Wolfram Engine, and SMT-RAT. This identified inconsistencies in some tools, underscoring the significance of a verified approach for the intricacies of real arithmetic. [Correctness_Algebras] title = Algebras for Iteration, Infinite Executions and Correctness of Sequential Computations author = Walter Guttmann topic = Computer science/Programming languages/Logics date = 2021-10-12 notify = walter.guttmann@canterbury.ac.nz abstract = We study models of state-based non-deterministic sequential computations and describe them using algebras. We propose algebras that describe iteration for strict and non-strict computations. They unify computation models which differ in the fixpoints used to represent iteration. We propose algebras that describe the infinite executions of a computation. They lead to a unified approximation order and results that connect fixpoints in the approximation and refinement orders. This unifies the semantics of recursion for a range of computation models. We propose algebras that describe preconditions and the effect of while-programs under postconditions. They unify correctness statements in two dimensions: one statement applies in various computation models to various correctness claims. [Belief_Revision] title = Belief Revision Theory author = Valentin Fouillard , Safouan Taha , Frédéric Boulanger , Nicolas Sabouret <> topic = Logic/General logic/Logics of knowledge and belief date = 2021-10-19 notify = safouan.taha@lri.fr, valentin.fouillard@limsi.fr abstract = The 1985 paper by Carlos Alchourrón, Peter Gärdenfors, and David Makinson (AGM), “On the Logic of Theory Change: Partial Meet Contraction and Revision Functions” launches a large and rapidly growing literature that employs formal models and logics to handle changing beliefs of a rational agent and to take into account new piece of information observed by this agent. In 2011, a review book titled "AGM 25 Years: Twenty-Five Years of Research in Belief Change" was edited to summarize the first twenty five years of works based on AGM. This HOL-based AFP entry is a faithful formalization of the AGM operators (e.g. contraction, revision, remainder ...) axiomatized in the original paper. It also contains the proofs of all the theorems stated in the paper that show how these operators combine. Both proofs of Harper and Levi identities are established. [X86_Semantics] title = X86 instruction semantics and basic block symbolic execution author = Freek Verbeek , Abhijith Bharadwaj <>, Joshua Bockenek <>, Ian Roessle <>, Timmy Weerwag <>, Binoy Ravindran <> topic = Computer science/Hardware, Computer science/Semantics date = 2021-10-13 notify = freek@vt.edu abstract = This AFP entry provides semantics for roughly 120 different X86-64 assembly instructions. These instructions include various moves, arithmetic/logical operations, jumps, call/return, SIMD extensions and others. External functions are supported by allowing a user to provide custom semantics for these calls. Floating-point operations are mapped to uninterpreted functions. The model provides semantics for register aliasing and a byte-level little-endian memory model. The semantics are purposefully incomplete, but overapproximative. For example, the precise effect of flags may be undefined for certain instructions, or instructions may simply have no semantics at all. In those cases, the semantics are mapped to universally quantified uninterpreted terms from a locale. Second, this entry provides a method to symbolic execution of basic blocks. The method, called ''se_step'' (for: symbolic execution step) fetches an instruction and updates the current symbolic state while keeping track of assumptions made over the memory model. A key component is a set of theorems that prove how reads from memory resolve after writes have occurred. Thirdly, this entry provides a parser that allows the user to copy-paste the output of the standard disassembly tool objdump into Isabelle/HOL. A couple small and explanatory examples are included, including functions from the word count program. Several examples can be supplied upon request (they are not included due to the running time of verification): functions from the floating-point modulo function from FDLIBM, the GLIBC strlen function and the CoreUtils SHA256 implementation. [Registers] title = Quantum and Classical Registers author = Dominique Unruh topic = Computer science/Algorithms/Quantum computing, Computer science/Programming languages/Logics, Computer science/Semantics date = 2021-10-28 notify = unruh@ut.ee abstract = A formalization of the theory of quantum and classical registers as developed by (Unruh, Quantum and Classical Registers). In a nutshell, a register refers to a part of a larger memory or system that can be accessed independently. Registers can be constructed from other registers and several (compatible) registers can be composed. This formalization develops both the generic theory of registers as well as specific instantiations for classical and quantum registers. [Szemeredi_Regularity] title = Szemerédi's Regularity Lemma author = Chelsea Edmonds , Angeliki Koutsoukou-Argyraki , Lawrence C. Paulson topic = Mathematics/Graph theory, Mathematics/Combinatorics date = 2021-11-05 notify = lp15@cam.ac.uk abstract = Szemerédi's regularity lemma is a key result in the study of large graphs. It asserts the existence of an upper bound on the number of parts the vertices of a graph need to be partitioned into such that the edges between the parts are random in a certain sense. This bound depends only on the desired precision and not on the graph itself, in the spirit of Ramsey's theorem. The formalisation follows online course notes by Tim Gowers and Yufei Zhao. [Factor_Algebraic_Polynomial] title = Factorization of Polynomials with Algebraic Coefficients author = Manuel Eberl , René Thiemann topic = Mathematics/Algebra date = 2021-11-08 notify = rene.thiemann@uibk.ac.at abstract = The AFP already contains a verified implementation of algebraic numbers. However, it is has a severe limitation in its factorization algorithm of real and complex polynomials: the factorization is only guaranteed to succeed if the coefficients of the polynomial are rational numbers. In this work, we verify an algorithm to factor all real and complex polynomials whose coefficients are algebraic. The existence of such an algorithm proves in a constructive way that the set of complex algebraic numbers is algebraically closed. Internally, the algorithm is based on resultants of multivariate polynomials and an approximation algorithm using interval arithmetic. [PAL] title = Automating Public Announcement Logic and the Wise Men Puzzle in Isabelle/HOL author = Christoph Benzmüller , Sebastian Reiche topic = Logic/General logic/Logics of knowledge and belief date = 2021-11-08 notify = c.benzmueller@gmail.com abstract = We present a shallow embedding of public announcement logic (PAL) with relativized general knowledge in HOL. We then use PAL to obtain an elegant encoding of the wise men puzzle, which we solve automatically using sledgehammer. [SimplifiedOntologicalArgument] title = Exploring Simplified Variants of Gödel’s Ontological Argument in Isabelle/HOL author = Christoph Benzmüller topic = Logic/Philosophical aspects, Logic/General logic/Modal logic date = 2021-11-08 notify = c.benzmueller@gmail.com abstract =

Simplified variants of Gödel's ontological argument are explored. Among those is a particularly interesting simplified argument which is (i) valid already in basic modal logics K or KT, (ii) which does not suffer from modal collapse, and (iii) which avoids the rather complex predicates of essence (Ess.) and necessary existence (NE) as used by Gödel.

Whether the presented variants increase or decrease the attractiveness and persuasiveness of the ontological argument is a question I would like to pass on to philosophy and theology.

[Van_Emde_Boas_Trees] title = van Emde Boas Trees author = Thomas Ammer<>, Peter Lammich<> topic = Computer science/Data structures date = 2021-11-23 notify = lammich@in.tum.de abstract = The van Emde Boas tree or van Emde Boas priority queue is a data structure supporting membership test, insertion, predecessor and successor search, minimum and maximum determination and deletion in O(log log U) time, where U = 0,...,2n-1 is the overall range to be considered.

The presented formalization follows Chapter 20 of the popular Introduction to Algorithms (3rd ed.) by Cormen, Leiserson, Rivest and Stein (CLRS), extending the list of formally verified CLRS algorithms. Our current formalization is based on the first author's bachelor's thesis.

First, we prove correct a functional implementation, w.r.t. an abstract data type for sets. Apart from functional correctness, we show a resource bound, and runtime bounds w.r.t. manually defined timing functions for the operations.

Next, we refine the operations to Imperative HOL with time, and show correctness and complexity. This yields a practically more efficient implementation, and eliminates the manually defined timing functions from the trusted base of the proof. [Hahn_Jordan_Decomposition] title = The Hahn and Jordan Decomposition Theorems author = Marie Cousin , Mnacho Echenim , Hervé Guiol topic = Mathematics/Measure theory date = 2021-11-19 notify = mnacho.echenim@univ-grenoble-alpes.fr abstract = In this work we formalize the Hahn decomposition theorem for signed measures, namely that any measure space for a signed measure can be decomposed into a positive and a negative set, where every measurable subset of the positive one has a positive measure, and every measurable subset of the negative one has a negative measure. We also formalize the Jordan decomposition theorem as a corollary, which states that the signed measure under consideration admits a unique decomposition into a difference of two positive measures, at least one of which is finite. [Simplicial_complexes_and_boolean_functions] title = Simplicial Complexes and Boolean functions author = Jesús Aransay , Alejandro del Campo , Julius Michaelis topic = Mathematics/Topology date = 2021-11-29 notify = jesus-maria.aransay@unirioja.es abstract = In this work we formalise the isomorphism between simplicial complexes of dimension $n$ and monotone Boolean functions in $n$ variables, mainly following the definitions and results as introduced by N. A. Scoville. We also take advantage of the AFP representation of ROBDD (Reduced Ordered Binary Decision Diagrams) to compute the ROBDD representation of a given simplicial complex (by means of the isomorphism to Boolean functions). Some examples of simplicial complexes and associated Boolean functions are also presented. [Foundation_of_geometry] title = Foundation of geometry in planes, and some complements: Excluding the parallel axioms author = Fumiya Iwama <> topic = Mathematics/Geometry date = 2021-11-22 notify = d1623001@s.konan-u.ac.jp abstract = "Foundations of Geometry" is a mathematical book written by Hilbert in 1899. This entry is a complete formalization of "Incidence" (excluding cubic axioms), "Order" and "Congruence" (excluding point sequences) of the axioms constructed in this book. In addition, the theorem of the problem about the part that is treated implicitly and is not clearly stated in it is being carried out in parallel. [Regular_Tree_Relations] title = Regular Tree Relations author = Alexander Lochmann , Bertram Felgenhauer<>, Christian Sternagel , René Thiemann , Thomas Sternagel<> topic = Computer science/Automata and formal languages date = 2021-12-15 notify = alexander.lochmann@uibk.ac.at abstract = Tree automata have good closure properties and therefore a commonly used to prove/disprove properties. This formalization contains among other things the proofs of many closure properties of tree automata (anchored) ground tree transducers and regular relations. Additionally it includes the well known pumping lemma and a lifting of the Myhill Nerode theorem for regular languages to tree languages. We want to mention the existence of a tree automata APF-entry developed by Peter Lammich. His work is based on epsilon free top-down tree automata, while this entry builds on bottom-up tree auotamta with epsilon transitions. Moreover our formalization relies on the Collections Framework, also by Peter Lammich, to obtain efficient code. All proven constructions of the closure properties are exportable using the Isabelle/HOL code generation facilities. [Roth_Arithmetic_Progressions] title = Roth's Theorem on Arithmetic Progressions author = Chelsea Edmonds , Angeliki Koutsoukou-Argyraki , Lawrence C. Paulson topic = Mathematics/Graph theory, Mathematics/Combinatorics date = 2021-12-28 notify = lp15@cam.ac.uk abstract = We formalise a proof of Roth's Theorem on Arithmetic Progressions, a major result in additive combinatorics on the existence of 3-term arithmetic progressions in subsets of natural numbers. To this end, we follow a proof using graph regularity. We employ our recent formalisation of Szemerédi's Regularity Lemma, a major result in extremal graph theory, which we use here to prove the Triangle Counting Lemma and the Triangle Removal Lemma. Our sources are Yufei Zhao's MIT lecture notes "Graph Theory and Additive Combinatorics" (latest version here) and W.T. Gowers's Cambridge lecture notes "Topics in Combinatorics". We also refer to the University of Georgia notes by Stephanie Bell and Will Grodzicki, "Using Szemerédi's Regularity Lemma to Prove Roth's Theorem". [Gale_Shapley] title = Gale-Shapley Algorithm author = Tobias Nipkow topic = Computer science/Algorithms, Mathematics/Games and economics date = 2021-12-29 notify = nipkow@in.tum.de abstract = This is a stepwise refinement and proof of the Gale-Shapley stable matching (or marriage) algorithm down to executable code. Both a purely functional implementation based on lists and a functional implementation based on efficient arrays (provided by the Collections Framework in the AFP) are developed. The latter implementation runs in time O(n2) where n is the cardinality of the two sets to be matched. [Knights_Tour] title = Knight's Tour Revisited Revisited author = Lukas Koller topic = Mathematics/Graph theory date = 2022-01-04 notify = lukas.koller@tum.de abstract = This is a formalization of the article Knight's Tour Revisited by Cull and De Curtins where they prove the existence of a Knight's path for arbitrary n × m-boards with min(n,m) ≥ 5. If n · m is even, then there exists a Knight's circuit. A Knight's Path is a sequence of moves of a Knight on a chessboard s.t. the Knight visits every square of a chessboard exactly once. Finding a Knight's path is a an instance of the Hamiltonian path problem. A Knight's circuit is a Knight's path, where additionally the Knight can move from the last square to the first square of the path, forming a loop. During the formalization two mistakes in the original proof were discovered. These mistakes are corrected in this formalization. [Hyperdual] title = Hyperdual Numbers and Forward Differentiation author = Filip Smola <>, Jacques Fleuriot topic = Mathematics/Algebra, Mathematics/Analysis date = 2021-12-31 notify = f.smola@sms.ed.ac.uk, Jacques.Fleuriot@ed.ac.uk abstract =

Hyperdual numbers are ones with a real component and a number of infinitesimal components, usually written as $a_0 + a_1 \cdot \epsilon_1 + a_2 \cdot \epsilon_2 + a_3 \cdot \epsilon_1\epsilon_2$. They have been proposed by Fike and Alonso in an approach to automatic differentiation.

In this entry we formalise hyperdual numbers and their application to forward differentiation. We show them to be an instance of multiple algebraic structures and then, along with facts about twice-differentiability, we define what we call the hyperdual extensions of functions on real-normed fields. This extension formally represents the proposed way that the first and second derivatives of a function can be automatically calculated. We demonstrate it on the standard logistic function $f(x) = \frac{1}{1 + e^{-x}}$ and also reproduce the example analytic function $f(x) = \frac{e^x}{\sqrt{sin(x)^3 + cos(x)^3}}$ used for demonstration by Fike and Alonso.

[Median_Method] title = Median Method author = Emin Karayel topic = Mathematics/Probability theory date = 2022-01-25 notify = me@eminkarayel.de abstract =

The median method is an amplification result for randomized approximation algorithms described in [1]. Given an algorithm whose result is in a desired interval with a probability larger than 1/2, it is possible to improve the success probability, by running the algorithm multiple times independently and using the median. In contrast to using the mean, the amplification of the success probability grows exponentially with the number of independent runs.

This entry contains a formalization of the underlying theorem: Given a sequence of n independent random variables, which are in a desired interval with a probability 1/2 + a. Then their median will be in the desired interval with a probability of 1 − exp(−2a2 n). In particular, the success probability approaches 1 exponentially with the number of variables.

In addition to that, this entry also contains a proof that order-statistics of Borel-measurable random variables are themselves measurable and that generalized intervals in linearly ordered Borel-spaces are measurable.

[Irrationals_From_THEBOOK] title = Irrational numbers from THE BOOK author = Lawrence C Paulson topic = Mathematics/Number theory date = 2022-01-08 notify = lp15@cam.ac.uk abstract = An elementary proof is formalised: that exp r is irrational for every nonzero rational number r. The mathematical development comes from the well-known volume Proofs from THE BOOK, by Aigner and Ziegler, who credit the idea to Hermite. The development illustrates a number of basic Isabelle techniques: the manipulation of summations, the calculation of quite complicated derivatives and the estimation of integrals. We also see how to import another AFP entry (Stirling's formula). As for the theorem itself, note that a much stronger and more general result (the Hermite--Lindemann--Weierstraß transcendence theorem) is already available in the AFP. [Interpolation_Polynomials_HOL_Algebra] title = Interpolation Polynomials (in HOL-Algebra) author = Emin Karayel topic = Mathematics/Algebra date = 2022-01-29 notify = me@eminkarayel.de abstract =

A well known result from algebra is that, on any field, there is exactly one polynomial of degree less than n interpolating n points [1, §7].

This entry contains a formalization of the above result, as well as the following generalization in the case of finite fields F: There are |F|m-n polynomials of degree less than m ≥ n interpolating the same n points, where |F| denotes the size of the domain of the field. To establish the result the entry also includes a formalization of Lagrange interpolation, which might be of independent interest.

The formalized results are defined on the algebraic structures from HOL-Algebra, which are distinct from the type-class based structures defined in HOL. Note that there is an existing formalization for polynomial interpolation and, in particular, Lagrange interpolation by Thiemann and Yamada [2] on the type-class based structures in HOL.

[Quasi_Borel_Spaces] title = Quasi-Borel Spaces author = Michikazu Hirata <>, Yasuhiko Minamide , Tetsuya Sato topic = Computer science/Semantics date = 2022-02-03 notify = hirata.m.ac@m.titech.ac.jp, minamide@is.titech.ac.jp, tsato@c.titech.ac.jp abstract = The notion of quasi-Borel spaces was introduced by Heunen et al. The theory provides a suitable denotational model for higher-order probabilistic programming languages with continuous distributions. This entry is a formalization of the theory of quasi-Borel spaces, including construction of quasi-Borel spaces (product, coproduct, function spaces), the adjunction between the category of measurable spaces and the category of quasi-Borel spaces, and the probability monad on quasi-Borel spaces. This entry also contains the formalization of the Bayesian regression presented in the work of Heunen et al. This work is a part of the work by same authors, Program Logic for Higher-Order Probabilistic Programs in Isabelle/HOL, which will be published in the proceedings of the 16th International Symposium on Functional and Logic Programming (FLOPS 2022). [Youngs_Inequality] title = Young's Inequality for Increasing Functions author = Lawrence C Paulson topic = Mathematics/Analysis date = 2022-01-31 notify = lp15@cam.ac.uk abstract = Young's inequality states that $$ ab \leq \int_0^a f(x)dx + \int_0^b f^{-1}(y) dy $$ where $a\geq 0$, $b\geq 0$ and $f$ is strictly increasing and continuous. Its proof is formalised following the development by Cunningham and Grossman. Their idea is to make the intuitive, geometric folklore proof rigorous by reasoning about step functions. The lack of the Riemann integral makes the development longer than one would like, but their argument is reproduced faithfully. [LP_Duality] title = Duality of Linear Programming author = René Thiemann topic = Mathematics/Algebra date = 2022-02-03 notify = rene.thiemann@uibk.ac.at abstract = We formalize the weak and strong duality theorems of linear programming. For the strong duality theorem we provide three sufficient preconditions: both the primal problem and the dual problem are satisfiable, the primal problem is satisfiable and bounded, or the dual problem is satisfiable and bounded. The proofs are based on an existing formalization of Farkas' Lemma. [Equivalence_Relation_Enumeration] title = Enumeration of Equivalence Relations author = Emin Karayel topic = Mathematics/Combinatorics, Computer science/Algorithms/Mathematical date = 2022-02-04 notify = me@eminkarayel.de abstract =

This entry contains a formalization of an algorithm enumerating all equivalence relations on an initial segment of the natural numbers. The approach follows the method described by Stanton and White [5,§ 1.5] using restricted growth functions.

The algorithm internally enumerates restricted growth functions (as lists), whose equivalence kernels then form the equivalence relations. This has the advantage that the representation is compact and lookup of the relation reduces to a list lookup operation.

The algorithm can also be used within a proof and an example application is included, where a sequence of variables is split by the possible partitions they can form.

[FO_Theory_Rewriting] title = First-Order Theory of Rewriting author = Alexander Lochmann , Bertram Felgenhauer<> topic = Computer science/Automata and formal languages, Logic/Rewriting, Logic/Proof theory date = 2022-02-02 notify = alexander.lochmann@uibk.ac.at abstract = The first-order theory of rewriting (FORT) is a decidable theory for linear variable-separated rewrite systems. The decision procedure is based on tree automata technique and an inference system presented in "Certifying Proofs in the First-Order Theory of Rewriting". This AFP entry provides a formalization of the underlying decision procedure. Moreover it allows to generate a function that can verify each inference step via the code generation facility of Isabelle/HOL. Additionally it contains the specification of a certificate language (that allows to state proofs in FORT) and a formalized function that allows to verify the validity of the proof. This gives software tool authors, that implement the decision procedure, the possibility to verify their output. [VYDRA_MDL] title = Multi-Head Monitoring of Metric Dynamic Logic author = Martin Raszyk topic = Computer science/Algorithms date = 2022-02-13 notify = martin.raszyk@inf.ethz.ch abstract =

Runtime monitoring (or runtime verification) is an approach to checking compliance of a system's execution with a specification (e.g., a temporal formula). The system's execution is logged into a trace—a sequence of time-points, each consisting of a time-stamp and observed events. A monitor is an algorithm that produces verdicts on the satisfaction of a temporal formula on a trace.

We formalize the time-stamps as an abstract algebraic structure satisfying certain assumptions. Instances of this structure include natural numbers, real numbers, and lexicographic combinations of them. We also include the formalization of a conversion from the abstract time domain introduced by Koymans (1990) to our time-stamps.

We formalize a monitoring algorithm for metric dynamic logic, an extension of metric temporal logic with regular expressions. The monitor computes whether a given formula is satisfied at every position in an input trace of time-stamped events. Our monitor follows the multi-head paradigm: it reads the input simultaneously at multiple positions and moves its reading heads asynchronously. This mode of operation results in unprecedented time and space complexity guarantees for metric dynamic logic: The monitor's amortized time complexity to process a time-point and the monitor's space complexity neither depends on the event-rate, i.e., the number of events within a fixed time-unit, nor on the numeric constants occurring in the quantitative temporal constraints in the given formula.

The multi-head monitoring algorithm for metric dynamic logic is reported in our paper ``Multi-Head Monitoring of Metric Dynamic Logic'' published at ATVA 2020. We have also formalized unpublished specialized algorithms for the temporal operators of metric temporal logic.

extra-history = Change history: [2022-02-23]: added conversion from the abstract time domain by Koymans (1990) to our time domain; refactored assumptions on time domain (revision c9f94b0ae10e)
[Eval_FO] title = First-Order Query Evaluation author = Martin Raszyk topic = Logic/General logic/Classical first-order logic date = 2022-02-15 notify = m.raszyk@gmail.com abstract = We formalize first-order query evaluation over an infinite domain with equality. We first define the syntax and semantics of first-order logic with equality. Next we define a locale eval_fo abstracting a representation of a potentially infinite set of tuples satisfying a first-order query over finite relations. Inside the locale, we define a function eval checking if the set of tuples satisfying a first-order query over a database (an interpretation of the query's predicates) is finite (i.e., deciding relative safety) and computing the set of satisfying tuples if it is finite. Altogether the function eval solves capturability (Avron and Hirshfeld, 1991) of first-order logic with equality. We also use the function eval to prove a code equation for the semantics of first-order logic, i.e., the function checking if a first-order query over a database is satisfied by a variable assignment.
We provide an interpretation of the locale eval_fo based on the approach by Ailamazyan et al. A core notion in the interpretation is the active domain of a query and a database that contains all domain elements that occur in the database or interpret the query's constants. We prove the main theorem of Ailamazyan et al. relating the satisfaction of a first-order query over an infinite domain to the satisfaction of this query over a finite domain consisting of the active domain and a few additional domain elements (outside the active domain) whose number only depends on the query. In our interpretation of the locale eval_fo, we use a potentially higher number of the additional domain elements, but their number still only depends on the query and thus has no effect on the data complexity (Vardi, 1982) of query evaluation. Our interpretation yields an executable function eval. The time complexity of eval on a query is linear in the total number of tuples in the intermediate relations for the subqueries. Specifically, we build a database index to evaluate a conjunction. We also optimize the case of a negated subquery in a conjunction. Finally, we export code for the infinite domain of natural numbers. [Wetzels_Problem] title = Wetzel's Problem and the Continuum Hypothesis author = Lawrence C Paulson<> topic = Mathematics/Analysis, Logic/Set theory date = 2022-02-18 notify = lp15@cam.ac.uk abstract = Let $F$ be a set of analytic functions on the complex plane such that, for each $z\in\mathbb{C}$, the set $\{f(z) \mid f\in F\}$ is countable; must then $F$ itself be countable? The answer is yes if the Continuum Hypothesis is false, i.e., if the cardinality of $\mathbb{R}$ exceeds $\aleph_1$. But if CH is true then such an $F$, of cardinality $\aleph_1$, can be constructed by transfinite recursion. The formal proof illustrates reasoning about complex analysis (analytic and homomorphic functions) and set theory (transfinite cardinalities) in a single setting. The mathematical text comes from Proofs from THE BOOK by Aigner and Ziegler. [Universal_Hash_Families] title = Universal Hash Families author = Emin Karayel topic = Mathematics/Probability theory, Computer science/Algorithms date = 2022-02-20 notify = me@eminkarayel.de abstract = A k-universal hash family is a probability space of functions, which have uniform distribution and form k-wise independent random variables. They can often be used in place of classic (or cryptographic) hash functions and allow the rigorous analysis of the performance of randomized algorithms and data structures that rely on hash functions. In 1981 Wegman and Carter introduced a generic construction for such families with arbitrary k using polynomials over a finite field. This entry contains a formalization of them and establishes the property of k-universality. To be useful the formalization also provides an explicit construction of finite fields using the factor ring of integers modulo a prime. Additionally, some generic results about independent families are shown that might be of independent interest. [ResiduatedTransitionSystem] title = Residuated Transition Systems author = Eugene W. Stark topic = Computer science/Automata and formal languages, Computer science/Concurrency, Computer science/Programming languages/Lambda calculi date = 2022-02-28 notify = stark@cs.stonybrook.edu abstract =

A residuated transition system (RTS) is a transition system that is equipped with a certain partial binary operation, called residuation, on transitions. Using the residuation operation, one can express nuances, such as a distinction between nondeterministic and concurrent choice, as well as partial commutativity relationships between transitions, which are not captured by ordinary transition systems. A version of residuated transition systems was introduced in previous work by the author, in which they were called “concurrent transition systems” in view of the original motivation for their definition from the study of concurrency. In the first part of the present article, we give a formal development that generalizes and subsumes the original presentation. We give an axiomatic definition of residuated transition systems that assumes only a single partial binary operation as given structure. From the axioms, we derive notions of “arrow“ (transition), “source”, “target”, “identity”, as well as “composition” and “join” of transitions; thereby recovering structure that in the previous work was assumed as given. We formalize and generalize the result, that residuation extends from transitions to transition paths, and we systematically develop the properties of this extension. A significant generalization made in the present work is the identification of a general notion of congruence on RTS’s, along with an associated quotient construction.

In the second part of this article, we use the RTS framework to formalize several results in the theory of reduction in Church’s λ-calculus. Using a de Bruijn index-based syntax in which terms represent parallel reduction steps, we define residuation on terms and show that it satisfies the axioms for an RTS. An application of the results on paths from the first part of the article allows us to prove the classical Church-Rosser Theorem with little additional effort. We then use residuation to define the notion of “development” and we prove the Finite Developments Theorem, that every development is finite, formalizing and adapting to de Bruijn indices a proof by de Vrijer. We also use residuation to define the notion of a “standard reduction path”, and we prove the Standardization Theorem: that every reduction path is congruent to a standard one. As a corollary of the Standardization Theorem, we obtain the Leftmost Reduction Theorem: that leftmost reduction is a normalizing strategy.

[Ackermanns_not_PR] title = Ackermann's Function Is Not Primitive Recursive author = Lawrence C. Paulson topic = Logic/Computability date = 2022-03-23 notify = lp15@cam.ac.uk abstract = Ackermann's function is defined in the usual way and a number of its elementary properties are proved. Then, the primitive recursive functions are defined inductively: as a predicate on the functions that map lists of numbers to numbers. It is shown that every primitive recursive function is strictly dominated by Ackermann's function. The formalisation follows an earlier one by Nora Szasz. [Dedekind_Real] title = Constructing the Reals as Dedekind Cuts of Rationals author = Jacques D. Fleuriot<>, Lawrence C. Paulson<> topic = Mathematics/Analysis date = 2022-03-24 notify = lp15@cam.ac.uk abstract = The type of real numbers is constructed from the positive rationals using the method of Dedekind cuts. This development, briefly described in papers by the authors, follows the textbook presentation by Gleason. It's notable that the first formalisation of a significant piece of mathematics, by Jutting in 1977, involved a similar construction. [FOL_Seq_Calc3] title = A Naive Prover for First-Order Logic author = Asta Halkjær From topic = Logic/General logic/Classical first-order logic, Logic/Proof theory, Logic/General logic/Mechanization of proofs date = 2022-03-22 notify = ahfrom@dtu.dk abstract =

The AFP entry Abstract Completeness by Blanchette, Popescu and Traytel formalizes the core of Beth/Hintikka-style completeness proofs for first-order logic and can be used to formalize executable sequent calculus provers. In the Journal of Automated Reasoning, the authors instantiate the framework with a sequent calculus for first-order logic and prove its completeness. Their use of an infinite set of proof rules indexed by formulas yields very direct arguments. A fair stream of these rules controls the prover, making its definition remarkably simple. The AFP entry, however, only contains a toy example for propositional logic. The AFP entry A Sequent Calculus Prover for First-Order Logic with Functions by From and Jacobsen also uses the framework, but uses a finite set of generic rules resulting in a more sophisticated prover with more complicated proofs.

This entry contains an executable sequent calculus prover for first-order logic with functions in the style presented by Blanchette et al. The prover can be exported to Haskell and this entry includes formalized proofs of its soundness and completeness. The proofs are simpler than those for the prover by From and Jacobsen but the performance of the prover is significantly worse.

The included theory Fair-Stream first proves that the sequence of natural numbers 0, 0, 1, 0, 1, 2, etc. is fair. It then proves that mapping any surjective function across the sequence preserves fairness. This method of obtaining a fair stream of rules is similar to the one given by Blanchette et al. The concrete functions from natural numbers to terms, formulas and rules are defined using the Nat-Bijection theory in the HOL-Library.

[Prefix_Free_Code_Combinators] title = A Combinator Library for Prefix-Free Codes author = Emin Karayel topic = Computer science/Algorithms, Computer science/Data structures date = 2022-04-08 notify = me@eminkarayel.de abstract = This entry contains a set of binary encodings for primitive data types, such as natural numbers, integers, floating-point numbers as well as combinators to construct encodings for products, lists, sets or functions of/between such types. For natural numbers and integers, the entry contains various encodings, such as Elias-Gamma-Codes and exponential Golomb Codes, which are efficient variable-length codes in use by current compression formats. A use-case for this library is measuring the persisted size of a complex data structure without having to hand-craft a dedicated encoding for it, independent of Isabelle's internal representation. [Frequency_Moments] title = Formalization of Randomized Approximation Algorithms for Frequency Moments author = Emin Karayel topic = Computer science/Algorithms/Approximation, Mathematics/Probability theory date = 2022-04-08 notify = me@eminkarayel.de abstract = In 1999 Alon et. al. introduced the still active research topic of approximating the frequency moments of a data stream using randomized algorithms with minimal space usage. This includes the problem of estimating the cardinality of the stream elements - the zeroth frequency moment. But, also higher-order frequency moments that provide information about the skew of the data stream. (The k-th frequency moment of a data stream is the sum of the k-th powers of the occurrence counts of each element in the stream.) This entry formalizes three randomized algorithms for the approximation of F0, F2 and Fk for k ≥ 3 based on [1, 2] and verifies their expected accuracy, success probability and space usage. [Multiset_Ordering_NPC] title = The Generalized Multiset Ordering is NP-Complete author = René Thiemann , Lukas Schmidinger <> topic = Logic/Rewriting date = 2022-04-20 notify = rene.thiemann@uibk.ac.at abstract = We consider the problem of comparing two multisets via the generalized multiset ordering. We show that the corresponding decision problem is NP-complete. To be more precise, we encode multiset-comparisons into propositional formulas or into conjunctive normal forms of quadratic size; we further prove that satisfiability of conjunctive normal forms can be encoded as multiset-comparison problems of linear size. As a corollary, we also show that the problem of deciding whether two terms are related by a recursive path order is NP-hard, provided the recursive path order is based on the generalized multiset ordering. [Fishers_Inequality] title = Fisher's Inequality: Linear Algebraic Proof Techniques for Combinatorics author = Chelsea Edmonds, Lawrence C. Paulson <> topic = Mathematics/Combinatorics, Mathematics/Algebra date = 2022-04-21 notify = cle47@cam.ac.uk abstract = Linear algebraic techniques are powerful, yet often underrated tools in combinatorial proofs. This formalisation provides a library including matrix representations of incidence set systems, general formal proof techniques for the rank argument and linear bound argument, and finally a formalisation of a number of variations of the well-known Fisher's inequality. We build on our prior work formalising combinatorial design theory using a locale-centric approach, including extensions such as constant intersect designs and dual incidence systems. In addition to Fisher's inequality, we also formalise proofs on other incidence system properties using the incidence matrix representation, such as design existence, dual system relationships and incidence system isomorphisms. This formalisation is presented in the paper "Formalising Fisher's Inequality: Formal Linear Algebraic Techniques in Combinatorics", accepted to ITP 2022. [Clique_and_Monotone_Circuits] title = Clique is not solvable by monotone circuits of polynomial size author = René Thiemann topic = Mathematics/Combinatorics date = 2022-05-08 notify = rene.thiemann@uibk.ac.at abstract =

Given a graph $G$ with $n$ vertices and a number $s$, the decision problem Clique asks whether $G$ contains a fully connected subgraph with $s$ vertices. For this NP-complete problem there exists a non-trivial lower bound: no monotone circuit of a size that is polynomial in $n$ can solve Clique.

This entry provides an Isabelle/HOL formalization of a concrete lower bound (the bound is $\sqrt[7]{n}^{\sqrt[8]{n}}$ for the fixed choice of $s = \sqrt[4]{n}$), following a proof by Gordeev.

+[Pluennecke_Ruzsa_Inequality] +title = The Plünnecke-Ruzsa Inequality +author = Angeliki Koutsoukou-Argyraki , Lawrence C. Paulson <> +topic = Mathematics/Combinatorics +date = 2022-05-26 +notify = lp15@cam.ac.uk +abstract = + We formalise Plünnecke's inequality and the Plünnecke-Ruzsa + inequality, following the notes by Timothy Gowers: "Introduction + to Additive Combinatorics" (2022) for the University of + Cambridge. To this end, we first introduce basic definitions and prove + elementary facts on sumsets and difference sets. Then, we show two + versions of the Ruzsa triangle inequality. We follow with a proof due + to Petridis. + +[Rewrite_Properties_Reduction] +title = Reducing Rewrite Properties to Properties on Ground Terms +author = Alexander Lochmann +topic = Logic/Rewriting +date = 2022-06-02 +notify = alexander.lochmann@uibk.ac.at +abstract = + This AFP entry relates important rewriting properties between the set + of terms and the set of ground terms induced by a given signature. The + properties considered are confluence, strong/local confluence, the + normal form property, unique normal forms with respect to reduction + and conversion, commutation, conversion equivalence, and normalization + equivalence. + +[Finite_Fields] +title = Finite Fields +author = Emin Karayel +topic = Mathematics/Algebra +date = 2022-06-08 +notify = me@eminkarayel.de +abstract = + This entry formalizes the classification of the finite fields (also + called Galois fields): For each prime power $p^n$ there exists exactly + one (up to isomorphisms) finite field of that size and there are no + other finite fields. The derivation includes a formalization of the + characteristic of rings, the Frobenius endomorphism, formal + differentiation for polynomials in HOL-Algebra and Gauss' formula + for the number of monic irreducible polynomials over finite fields: \[ + \frac{1}{n} \sum_{d | n} \mu(d) p^{n/d} \textrm{.} \] The proofs are + based on the books from Ireland + and Rosen, as well as, Lidl and + Niederreiter. diff --git a/thys/Combinable_Wands/CombinableWands.thy b/thys/Combinable_Wands/CombinableWands.thy new file mode 100755 --- /dev/null +++ b/thys/Combinable_Wands/CombinableWands.thy @@ -0,0 +1,884 @@ +section \Combinable Magic Wands\ + +text \Note that, in this theory, assertions are represented as semantic assertions, i.e., as the set of states in which they hold.\ + +theory CombinableWands + imports PartialHeapSA +begin + +subsection \Definitions\ + +type_synonym sem_assertion = "state set" + +fun multiply :: "prat \ state \ state" where + "multiply p \ = Abs_state (multiply_mask p (get_m \), get_h \)" + +text \Because we work in an intuitionistic setting, a fraction of an assertion is defined using the upper-closure operator.\ + +fun multiply_sem_assertion :: "prat \ sem_assertion \ sem_assertion" where + "multiply_sem_assertion p P = PartialSA.upper_closure (multiply p ` P)" + +definition combinable :: "sem_assertion \ bool" where + "combinable P \ (\\ \. ppos \ \ ppos \ \ pgte pwrite (padd \ \) \ (multiply_sem_assertion \ P) \ (multiply_sem_assertion \ P) \ multiply_sem_assertion (padd \ \) P)" + +definition scaled where + "scaled \ = { multiply p \ |p. ppos p \ pgte pwrite p }" + +definition comp_min_mask :: "mask \ (mask \ mask)" where + "comp_min_mask b a hl = pmin (a hl) (comp_one (b hl))" + +definition scalable where + "scalable w a \ (\\ \ scaled w. \ a |#| \)" + +definition R where + "R a w = (if scalable w a then w else Abs_state (comp_min_mask (get_m a) (get_m w), get_h w))" + +definition cwand where + "cwand A B = { w |w. \a x. a \ A \ Some x = R a w \ a \ x \ B }" + +definition wand :: "sem_assertion \ sem_assertion \ sem_assertion" where + "wand A B = { w |w. \a x. a \ A \ Some x = w \ a \ x \ B }" + +definition intuitionistic where + "intuitionistic A \ (\a b. a \ b \ b \ A \ a \ A)" + +definition binary_mask :: "mask \ mask" where + "binary_mask \ l = (if \ l = pwrite then pwrite else pnone)" + +definition binary :: "sem_assertion \ bool" where + "binary A \ (\\ \ A. Abs_state (binary_mask (get_m \), get_h \) \ A)" + + + + +subsection Lemmas + + +lemma wand_equiv_def: + "wand A B = { \ |\. A \ {\} \ B }" +proof + show "wand A B \ {\ |\. A \ {\} \ B}" + proof + fix w assume "w \ wand A B" + have "A \ {w} \ B" + proof + fix x assume "x \ A \ {w}" + then show "x \ B" + using PartialSA.add_set_elem \w \ wand A B\ commutative wand_def by auto + qed + then show "w \ {\ |\. A \ {\} \ B}" + by simp + qed + show "{\ |\. A \ {\} \ B} \ wand A B" + proof + fix w assume "w \ {\ |\. A \ {\} \ B}" + have "\a x. a \ A \ Some x = w \ a \ x \ B" + proof - + fix a x assume "a \ A \ Some x = w \ a" + then have "x \ A \ {w}" + using PartialSA.add_set_elem PartialSA.commutative by auto + then show "x \ B" + using \w \ {\ |\. A \ {\} \ B}\ by blast + qed + then show "w \ wand A B" + using wand_def by force + qed +qed + +lemma w_in_scaled: + "w \ scaled w" +proof - + have "multiply pwrite w = w" + by (simp add: Rep_state_inverse mult_write_mask) + then show ?thesis + by (metis (mono_tags, lifting) half_between_0_1 half_plus_half mem_Collect_eq not_pgte_charact pgt_implies_pgte ppos_add scaled_def) +qed + +lemma non_scalable_instantiate: + assumes "\ scalable w a" + shows "\p. ppos p \ pgte pwrite p \ a |#| multiply p w" + using assms scalable_def scaled_def by auto + +lemma compatible_same_mask: + assumes "valid_mask (add_masks a w)" + shows "w = comp_min_mask a w" +proof (rule ext) + fix x + have "pgte pwrite (padd (a x) (w x))" + by (metis add_masks.simps assms valid_mask.elims(1)) + moreover have "padd (a x) (comp_one (a x)) = pwrite" + by (meson assms padd_comp_one upper_valid_aux valid_mask.elims(1)) + then have "pgte (comp_one (a x)) (w x)" + by (metis add_le_cancel_left calculation padd.rep_eq pgte.rep_eq) + then show "w x = comp_min_mask a w x" + by (metis comp_min_mask_def pmin_comm pmin_is) +qed + +lemma R_smaller: + "w \ R a w" +proof (cases "scalable w a") + case True + then show ?thesis + by (simp add: PartialSA.succ_refl R_def) +next + case False + then have "R a w = Abs_state (comp_min_mask (get_m a) (get_m w), get_h w)" + by (meson R_def) + moreover have "greater_mask (get_m w) (comp_min_mask (get_m a) (get_m w))" + proof (rule greater_maskI) + fix hl show "pgte (get_m w hl) (comp_min_mask (get_m a) (get_m w) hl)" + by (simp add: comp_min_mask_def pmin_greater) + qed + ultimately show ?thesis + by (metis Abs_state_cases larger_heap_refl Rep_state_cases Rep_state_inverse fst_conv get_h_m greaterI greater_mask_def mem_Collect_eq snd_conv valid_state_decompose) +qed + +lemma R_compatible_same: + assumes "a |#| w" + shows "R a w = w" +proof - + have "\ scalable w a" + using assms scalable_def w_in_scaled by blast + then have "R a w = Abs_state (comp_min_mask (get_m a) (get_m w), get_h w)" + using R_def by auto + then show ?thesis + by (metis PartialSA.defined_def Rep_state_inverse assms compatible_same_mask get_h.simps get_m.simps plus_ab_defined prod.collapse) +qed + +lemma in_cwand: + assumes "\a x. a \ A \ Some x = R a w \ a \ x \ B" + shows "w \ cwand A B" + using assms cwand_def by force + +lemma wandI: + assumes "\a x. a \ A \ Some x = a \ w \ x \ B" + shows "w \ wand A B" +proof - + have "A \ {w} \ B" + proof (rule subsetI) + fix x assume "x \ A \ {w}" + then obtain a where "Some x = a \ w" "a \ A" + using PartialSA.add_set_elem by auto + then show "x \ B" + using assms by blast + qed + then show ?thesis + using wand_equiv_def by force +qed + +lemma non_scalable_R_charact: + assumes "\ scalable w a" + shows "get_m (R a w) = comp_min_mask (get_m a) (get_m w) \ get_h (R a w) = get_h w" +proof - + have "R a w = Abs_state (comp_min_mask (get_m a) (get_m w), get_h w)" + using R_def assms by auto + moreover have "valid_state (comp_min_mask (get_m a) (get_m w), get_h w)" + proof (rule valid_stateI) + show "valid_mask (comp_min_mask (get_m a) (get_m w))" + proof (rule valid_maskI) + show "\f. comp_min_mask (get_m a) (get_m w) (null, f) = pnone" + by (metis (no_types, opaque_lifting) PartialSA.unit_neutral add_masks.simps comp_min_mask_def option.distinct(1) p_greater_exists padd_zero plus_ab_defined pmin_greater valid_mask.simps) + fix hl show "pgte pwrite (comp_min_mask (get_m a) (get_m w) hl)" + by (metis PartialSA.unit_neutral comp_min_mask_def greater_mask_def greater_mask_equiv_def option.distinct(1) plus_ab_defined pmin_greater upper_valid_aux valid_mask.simps) + qed + fix hl assume "ppos (comp_min_mask (get_m a) (get_m w) hl)" + show "get_h w hl \ None" + by (metis Rep_state \ppos (comp_min_mask (get_m a) (get_m w) hl)\ comp_min_mask_def get_h.simps get_pre(2) mem_Collect_eq p_greater_exists pmin_greater ppos_add prod.collapse valid_heap_def valid_state.simps) + qed + ultimately show ?thesis + by (metis Rep_state_cases Rep_state_inverse fst_conv get_h.simps get_m.simps mem_Collect_eq snd_conv) +qed + +lemma valid_bin: + "valid_state (binary_mask (get_m a), get_h a)" +proof (rule valid_stateI) + show "valid_mask (binary_mask (get_m a))" + by (metis PartialSA.unit_neutral binary_mask_def minus_empty option.discI plus_ab_defined unit_charact(2) valid_mask.elims(2) valid_mask.elims(3)) + show "\hl. ppos (binary_mask (get_m a) hl) \ get_h a hl \ None" + by (metis Rep_prat Rep_state binary_mask_def get_h.simps get_pre(2) leD mem_Collect_eq pnone.rep_eq ppos.rep_eq prod.collapse valid_heap_def valid_state.simps) +qed + +lemma in_multiply_sem: + assumes "x \ multiply_sem_assertion p A" + shows "\a \ A. x \ multiply p a" + using PartialSA.sep_algebra_axioms assms greater_def sep_algebra.upper_closure_def by fastforce + +lemma get_h_multiply: + assumes "pgte pwrite p" + shows "get_h (multiply p x) = get_h x" + using Abs_state_inverse assms multiply_valid by auto + +lemma in_multiply_refl: + assumes "x \ A" + shows "multiply p x \ multiply_sem_assertion p A" + using PartialSA.succ_refl PartialSA.upper_closure_def assms by fastforce + +lemma get_m_smaller: + assumes "pgte pwrite p" + shows "get_m (multiply p a) hl = pmult p (get_m a hl)" + using Abs_state_inverse assms multiply_mask_def multiply_valid by auto + +lemma get_m_smaller_mask: + assumes "pgte pwrite p" + shows "get_m (multiply p a) = multiply_mask p (get_m a)" + using Abs_state_inverse assms multiply_mask_def multiply_valid by auto + +lemma multiply_order: + assumes "pgte pwrite p" + and "a \ b" + shows "multiply p a \ multiply p b" +proof (rule greaterI) + show "larger_heap (get_h (multiply p a)) (get_h (multiply p b))" + using assms(1) assms(2) get_h_multiply larger_implies_larger_heap by presburger + show "greater_mask (get_m (multiply p a)) (get_m (multiply p b))" + by (metis assms(1) assms(2) get_m_smaller_mask greater_maskI larger_implies_greater_mask_hl mult_greater) +qed + +lemma multiply_twice: + assumes "pgte pwrite a \ pgte pwrite b" + shows "multiply a (multiply b x) = multiply (pmult a b) x" +proof - + have "get_h (multiply (pmult a b) x) = get_h x" + by (metis assms get_h_multiply p_greater_exists padd_asso pmult_order pmult_special(1)) + moreover have "get_h (multiply a (multiply b x)) = get_h x" + using assms get_h_multiply by presburger + moreover have "get_m (multiply a (multiply b x)) = get_m (multiply (pmult a b) x)" + proof (rule ext) + fix l + have "pgte pwrite (pmult a b)" using multiply_smaller_pwrite assms by simp + then have "get_m (multiply (pmult a b) x) l = pmult (pmult a b) (get_m x l)" + using get_m_smaller by blast + then show "get_m (multiply a (multiply b x)) l = get_m (multiply (pmult a b) x) l" + by (metis Rep_prat_inverse assms get_m_smaller mult.assoc pmult.rep_eq) + qed + ultimately show ?thesis + using state_ext by presburger +qed + +lemma valid_mask_add_comp_min: + assumes "valid_mask a" + and "valid_mask b" + shows "valid_mask (add_masks (comp_min_mask b a) b)" +proof (rule valid_maskI) + show "\f. add_masks (comp_min_mask b a) b (null, f) = pnone" + proof - + fix f + have "comp_min_mask b a (null, f) = pnone" + by (metis assms(1) comp_min_mask_def p_greater_exists padd_zero pmin_greater valid_mask.simps) + then show "add_masks (comp_min_mask b a) b (null, f) = pnone" + by (metis add_masks.simps assms(2) padd_zero valid_mask.simps) + qed + fix hl show "pgte pwrite (add_masks (comp_min_mask b a) b hl)" + proof (cases "pgte (a hl) (comp_one (b hl))") + case True + then have "add_masks (comp_min_mask b a) b hl = padd (comp_one (b hl)) (b hl)" + by (simp add: comp_min_mask_def pmin_is) + then have "add_masks (comp_min_mask b a) b hl = pwrite" + by (metis assms(2) padd_comm padd_comp_one valid_mask.simps) + then show ?thesis + by (simp add: pgte.rep_eq) + next + case False + then have "comp_min_mask b a hl = a hl" + by (metis comp_min_mask_def not_pgte_charact pgt_implies_pgte pmin_comm pmin_is) + then have "add_masks (comp_min_mask b a) b hl = padd (a hl) (b hl)" + by auto + moreover have "pgte (padd (comp_one (b hl)) (b hl)) (padd (a hl) (b hl))" + using False padd.rep_eq pgte.rep_eq by force + moreover have "padd (comp_one (b hl)) (b hl) = pwrite" + by (metis assms(2) padd_comm padd_comp_one valid_mask.simps) + ultimately show ?thesis by simp + qed +qed + + + +subsection \The combinable wand is stronger than the original wand\ + +lemma cwand_stronger: + "cwand A B \ wand A B" +proof + fix w assume asm0: "w \ cwand A B" + then have r: "\a x. a \ A \ Some x = R a w \ a \ x \ B" + using cwand_def by blast + show "w \ wand A B" + proof (rule wandI) + fix a x assume asm1: "a \ A \ Some x = a \ w" + then have "R a w = w" + by (metis PartialSA.defined_def R_compatible_same option.distinct(1)) + then show "x \ B" + by (metis PartialSA.commutative asm1 r) + qed +qed + + +subsection \The combinable wand is the same as the original wand when the left-hand side is binary\ + +lemma binary_same: + assumes "binary A" + and "intuitionistic B" + shows "wand A B \ cwand A B" +proof (rule subsetI) + fix w assume "w \ wand A B" + then have asm0: "A \ {w} \ B" + by (simp add: wand_equiv_def) + show "w \ cwand A B" + proof (rule in_cwand) + fix a x assume "a \ A \ Some x = R a w \ a" + show "x \ B" + proof (cases "scalable w a") + case True + then show ?thesis + by (metis PartialSA.commutative PartialSA.defined_def R_def \a \ A \ Some x = R a w \ a\ option.distinct(1) scalable_def w_in_scaled) + next + case False + then have "get_m (R a w) = comp_min_mask (get_m a) (get_m w) \ get_h (R a w) = get_h w" + using non_scalable_R_charact by blast + moreover have "Abs_state (binary_mask (get_m a), get_h a) \ A" + using \a \ A \ Some x = R a w \ a\ assms(1) binary_def by blast + moreover have "greater_mask (add_masks (comp_min_mask (get_m a) (get_m w)) (get_m a)) + (add_masks (binary_mask (get_m a)) (get_m w))" + proof (rule greater_maskI) + fix hl show "pgte (add_masks (comp_min_mask (get_m a) (get_m w)) (get_m a) hl) (add_masks (binary_mask (get_m a)) (get_m w) hl)" + proof (cases "get_m a hl = pwrite") + case True + obtain \ where "\ \ scaled w" "a |#| \" using False scalable_def[of w a] + by blast + then obtain p where "ppos p" "pgte pwrite p" "multiply p w |#| a" + using PartialSA.commutative PartialSA.defined_def mem_Collect_eq scaled_def by auto + have "get_m w hl = pnone" + proof (rule ccontr) + assume "get_m w hl \ pnone" + then have "ppos (get_m w hl)" + by (metis less_add_same_cancel1 not_pgte_charact p_greater_exists padd.rep_eq padd_zero pgt.rep_eq ppos.rep_eq) + moreover have "get_m (multiply p \) = multiply_mask p (get_m \)" + using multiply_valid[of p \] multiply.simps[of p \] + by (metis Rep_state_cases Rep_state_inverse \pgte pwrite p\ fst_conv get_pre(2) mem_Collect_eq) + then have "ppos (get_m (multiply p w) hl)" using pmult_ppos + by (metis Rep_state_cases Rep_state_inverse \pgte pwrite p\ \ppos p\ calculation fst_conv get_pre(2) mem_Collect_eq multiply.simps multiply_mask_def multiply_valid) + then have "pgt (padd (get_m (multiply p w) hl) (get_m a hl)) pwrite" + by (metis True add_le_same_cancel2 leD not_pgte_charact padd.rep_eq pgte.rep_eq ppos.rep_eq) + then have "\ valid_mask (add_masks (get_m (multiply p w)) (get_m a))" + by (metis add_masks.elims not_pgte_charact valid_mask.elims(1)) + then show False + using PartialSA.defined_def \multiply p w |#| a\ plus_ab_defined by blast + qed + then show ?thesis + by (metis Rep_prat_inverse add.right_neutral add_masks.simps binary_mask_def p_greater_exists padd.rep_eq padd_comm pnone.rep_eq) + next + case False + then have "add_masks (binary_mask (get_m a)) (get_m w) hl = get_m w hl" + by (metis Rep_prat_inject add.right_neutral add_masks.simps binary_mask_def padd.rep_eq padd_comm pnone.rep_eq) + then show ?thesis + proof (cases "pgte (get_m w hl) (comp_one (get_m a hl))") + case True + then have "comp_min_mask (get_m a) (get_m w) hl = comp_one (get_m a hl)" + using comp_min_mask_def pmin_is by presburger + then have "add_masks (comp_min_mask (get_m a) (get_m w)) (get_m a) hl = pwrite" + by (metis PartialSA.unit_neutral add_masks.simps add_masks_comm minus_empty option.distinct(1) padd_comp_one plus_ab_defined unit_charact(2) valid_mask.simps) + then show ?thesis + by (metis PartialSA.unit_neutral \add_masks (binary_mask (get_m a)) (get_m w) hl = get_m w hl\ minus_empty option.distinct(1) plus_ab_defined unit_charact(2) valid_mask.simps) + next + case False + then have "comp_min_mask (get_m a) (get_m w) hl = get_m w hl" + by (metis comp_min_mask_def not_pgte_charact pgt_implies_pgte pmin_comm pmin_is) + then show ?thesis + using \add_masks (binary_mask (get_m a)) (get_m w) hl = get_m w hl\ p_greater_exists by auto + qed + qed + qed + then have "valid_mask (add_masks (binary_mask (get_m a)) (get_m w))" + by (metis \a \ A \ Some x = R a w \ a\ calculation(1) greater_mask_def option.distinct(1) plus_ab_defined upper_valid_aux) + moreover have "compatible_heaps (get_h a) (get_h w)" + by (metis PartialSA.commutative \a \ A \ Some x = R a w \ a\ \get_m (R a w) = comp_min_mask (get_m a) (get_m w) \ get_h (R a w) = get_h w\ option.simps(3) plus_ab_defined) + then obtain xx where "Some xx = Abs_state (binary_mask (get_m a), get_h a) \ w" + using Abs_state_inverse calculation compatible_def fst_conv plus_def valid_bin by auto + then have "xx \ B" using asm0 + by (meson PartialSA.add_set_elem \Abs_state (binary_mask (get_m a), get_h a) \ A\ singletonI subset_iff) + moreover have "x \ xx" + proof (rule greaterI) + show "greater_mask (get_m x) (get_m xx)" + using Abs_state_inverse \Some xx = Abs_state (binary_mask (get_m a), get_h a) \ w\ \a \ A \ Some x = R a w \ a\ \greater_mask (add_masks (comp_min_mask (get_m a) (get_m w)) (get_m a)) (add_masks (binary_mask (get_m a)) (get_m w))\ calculation(1) plus_charact(1) valid_bin by auto + show "larger_heap (get_h x) (get_h xx)" + proof (rule larger_heapI) + fix hl xa assume "get_h xx hl = Some xa" + then show "get_h x hl = Some xa" + by (metis PartialSA.commutative Rep_state_cases Rep_state_inverse \Some xx = Abs_state (binary_mask (get_m a), get_h a) \ w\ \a \ A \ Some x = R a w \ a\ calculation(1) get_h.simps mem_Collect_eq plus_charact(2) snd_conv valid_bin) + qed + qed + ultimately show ?thesis + using assms(2) intuitionistic_def by blast + qed + qed +qed + + +subsection \The combinable wand is combinable\ + +lemma combinableI: + assumes "\a b. ppos a \ ppos b \ padd a b = pwrite \ (multiply_sem_assertion a (cwand A B)) \ (multiply_sem_assertion b (cwand A B)) \ cwand A B" + shows "combinable (cwand A B)" +proof - + have "\a b. ppos a \ ppos b \ pgte pwrite (padd a b) \ (multiply_sem_assertion a (cwand A B)) \ (multiply_sem_assertion b (cwand A B)) \ multiply_sem_assertion (padd a b) (cwand A B)" + proof - + fix a b assume asm0: "ppos a \ ppos b \ pgte pwrite (padd a b)" + then have "pgte pwrite a \ pgte pwrite b" + using padd.rep_eq pgte.rep_eq ppos.rep_eq by auto + show "(multiply_sem_assertion a (cwand A B)) \ (multiply_sem_assertion b (cwand A B)) \ multiply_sem_assertion (padd a b) (cwand A B)" + proof + fix x assume "x \ multiply_sem_assertion a (cwand A B) \ multiply_sem_assertion b (cwand A B)" + then obtain xa xb where "Some x = xa \ xb" "xa \ multiply_sem_assertion a (cwand A B)" "xb \ multiply_sem_assertion b (cwand A B)" + by (meson PartialSA.add_set_elem) + then obtain wa wb where "wa \ cwand A B" "wb \ cwand A B" "xa \ multiply a wa" "xb \ multiply b wb" + by (meson in_multiply_sem) + let ?a = "pdiv a (padd a b)" + let ?b = "pdiv b (padd a b)" + have "pgte pwrite ?a \ pgte pwrite ?b" + using asm0 p_greater_exists padd_comm pdiv_smaller ppos_add by blast + have "multiply ?a wa |#| multiply ?b wb" + proof (rule compatibleI) + show "compatible_heaps (get_h (multiply (pdiv a (padd a b)) wa)) (get_h (multiply (pdiv b (padd a b)) wb))" + proof - + have "compatible_heaps (get_h (multiply a wa)) (get_h (multiply b wb))" + by (metis PartialSA.asso2 PartialSA.asso3 PartialSA.greater_equiv PartialSA.minus_some \Some x = xa \ xb\ \xa \ multiply a wa\ \xb \ multiply b wb\ option.simps(3) plus_ab_defined) + moreover have "get_h (multiply (pdiv a (padd a b)) wa) = get_h (multiply a wa) \ get_h (multiply (pdiv b (padd a b)) wb) = get_h (multiply b wb)" + proof - + have "pgte pwrite a \ pgte pwrite b" + by (metis asm0 p_greater_exists padd_asso padd_comm) + moreover have "pgte pwrite ?a \ pgte pwrite ?b" + using asm0 p_greater_exists padd_comm pdiv_smaller ppos_add by blast + ultimately show ?thesis + using get_h_multiply by presburger + qed + then show ?thesis + using calculation by presburger + qed + show "valid_mask (add_masks (get_m (multiply (pdiv a (padd a b)) wa)) (get_m (multiply (pdiv b (padd a b)) wb)))" + proof (rule valid_maskI) + show "\f. add_masks (get_m (multiply (pdiv a (padd a b)) wa)) (get_m (multiply (pdiv b (padd a b)) wb)) (null, f) = pnone" + by (metis PartialSA.unit_neutral add_masks_equiv_valid_null option.distinct(1) plus_ab_defined valid_mask.simps valid_null_def) + fix hl have "add_masks (get_m (multiply (pdiv a (padd a b)) wa)) (get_m (multiply (pdiv b (padd a b)) wb)) hl + = padd (pmult ?a (get_m wa hl)) (pmult ?b (get_m wb hl))" + proof - + have "get_m (multiply ?a wa) hl = pmult ?a (get_m wa hl)" + using Abs_state_inverse \pgte pwrite (pdiv a (padd a b)) \ pgte pwrite (pdiv b (padd a b))\ multiply_mask_def multiply_valid by auto + moreover have "get_m (multiply ?b wb) hl = pmult ?b (get_m wb hl)" + using Abs_state_inverse \pgte pwrite (pdiv a (padd a b)) \ pgte pwrite (pdiv b (padd a b))\ multiply_mask_def multiply_valid by auto + ultimately show ?thesis by simp + qed + moreover have "pgte pwrite (padd (pmult ?a (get_m wa hl)) (pmult ?b (get_m wb hl)))" + proof (rule padd_one_ineq_sum) + show "pgte pwrite (get_m wa hl)" + by (metis PartialSA.unit_neutral option.discI plus_ab_defined upper_valid_aux valid_mask.simps) + show "pgte pwrite (get_m wb hl)" + by (metis PartialSA.unit_neutral option.discI plus_ab_defined upper_valid_aux valid_mask.simps) + show "padd (pdiv a (padd a b)) (pdiv b (padd a b)) = pwrite" + using asm0 sum_coeff by blast + qed + ultimately show "pgte pwrite (add_masks (get_m (multiply (pdiv a (padd a b)) wa)) (get_m (multiply (pdiv b (padd a b)) wb)) hl)" + by presburger + qed + qed + then obtain xx where "Some xx = multiply ?a wa \ multiply ?b wb" + using PartialSA.defined_def by auto + moreover have "(multiply_sem_assertion ?a (cwand A B)) \ (multiply_sem_assertion ?b (cwand A B)) \ cwand A B" + proof (rule assms) + show "ppos (pdiv a (padd a b)) \ ppos (pdiv b (padd a b)) \ padd (pdiv a (padd a b)) (pdiv b (padd a b)) = pwrite" + using asm0 padd.rep_eq pdiv.rep_eq ppos.rep_eq sum_coeff by auto + qed + ultimately have "xx \ cwand A B" + proof - + have "multiply ?a wa \ multiply_sem_assertion ?a (cwand A B)" + using \wa \ cwand A B\ in_multiply_refl by presburger + moreover have "multiply ?b wb \ multiply_sem_assertion ?b (cwand A B)" + by (meson \wb \ cwand A B\ in_multiply_refl) + ultimately show ?thesis + using PartialSA.add_set_def \Some xx = multiply (pdiv a (padd a b)) wa \ multiply (pdiv b (padd a b)) wb\ \multiply_sem_assertion (pdiv a (padd a b)) (cwand A B) \ multiply_sem_assertion (pdiv b (padd a b)) (cwand A B) \ cwand A B\ by fastforce + qed + moreover have "x \ multiply (padd a b) xx" + proof (rule greaterI) + have "valid_state (multiply_mask (padd a b) (get_m xx), get_h xx)" + using asm0 multiply_valid by blast + show "larger_heap (get_h x) (get_h (multiply (padd a b) xx))" + proof - + have "get_h (multiply (padd a b) xx) = get_h xx" + using asm0 get_h_multiply by blast + moreover have "get_h xx = get_h wa ++ get_h wb" + by (metis \Some xx = multiply (pdiv a (padd a b)) wa \ multiply (pdiv b (padd a b)) wb\ asm0 get_h_multiply p_greater_exists padd_comm plus_charact(2) sum_coeff) + moreover have "get_h x = get_h xa ++ get_h xb" + using \Some x = xa \ xb\ plus_charact(2) by presburger + moreover have "get_h wa = get_h (multiply a wa) \ get_h wb = get_h (multiply b wb)" + by (metis asm0 get_h_multiply order_trans p_greater_exists padd_comm pgte.rep_eq) + moreover have "larger_heap (get_h xa) (get_h wa) \ larger_heap (get_h xb) (get_h wb)" + using \xa \ multiply a wa\ \xb \ multiply b wb\ calculation(4) larger_implies_larger_heap by presburger + ultimately show ?thesis + by (metis \Some x = xa \ xb\ larger_heaps_sum_ineq option.simps(3) plus_ab_defined) + qed + show "greater_mask (get_m x) (get_m (multiply (padd a b) xx))" + proof (rule greater_maskI) + fix hl + have "pgte (get_m x hl) (padd (get_m xa hl) (get_m xb hl))" + using \Some x = xa \ xb\ pgte.rep_eq plus_charact(1) by auto + moreover have "pgte (get_m xa hl) (get_m (multiply a wa) hl) \ pgte (get_m xb hl) (get_m (multiply b wb) hl)" + using \xa \ multiply a wa\ \xb \ multiply b wb\ larger_implies_greater_mask_hl by blast + moreover have "get_m (multiply (padd a b) xx) hl = pmult (padd a b) (get_m xx hl)" + by (metis Rep_state_cases Rep_state_inverse \valid_state (multiply_mask (padd a b) (get_m xx), get_h xx)\ fst_conv get_pre(2) mem_Collect_eq multiply.simps multiply_mask_def) + moreover have "... = padd (pmult (pmult (padd a b) ?a) (get_m wa hl)) (pmult (pmult (padd a b) ?b) (get_m wb hl))" + proof - + have "get_m (multiply ?a wa) hl = pmult ?a (get_m wa hl)" + by (metis Abs_state_inverse asm0 fst_conv get_pre(2) mem_Collect_eq multiply.simps multiply_mask_def multiply_valid p_greater_exists sum_coeff) + moreover have "get_m (multiply ?b wb) hl = pmult ?b (get_m wb hl)" + by (metis Abs_state_inverse asm0 fst_conv get_pre(2) mem_Collect_eq multiply.simps multiply_mask_def multiply_valid p_greater_exists padd_comm pdiv_smaller ppos_add) + ultimately have "get_m xx hl = padd (pmult ?a (get_m wa hl)) (pmult ?b (get_m wb hl))" + using \Some xx = multiply (pdiv a (padd a b)) wa \ multiply (pdiv b (padd a b)) wb\ plus_charact(1) by fastforce + then show ?thesis + by (simp add: pmult_padd) + qed + moreover have "... = padd (pmult a (get_m wa hl)) (pmult b (get_m wb hl))" + using asm0 pmult_pdiv_cancel ppos_add by presburger + moreover have "get_m (multiply a wa) hl = pmult a (get_m wa hl) \ get_m (multiply b wb) hl = pmult b (get_m wb hl)" + proof - + have "valid_mask (multiply_mask a (get_m wa))" + using asm0 mult_add_states multiply_valid upper_valid_aux valid_state.simps by blast + moreover have "valid_mask (multiply_mask b (get_m wb))" + using asm0 mult_add_states multiply_valid upper_valid valid_state.simps by blast + ultimately show ?thesis + by (metis (no_types, lifting) Abs_state_inverse asm0 fst_conv get_pre(2) mem_Collect_eq multiply.simps multiply_mask_def multiply_valid order_trans p_greater_exists padd_comm pgte.rep_eq) + qed + ultimately show "pgte (get_m x hl) (get_m (multiply (padd a b) xx) hl)" + by (simp add: padd.rep_eq pgte.rep_eq) + qed + qed + ultimately show "x \ multiply_sem_assertion (padd a b) (cwand A B)" + by (metis PartialSA.up_closed_def PartialSA.upper_closure_up_closed in_multiply_refl multiply_sem_assertion.simps) + qed + qed + then show ?thesis + using combinable_def by presburger +qed + +lemma combinable_cwand: + assumes "combinable B" + and "intuitionistic B" + shows "combinable (cwand A B)" +proof (rule combinableI) + fix \ \ assume asm0: "ppos \ \ ppos \ \ padd \ \ = pwrite" + then have "pgte pwrite \ \ pgte pwrite \" + by (metis p_greater_exists padd_comm) + show "multiply_sem_assertion \ (cwand A B) \ multiply_sem_assertion \ (cwand A B) \ cwand A B" + proof + fix w assume "w \ multiply_sem_assertion \ (cwand A B) \ multiply_sem_assertion \ (cwand A B)" + then obtain xa xb where "Some w = xa \ xb" "xa \ multiply_sem_assertion \ (cwand A B)" "xb \ multiply_sem_assertion \ (cwand A B)" + by (meson PartialSA.add_set_elem) + then obtain wa wb where "wa \ cwand A B" "wb \ cwand A B" "xa \ multiply \ wa" "xb \ multiply \ wb" + by (meson in_multiply_sem) + then obtain r: "\a x. a \ A \ Some x = R a wa \ a \ x \ B" "\a x. a \ A \ Some x = R a wb \ a \ x \ B" + using cwand_def by blast + show "w \ cwand A B" + proof (rule in_cwand) + fix a x assume asm1: "a \ A \ Some x = R a w \ a" + have "\ scalable w a" + proof (rule ccontr) + assume "\ \ scalable w a" + then have "R a w = w \ \ a |#| R a w" + by (simp add: R_def scalable_def w_in_scaled) + then show False + using PartialSA.commutative PartialSA.defined_def asm1 by auto + qed + then have "get_h (R a w) = get_h w \ get_m (R a w) = comp_min_mask (get_m a) (get_m w)" + using non_scalable_R_charact by blast + moreover obtain p where "a |#| multiply p w" "ppos p \ pgte pwrite p" + using \\ scalable w a\ non_scalable_instantiate by blast + moreover have "\ scalable wa a" + proof - + have "a |#| multiply (pmult \ p) wa" + proof - + have "w \ xa" using \Some w = xa \ xb\ using PartialSA.greater_def by blast + then have "multiply p w \ multiply p xa" + using calculation(3) multiply_order by blast + then have "multiply p w \ multiply (pmult \ p) wa" + proof - + have "multiply p w \ multiply p (multiply \ wa)" + using PartialSA.succ_trans \w \ xa\ \xa \ multiply \ wa\ calculation(3) multiply_order by blast + then show ?thesis + using \pgte pwrite \ \ pgte pwrite \\ calculation(3) multiply_twice pmult_comm by auto + qed + then show ?thesis + using PartialSA.asso3 PartialSA.defined_def PartialSA.minus_some calculation(2) by fastforce + qed + moreover have "ppos (pmult \ p) \ pgte pwrite (pmult \ p)" + by (metis Rep_prat_inverse \ppos p \ pgte pwrite p\ add.right_neutral asm0 dual_order.strict_iff_order padd.rep_eq pgte.rep_eq pmult_comm pmult_ppos pmult_special(2) pnone.rep_eq ppos.rep_eq ppos_eq_pnone padd_one_ineq_sum) + ultimately show ?thesis + using scalable_def scaled_def by auto + qed + then have "get_h (R a wa) = get_h wa \ get_m (R a wa) = comp_min_mask (get_m a) (get_m wa)" + using non_scalable_R_charact by blast + moreover have "R a wa |#| a" + proof (rule compatibleI) + have "larger_heap (get_h w) (get_h xa) \ larger_heap (get_h xa) (get_h wa)" + by (metis PartialSA.commutative PartialSA.greater_equiv \Some w = xa \ xb\ \pgte pwrite \ \ pgte pwrite \\ \xa \ multiply \ wa\ get_h_multiply larger_implies_larger_heap) + then show "compatible_heaps (get_h (R a wa)) (get_h a)" + by (metis asm1 calculation(1) calculation(4) larger_heap_comp option.distinct(1) plus_ab_defined) + show "valid_mask (add_masks (get_m (R a wa)) (get_m a))" + by (metis PartialSA.unit_neutral calculation(4) minus_empty option.distinct(1) plus_ab_defined unit_charact(2) valid_mask_add_comp_min) + qed + then obtain ba where "Some ba = R a wa \ a" + using PartialSA.defined_def by auto + + moreover have "\ scalable wb a" + proof - + have "a |#| multiply (pmult \ p) wb" + proof - + have "w \ xb" using \Some w = xa \ xb\ + using PartialSA.greater_equiv by blast + then have "multiply p w \ multiply p xb" + using calculation(3) multiply_order by blast + then have "multiply p w \ multiply (pmult \ p) wb" + proof - + have "multiply p w \ multiply p (multiply \ wb)" + using PartialSA.succ_trans \w \ xb\ \xb \ multiply \ wb\ calculation(3) multiply_order by blast + then show ?thesis + using \pgte pwrite \ \ pgte pwrite \\ calculation(3) multiply_twice pmult_comm by auto + qed + then show ?thesis + using PartialSA.asso3 PartialSA.defined_def PartialSA.minus_some calculation(2) by fastforce + qed + moreover have "ppos (pmult \ p) \ pgte pwrite (pmult \ p)" + by (simp add: \pgte pwrite \ \ pgte pwrite \\ \ppos p \ pgte pwrite p\ asm0 multiply_smaller_pwrite pmult_ppos) + ultimately show ?thesis + using scalable_def scaled_def by auto + qed + then have "get_h (R a wb) = get_h wb \ get_m (R a wb) = comp_min_mask (get_m a) (get_m wb)" + using non_scalable_R_charact by blast + moreover have "R a wb |#| a" + proof (rule compatibleI) + have "larger_heap (get_h w) (get_h xb) \ larger_heap (get_h xb) (get_h wb)" + using \Some w = xa \ xb\ \pgte pwrite \ \ pgte pwrite \\ \xb \ multiply \ wb\ get_h_multiply larger_heap_def larger_implies_larger_heap plus_charact(2) by fastforce + then show "compatible_heaps (get_h (R a wb)) (get_h a)" + by (metis asm1 calculation(1) calculation(6) larger_heap_comp option.simps(3) plus_ab_defined) + show "valid_mask (add_masks (get_m (R a wb)) (get_m a))" + by (metis PartialSA.unit_neutral calculation(6) minus_empty option.distinct(1) plus_ab_defined unit_charact(2) valid_mask_add_comp_min) + qed + then obtain bb where "Some bb = R a wb \ a" + using PartialSA.defined_def by auto + + moreover obtain ya where "Some ya = R a wa \ a" + using calculation(5) by auto + then have "ya \ B" + using asm1 r(1) by blast + then have "multiply \ ya \ multiply_sem_assertion \ B" + using in_multiply_refl by blast + moreover obtain yb where "Some yb = R a wb \ a" + using calculation(7) by auto + then have "yb \ B" + using asm1 r(2) by blast + then have "multiply \ yb \ multiply_sem_assertion \ B" + using in_multiply_refl by blast + moreover have "(multiply \ ya) |#| (multiply \ yb)" + proof (rule compatibleI) + have "get_h ya = get_h wa ++ get_h a" + using \Some ya = R a wa \ a\ \get_h (R a wa) = get_h wa \ get_m (R a wa) = comp_min_mask (get_m a) (get_m wa)\ plus_charact(2) by presburger + then have "get_h (multiply \ ya) = get_h wa ++ get_h a" + using \pgte pwrite \ \ pgte pwrite \\ get_h_multiply by presburger + moreover have "get_h yb = get_h wb ++ get_h a" + using \Some yb = R a wb \ a\ \get_h (R a wb) = get_h wb \ get_m (R a wb) = comp_min_mask (get_m a) (get_m wb)\ plus_charact(2) by presburger + then have "get_h (multiply \ yb) = get_h wb ++ get_h a" + using \pgte pwrite \ \ pgte pwrite \\ get_h_multiply by presburger + moreover have "compatible_heaps (get_h wa) (get_h wb)" + proof (rule compatible_heapsI) + fix hl a b assume "get_h wa hl = Some a" "get_h wb hl = Some b" + then have "get_h xa hl = Some a" "get_h xb hl = Some b" + apply (metis (full_types) \pgte pwrite \ \ pgte pwrite \\ \xa \ multiply \ wa\ get_h_multiply larger_heap_def larger_implies_larger_heap) + by (metis \get_h wb hl = Some b\ \pgte pwrite \ \ pgte pwrite \\ \xb \ multiply \ wb\ get_h_multiply larger_heap_def larger_implies_larger_heap) + moreover have "compatible_heaps (get_h xa) (get_h xb)" + by (metis \Some w = xa \ xb\ option.simps(3) plus_ab_defined) + ultimately show "a = b" + by (metis compatible_heaps_def compatible_options.simps(1)) + qed + ultimately show "compatible_heaps (get_h (multiply \ ya)) (get_h (multiply \ yb))" + by (metis PartialSA.commutative PartialSA.core_is_smaller \Some ya = R a wa \ a\ \Some yb = R a wb \ a\ \get_h (R a wa) = get_h wa \ get_m (R a wa) = comp_min_mask (get_m a) (get_m wa)\ \get_h (R a wb) = get_h wb \ get_m (R a wb) = comp_min_mask (get_m a) (get_m wb)\ compatible_heaps_sum core_defined(1) core_defined(2) option.distinct(1) plus_ab_defined) + show "valid_mask (add_masks (get_m (multiply \ ya)) (get_m (multiply \ yb)))" + proof (rule valid_maskI) + show "\f. add_masks (get_m (multiply \ ya)) (get_m (multiply \ yb)) (null, f) = pnone" + by (metis (no_types, opaque_lifting) PartialSA.core_is_smaller add_masks.simps core_defined(2) minus_empty not_None_eq plus_ab_defined valid_mask.simps) + fix hl + have "add_masks (get_m (multiply \ ya)) (get_m (multiply \ yb)) hl = padd (pmult \ (get_m ya hl)) (pmult \ (get_m yb hl))" + using \pgte pwrite \ \ pgte pwrite \\ get_m_smaller by auto + moreover have "get_m ya hl = padd (get_m (R a wa) hl) (get_m a hl) \ get_m yb hl = padd (get_m (R a wb) hl) (get_m a hl)" + using \Some ya = R a wa \ a\ \Some yb = R a wb \ a\ plus_charact(1) by auto + ultimately show "pgte pwrite (add_masks (get_m (multiply \ ya)) (get_m (multiply \ yb)) hl)" + by (metis PartialSA.unit_neutral asm0 option.distinct(1) padd_one_ineq_sum plus_ab_defined plus_charact(1) valid_mask.simps) + qed + qed + then obtain y where "Some y = multiply \ ya \ multiply \ yb" + using PartialSA.defined_def by auto + moreover have "x \ y" + proof (rule greaterI) + have "get_h y = get_h ya ++ get_h yb" + using \pgte pwrite \ \ pgte pwrite \\ calculation(10) get_h_multiply plus_charact(2) by presburger + moreover have "get_h ya = get_h wa ++ get_h a" + using \Some ya = R a wa \ a\ \get_h (R a wa) = get_h wa \ get_m (R a wa) = comp_min_mask (get_m a) (get_m wa)\ plus_charact(2) by presburger + moreover have "get_h yb = get_h wb ++ get_h a" + using \Some yb = R a wb \ a\ \get_h (R a wb) = get_h wb \ get_m (R a wb) = comp_min_mask (get_m a) (get_m wb)\ plus_charact(2) by presburger + moreover have "larger_heap (get_h x) (get_h wa)" + proof - + have "larger_heap (get_h x) (get_h xa)" + by (metis PartialSA.greater_def \Some w = xa \ xb\ \get_h (R a w) = get_h w \ get_m (R a w) = comp_min_mask (get_m a) (get_m w)\ asm1 larger_heap_trans larger_implies_larger_heap) + moreover have "larger_heap (get_h xa) (get_h wa)" + by (metis \pgte pwrite \ \ pgte pwrite \\ \xa \ multiply \ wa\ get_h_multiply larger_implies_larger_heap) + ultimately show ?thesis + using larger_heap_trans by blast + qed + moreover have "larger_heap (get_h x) (get_h wb)" + proof - + have "larger_heap (get_h x) (get_h xb)" + by (metis PartialSA.greater_def PartialSA.greater_equiv \Some w = xa \ xb\ \get_h (R a w) = get_h w \ get_m (R a w) = comp_min_mask (get_m a) (get_m w)\ asm1 larger_heap_trans larger_implies_larger_heap) + moreover have "larger_heap (get_h xb) (get_h wb)" + by (metis \pgte pwrite \ \ pgte pwrite \\ \xb \ multiply \ wb\ get_h_multiply larger_implies_larger_heap) + ultimately show ?thesis + using larger_heap_trans by blast + qed + moreover have "larger_heap (get_h x) (get_h a)" + using PartialSA.greater_equiv asm1 larger_implies_larger_heap by blast + ultimately show "larger_heap (get_h x) (get_h y)" + by (simp add: larger_heap_plus) + show "greater_mask (get_m x) (get_m y)" + proof (rule greater_maskI) + fix hl + have "get_m x hl = padd (get_m (R a w) hl) (get_m a hl)" + using asm1 plus_charact(1) by auto + moreover have "get_m y hl = padd (pmult \ (padd (get_m (R a wa) hl) (get_m a hl))) (pmult \ (padd (get_m (R a wb) hl) (get_m a hl)))" + by (metis \Some y = multiply \ ya \ multiply \ yb\ \Some ya = R a wa \ a\ \Some yb = R a wb \ a\ \pgte pwrite \ \ pgte pwrite \\ add_masks.simps get_m_smaller plus_charact(1)) + + moreover have "padd (pmult \ (padd (get_m (R a wa) hl) (get_m a hl))) (pmult \ (padd (get_m (R a wb) hl) (get_m a hl))) += padd (padd (pmult \ (get_m a hl)) (pmult \ (get_m a hl))) (padd (pmult \ (get_m (R a wa) hl)) (pmult \ (get_m (R a wb) hl)))" + using padd_asso padd_comm pmult_distr by force + + have "pgte (get_m (R a w) hl) (padd (pmult \ (get_m (R a wa) hl)) (pmult \ (get_m (R a wb) hl)))" + proof (cases "pgte (get_m w hl) (comp_one (get_m a hl))") + case True + then have "get_m (R a w) hl = (comp_one (get_m a hl))" + using \get_h (R a w) = get_h w \ get_m (R a w) = comp_min_mask (get_m a) (get_m w)\ comp_min_mask_def pmin_is by presburger + moreover have "pgte (comp_one (get_m a hl)) (get_m (R a wa) hl)" + by (metis \get_h (R a wa) = get_h wa \ get_m (R a wa) = comp_min_mask (get_m a) (get_m wa)\ comp_min_mask_def pmin_comm pmin_greater) + then have "pgte (pmult \ (comp_one (get_m a hl))) (pmult \ (get_m (R a wa) hl))" + by (metis pmult_comm pmult_order) + moreover have "pgte (comp_one (get_m a hl)) (get_m (R a wb) hl)" + by (metis \get_h (R a wb) = get_h wb \ get_m (R a wb) = comp_min_mask (get_m a) (get_m wb)\ comp_min_mask_def pmin_comm pmin_greater) + then have "pgte (pmult \ (comp_one (get_m a hl))) (pmult \ (get_m (R a wb) hl))" + by (metis pmult_comm pmult_order) + ultimately show ?thesis + using \pgte (comp_one (get_m a hl)) (get_m (R a wa) hl)\ \pgte (comp_one (get_m a hl)) (get_m (R a wb) hl)\ asm0 padd_one_ineq_sum by presburger + next + case False + then have "get_m (R a w) hl = get_m w hl" + by (metis \get_h (R a w) = get_h w \ get_m (R a w) = comp_min_mask (get_m a) (get_m w)\ comp_min_mask_def not_pgte_charact pgt_implies_pgte pmin_comm pmin_is) + moreover have "pgte (get_m w hl) (padd (pmult \ (get_m wa hl)) (pmult \ (get_m wb hl)))" + proof - + have "pgte (get_m w hl) (padd (get_m xa hl) (get_m xb hl))" + using \Some w = xa \ xb\ not_pgte_charact pgt_implies_pgte plus_charact(1) by auto + moreover have "pgte (get_m xa hl) (pmult \ (get_m wa hl))" + by (metis \pgte pwrite \ \ pgte pwrite \\ \xa \ multiply \ wa\ get_m_smaller larger_implies_greater_mask_hl) + moreover have "pgte (get_m xb hl) (pmult \ (get_m wb hl))" + by (metis \pgte pwrite \ \ pgte pwrite \\ \xb \ multiply \ wb\ get_m_smaller larger_implies_greater_mask_hl) + ultimately show ?thesis + by (simp add: padd.rep_eq pgte.rep_eq) + qed + moreover have "pgte (pmult \ (get_m wa hl)) (pmult \ (get_m (R a wa) hl))" + by (metis R_smaller larger_implies_greater_mask_hl pmult_comm pmult_order) + moreover have "pgte (pmult \ (get_m wb hl)) (pmult \ (get_m (R a wb) hl))" + by (metis R_smaller larger_implies_greater_mask_hl pmult_comm pmult_order) + ultimately show ?thesis + using padd.rep_eq pgte.rep_eq by force + qed + moreover have "get_m x hl = padd (get_m (R a w) hl) (get_m a hl)" + using calculation(1) by auto + moreover have "get_m y hl = padd (pmult \ (get_m ya hl)) (pmult \ (get_m yb hl))" + using \Some y = multiply \ ya \ multiply \ yb\ \pgte pwrite \ \ pgte pwrite \\ get_m_smaller plus_charact(1) by auto + moreover have "padd (pmult \ (get_m ya hl)) (pmult \ (get_m yb hl)) = +padd (pmult \ (padd (get_m (R a wa) hl) (get_m a hl))) (pmult \ (padd (get_m (R a wb) hl) (get_m a hl)))" + using calculation(2) calculation(5) by presburger + moreover have "... = padd (pmult (padd \ \) (get_m a hl)) (padd (pmult \ (get_m (R a wa) hl)) (pmult \ (get_m (R a wb) hl)))" + by (metis \padd (pmult \ (padd (get_m (R a wa) hl) (get_m a hl))) (pmult \ (padd (get_m (R a wb) hl) (get_m a hl))) = padd (padd (pmult \ (get_m a hl)) (pmult \ (get_m a hl))) (padd (pmult \ (get_m (R a wa) hl)) (pmult \ (get_m (R a wb) hl)))\ pmult_comm pmult_distr) + ultimately show "pgte (get_m x hl) (get_m y hl)" + using asm0 p_greater_exists padd_asso padd_comm pmult_special(1) by force + qed + qed + ultimately have "y \ multiply_sem_assertion \ B \ multiply_sem_assertion \ B" + using PartialSA.add_set_elem by blast + then have "y \ multiply_sem_assertion pwrite B" + by (metis asm0 assms(1) combinable_def not_pgte_charact pgt_implies_pgte subsetD) + then obtain b where "y \ multiply pwrite b" "b \ B" + using in_multiply_sem by blast + then have "multiply pwrite b = b" + by (metis Rep_state_inverse get_h_m mult_write_mask multiply.simps) + then have "y \ B" + by (metis \b \ B\ \y \ multiply pwrite b\ assms(2) intuitionistic_def) + show "x \ B" + using \x \ y\ \y \ B\ assms(2) intuitionistic_def by blast + qed + qed +qed + + + + + +subsection Theorems + +text \The following theorem is crucial to use the package logic~\cite{Dardinier22} to automatically +compute footprints of combinable wands.\ + +theorem R_mono_transformer: + "PartialSA.mono_transformer (R a)" +proof - + have "R a unit = unit" + by (simp add: PartialSA.succ_antisym PartialSA.unit_smaller R_smaller) + moreover have "\\ \'. \' \ \ \ R a \' \ R a \" + proof - + fix \ \' + assume "\' \ \" + show "R a \' \ R a \" + proof (cases "scalable \' a") + case True + then show ?thesis + by (metis PartialSA.succ_trans R_def R_smaller \\' \ \\) + next + case False + then obtain p where "ppos p" "pgte pwrite p" "multiply p \' |#| a" + by (metis PartialSA.commutative PartialSA.defined_def non_scalable_instantiate) + then have "multiply p \ |#| a" + using PartialSA.smaller_compatible \\' \ \\ multiply_order by blast + then have "\ scalable \ a" + using PartialSA.commutative PartialSA.defined_def \pgte pwrite p\ \ppos p\ scalable_def scaled_def by auto + + moreover have "greater_mask (comp_min_mask (get_m a) (get_m \')) (comp_min_mask (get_m a) (get_m \))" + proof (rule greater_maskI) + fix hl show "pgte (comp_min_mask (get_m a) (get_m \') hl) (comp_min_mask (get_m a) (get_m \) hl)" + proof (cases "pgte (get_m \' hl) (comp_one (get_m a hl))") + case True + then show ?thesis + by (metis comp_min_mask_def pmin_comm pmin_greater pmin_is) + next + case False + then show ?thesis + by (metis PartialSA.succ_trans R_smaller \\' \ \\ calculation comp_min_mask_def larger_implies_greater_mask_hl non_scalable_R_charact not_pgte_charact pgt_implies_pgte pmin_comm pmin_is) + qed + qed + ultimately show ?thesis + using False \\' \ \\ greaterI larger_implies_larger_heap non_scalable_R_charact by presburger + qed + qed + ultimately show ?thesis + by (simp add: PartialSA.mono_transformer_def) +qed + +theorem properties_of_combinable_wands: + assumes "intuitionistic B" + shows "combinable B \ combinable (cwand A B)" + and "cwand A B \ wand A B" + and "binary A \ cwand A B = wand A B" + by (simp_all add: assms combinable_cwand cwand_stronger binary_same dual_order.eq_iff) + + +end diff --git a/thys/Combinable_Wands/Mask.thy b/thys/Combinable_Wands/Mask.thy new file mode 100755 --- /dev/null +++ b/thys/Combinable_Wands/Mask.thy @@ -0,0 +1,499 @@ +subsection \Permission masks: Maps from heap locations to permission amounts\ + +theory Mask + imports PosRat +begin + +subsubsection \Definitions\ + +type_synonym field = string +type_synonym address = nat +type_synonym heap_loc = "address \ field" + +type_synonym mask = "heap_loc \ prat" +type_synonym bmask = "heap_loc \ bool" + +definition null where "null = 0" + +definition full_mask :: "mask" where + "full_mask hl = (if fst hl = null then pnone else pwrite)" + + +definition multiply_mask :: "prat \ mask \ mask" where + "multiply_mask p \ hl = pmult p (\ hl)" + +fun empty_mask where + "empty_mask hl = pnone" + +fun empty_bmask where + "empty_bmask hl = False" + +fun add_acc where "add_acc \ hl p = \(hl := padd (\ hl) p)" + +inductive rm_acc where + "\ hl = padd p r \ rm_acc \ hl p (\(hl := r))" + +fun add_masks where + "add_masks \' \ hl = padd (\' hl) (\ hl)" + +definition greater_mask where + "greater_mask \' \ \ (\r. \' = add_masks \ r)" + +fun uni_mask where + "uni_mask hl p = empty_mask(hl := p)" + +fun valid_mask :: "mask \ bool" where + "valid_mask \ \ (\hl. pgte pwrite (\ hl)) \ (\f. \ (null, f) = pnone)" + +definition valid_null :: "mask \ bool" where + "valid_null \ \ (\f. \ (null, f) = pnone)" + +definition equal_on_mask where + "equal_on_mask \ h h' \ (\hl. ppos (\ hl) \ h hl = h' hl)" + +definition equal_on_bmask where + "equal_on_bmask \ h h' \ (\hl. \ hl \ h hl = h' hl)" + +definition big_add_masks where + "big_add_masks \ \' h = add_masks (\ h) (\' h)" + +definition big_greater_mask where + "big_greater_mask \ \' \ (\h. greater_mask (\ h) (\' h))" + +definition greater_bmask where + "greater_bmask H H' \ (\h. H' h \ H h)" + +definition update_dm where + "update_dm dm \ \' hl \ (dm hl \ pgt (\ hl) (\' hl))" + +fun pre_get_m where "pre_get_m \ = fst \" +fun pre_get_h where "pre_get_h \ = snd \" +fun srm_acc where "srm_acc \ hl p = (rm_acc (pre_get_m \) hl p, pre_get_h \)" + + +datatype val = Bool (the_bool: bool) | Address (the_address: address) | Rat (the_rat: prat) + +definition upper_bounded :: "mask \ prat \ bool" where + "upper_bounded \ p \ (\hl. pgte p (\ hl))" + + + + +subsubsection \Lemmas\ + +lemma ssubsetI: + assumes "\\ h. (\, h) \ A \ (\, h) \ B" + shows "A \ B" + using assms by auto + +lemma double_inclusion: + assumes "A \ B" + and "B \ A" + shows "A = B" + using assms by blast + +lemma add_masks_comm: + "add_masks a b = add_masks b a" +proof (rule ext) + fix x show "add_masks a b x = add_masks b a x" + by (metis Rep_prat_inverse add.commute add_masks.simps padd.rep_eq) +qed + +lemma add_masks_asso: + "add_masks (add_masks a b) c = add_masks a (add_masks b c)" +proof (rule ext) + fix x show "add_masks (add_masks a b) c x = add_masks a (add_masks b c) x" + by (metis Rep_prat_inverse add.assoc add_masks.simps padd.rep_eq) +qed + +lemma minus_empty: + "\ = add_masks \ empty_mask" +proof (rule ext) + fix x show "\ x = add_masks \ empty_mask x" + by (metis Rep_prat_inverse add.right_neutral add_masks.simps empty_mask.simps padd.rep_eq pnone.rep_eq) +qed + +lemma add_acc_uni_mask: + "add_acc \ hl p = add_masks \ (uni_mask hl p)" +proof (rule ext) + fix x show "add_acc \ hl p x = add_masks \ (uni_mask hl p) x" + by (metis (no_types, opaque_lifting) add_acc.simps add_masks.simps fun_upd_apply minus_empty uni_mask.simps) +qed + +lemma add_masks_equiv_valid_null: + "valid_null (add_masks a b) \ valid_null a \ valid_null b" + by (metis (mono_tags, lifting) add_masks.simps padd_zero valid_null_def) + +lemma valid_maskI: + assumes "\hl. pgte pwrite (\ hl)" + and "\f. \ (null, f) = pnone" + shows "valid_mask \" + by (simp add: assms(1) assms(2)) + +lemma greater_mask_equiv_def: + "greater_mask \' \ \ (\hl. pgte (\' hl) (\ hl))" + (is "?A \ ?B") +proof (rule iffI) + show "?A \ ?B" + proof (clarify) + fix hl assume "greater_mask \' \" + then obtain r where "\' = add_masks \ r" + using greater_mask_def by blast + then show "pgte (\' hl) (\ hl)" + using Rep_prat padd.rep_eq pgte.rep_eq by auto + qed + show "?B \ ?A" + proof - + assume ?B + let ?r = "\hl. (SOME p. \' hl = padd (\ hl) p)" + have "\' = add_masks \ ?r" + proof (rule ext) + fix hl + have "\' hl = padd (\ hl) (?r hl)" + by (meson \\hl. pgte (\' hl) (\ hl)\ p_greater_exists someI_ex) + then show "\' hl = add_masks \ ?r hl" + by auto + qed + then show ?A + using greater_mask_def by blast + qed +qed + +lemma greater_maskI: + assumes "\hl. pgte (\' hl) (\ hl)" + shows "greater_mask \' \" + by (simp add: assms greater_mask_equiv_def) + +lemma greater_mask_properties: + "greater_mask \ \" + "greater_mask a b \ greater_mask b c \ greater_mask a c" + "greater_mask \' \ \ greater_mask \ \' \ \ = \'" + apply (simp add: greater_maskI pgte.rep_eq) + apply (metis add_masks_asso greater_mask_def) +proof (rule ext) + fix x assume "greater_mask \' \ \ greater_mask \ \'" + show "\ x = \' x" + by (meson \greater_mask \' \ \ greater_mask \ \'\ greater_mask_equiv_def pgte_antisym) +qed + +lemma greater_mask_decomp: + assumes "greater_mask a (add_masks b c)" + shows "\a1 a2. a = add_masks a1 a2 \ greater_mask a1 b \ greater_mask a2 c" + by (metis add_masks_asso assms greater_mask_def greater_mask_properties(1)) + +lemma valid_empty: + "valid_mask empty_mask" + by (metis empty_mask.simps le_add_same_cancel1 p_greater_exists padd.rep_eq pgte.rep_eq pnone.rep_eq valid_mask.simps) + +lemma upper_valid_aux: + assumes "valid_mask a" + and "a = add_masks b c" + shows "valid_mask b" +proof (rule valid_maskI) + show "\hl. pgte pwrite (b hl)" + using assms(1) assms(2) p_greater_exists padd_asso by fastforce + fix f show " b (null, f) = pnone" + by (metis add_masks_comm assms(1) assms(2) empty_mask.simps greater_mask_def greater_mask_equiv_def minus_empty pgte_antisym valid_mask.simps) +qed + +lemma upper_valid: + assumes "valid_mask a" + and "a = add_masks b c" + shows "valid_mask b \ valid_mask c" + using add_masks_comm assms(1) assms(2) upper_valid_aux by blast + +lemma equal_on_bmaskI: + assumes "\hl. \ hl \ h hl = h' hl" + shows "equal_on_bmask \ h h'" + using assms equal_on_bmask_def by blast + +lemma big_add_greater: + "big_greater_mask (big_add_masks A B) B" + by (metis add_masks_comm big_add_masks_def big_greater_mask_def greater_mask_def) + +lemma big_greater_iff: + "big_greater_mask A B \ (\C. A = big_add_masks B C)" +proof - + assume "big_greater_mask A B" + let ?C = "\h. SOME r. A h = add_masks (B h) r" + have "A = big_add_masks B ?C" + proof (rule ext) + fix x + have "A x = add_masks (B x) (?C x)" + proof (rule ext) + fix xa + have "A x = add_masks (B x) (SOME r. A x = add_masks (B x) r)" + by (metis (mono_tags, lifting) \big_greater_mask A B\ big_greater_mask_def greater_mask_def someI_ex) + then show "A x xa = add_masks (B x) (SOME r. A x = add_masks (B x) r) xa" + by auto + qed + then show "A x = big_add_masks B (\h. SOME r. A h = add_masks (B h) r) x" + by (metis (no_types, lifting) big_add_masks_def) + qed + then show "\C. A = big_add_masks B C" + by fast +qed + +lemma big_add_masks_asso: + "big_add_masks A (big_add_masks B C) = big_add_masks (big_add_masks A B) C" +proof (rule ext) + fix x show "big_add_masks A (big_add_masks B C) x = big_add_masks (big_add_masks A B) C x" + by (simp add: add_masks_asso big_add_masks_def) +qed + +lemma big_add_mask_neutral: + "big_add_masks \ (\_. empty_mask) = \" +proof (rule ext) + fix x show "big_add_masks \ (\_. empty_mask) x = \ x" + by (metis big_add_masks_def minus_empty) +qed + +lemma sym_equal_on_mask: + "equal_on_mask \ a b \ equal_on_mask \ b a" +proof - + have "\a b. equal_on_mask \ a b \ equal_on_mask \ b a" + by (simp add: equal_on_mask_def) + then show ?thesis by blast +qed + +lemma greater_mask_uni_equiv: + "greater_mask \ (uni_mask hl r) \ pgte (\ hl) r" + by (metis add_masks_comm fun_upd_apply greater_mask_def greater_mask_equiv_def minus_empty uni_mask.simps) + +lemma greater_mask_uniI: + assumes "pgte (\ hl) r" + shows "greater_mask \ (uni_mask hl r)" + using greater_mask_uni_equiv assms by metis + +lemma greater_bmask_refl: + "greater_bmask H H" + by (simp add: greater_bmask_def) + +lemma greater_bmask_trans: + assumes "greater_bmask A B" + and "greater_bmask B C" + shows "greater_bmask A C" + by (metis assms(1) assms(2) greater_bmask_def) + +lemma update_dm_same: + "update_dm dm \ \ = dm" +proof (rule ext) + fix x show "update_dm dm \ \ x = dm x" + by (simp add: pgt.rep_eq update_dm_def) +qed + +lemma update_trans: + assumes "greater_mask \ \'" + and "greater_mask \' \''" + shows "update_dm (update_dm dm \ \') \' \'' = update_dm dm \ \''" +proof (rule ext) + fix hl show "update_dm (update_dm dm \ \') \' \'' hl = update_dm dm \ \'' hl" + proof - + have "update_dm (update_dm dm \ \') \' \'' hl \ (update_dm dm \ \') hl \ pgt (\' hl) (\'' hl)" + using update_dm_def by metis + also have "... \ dm hl \ pgt (\ hl) (\' hl) \ pgt (\' hl) (\'' hl)" + using update_dm_def by metis + moreover have "update_dm dm \ \'' hl \ dm hl \ pgt (\ hl) (\'' hl)" + using update_dm_def by metis + moreover have "pgt (\ hl) (\' hl) \ pgt (\' hl) (\'' hl) \ pgt (\ hl) (\'' hl)" + proof + show "pgt (\ hl) (\' hl) \ pgt (\' hl) (\'' hl) \ pgt (\ hl) (\'' hl)" + by (metis assms(1) assms(2) greater_mask_equiv_def greater_mask_properties(2) not_pgte_charact pgte_antisym) + show "pgt (\ hl) (\'' hl) \ pgt (\ hl) (\' hl) \ pgt (\' hl) (\'' hl)" + by (metis assms(1) greater_mask_equiv_def not_pgte_charact pgte_antisym) + qed + ultimately show ?thesis by blast + qed +qed + +lemma equal_on_bmask_greater: + assumes "equal_on_bmask \' h h'" + and "greater_bmask \' \" + shows "equal_on_bmask \ h h'" + by (metis (mono_tags, lifting) assms(1) assms(2) equal_on_bmask_def greater_bmask_def) + +lemma update_dm_equal_bmask: + assumes "\ = add_masks \' m" + shows "equal_on_bmask (update_dm dm \ \') h' h \ equal_on_mask m h h' \ equal_on_bmask dm h h'" +proof - + have "equal_on_bmask (update_dm dm \ \') h' h \ (\hl. update_dm dm \ \' hl \ h' hl = h hl)" + by (simp add: equal_on_bmask_def) + moreover have "\hl. update_dm dm \ \' hl \ dm hl \ pgt (\ hl) (\' hl)" + by (simp add: update_dm_def) + moreover have "(\hl. update_dm dm \ \' hl \ h' hl = h hl) \ equal_on_mask m h h' \ equal_on_bmask dm h h'" + proof + show "\hl. update_dm dm \ \' hl \ h' hl = h hl \ equal_on_mask m h h' \ equal_on_bmask dm h h'" + by (simp add: assms equal_on_bmask_def equal_on_mask_def padd.rep_eq pgt.rep_eq ppos.rep_eq update_dm_def) + assume "equal_on_mask m h h' \ equal_on_bmask dm h h'" + then have "\hl. update_dm dm \ \' hl \ h' hl = h hl" + by (metis (full_types) add.right_neutral add_masks.simps assms dual_order.strict_iff_order equal_on_bmask_def equal_on_mask_def padd.rep_eq pgt.rep_eq pnone.rep_eq ppos_eq_pnone update_dm_def) + then show "\hl. update_dm dm \ \' hl \ h' hl = h hl" + by simp + qed + then show ?thesis + by (simp add: calculation) +qed + +lemma const_sum_mask_greater: + assumes "add_masks a b = add_masks c d" + and "greater_mask a c" + shows "greater_mask d b" +proof (rule ccontr) + assume "\ greater_mask d b" + then obtain hl where "\ pgte (d hl) (b hl)" + using greater_mask_equiv_def by blast + then have "pgt (b hl) (d hl)" + using not_pgte_charact by auto + then have "pgt (padd (a hl) (b hl)) (padd (c hl) (d hl))" + by (metis assms(2) greater_mask_equiv_def padd_comm pgte_pgt) + then show "False" + by (metis add_masks.simps assms(1) not_pgte_charact order_refl pgte.rep_eq) +qed + +lemma add_masks_cancellative: + assumes "add_masks b c = add_masks b d" + shows "c = d" +proof (rule ext) + fix x show "c x = d x" + by (metis assms(1) const_sum_mask_greater greater_mask_properties(1) greater_mask_properties(3)) +qed + +lemma equal_on_maskI: + assumes "\hl. ppos (\ hl) \ h hl = h' hl" + shows "equal_on_mask \ h h'" + by (simp add: assms equal_on_mask_def) + +lemma greater_equal_on_mask: + assumes "equal_on_mask \' h h'" + and "greater_mask \' \" + shows "equal_on_mask \ h h'" +proof (rule equal_on_maskI) + fix hl assume asm: "ppos (\ hl)" + then show "h hl = h' hl" + by (metis assms(1) assms(2) equal_on_mask_def greater_mask_equiv_def less_le_trans pgte.rep_eq ppos.rep_eq) +qed + +lemma equal_on_mask_sum: + "equal_on_mask \1 h h' \ equal_on_mask \2 h h' \ equal_on_mask (add_masks \1 \2) h h'" +proof + show "equal_on_mask (add_masks \1 \2) h h' \ equal_on_mask \1 h h' \ equal_on_mask \2 h h'" + using add_masks_comm greater_equal_on_mask greater_mask_def by blast + assume "equal_on_mask \1 h h' \ equal_on_mask \2 h h'" + show "equal_on_mask (add_masks \1 \2) h h'" + proof (rule equal_on_maskI) + fix hl assume "ppos (add_masks \1 \2 hl)" + then show "h hl = h' hl" + proof (cases "ppos (\1 hl)") + case True + then show ?thesis + by (meson \equal_on_mask \1 h h' \ equal_on_mask \2 h h'\ equal_on_mask_def) + next + case False + then show ?thesis + by (metis \equal_on_mask \1 h h' \ equal_on_mask \2 h h'\ \ppos (add_masks \1 \2 hl)\ add_masks.simps equal_on_mask_def padd_zero ppos_eq_pnone) + qed + qed +qed + +lemma valid_larger_mask: + "valid_mask \ \ greater_mask full_mask \ " + by (metis fst_eqD full_mask_def greater_maskI greater_mask_def not_one_le_zero not_pgte_charact pgt_implies_pgte pgte.rep_eq pnone.rep_eq pwrite.rep_eq surjective_pairing upper_valid_aux valid_mask.elims(1)) + +lemma valid_mask_full_mask: + "valid_mask full_mask" + using greater_mask_properties(1) valid_larger_mask by blast + +lemma mult_greater: + assumes "greater_mask a b" + shows "greater_mask (multiply_mask p a) (multiply_mask p b)" + by (metis (full_types) assms greater_mask_equiv_def multiply_mask_def p_greater_exists pmult_distr) + +lemma mult_write_mask: + "multiply_mask pwrite \ = \" +proof (rule ext) + fix x show "multiply_mask pwrite \ x = \ x" + by (simp add: multiply_mask_def pmult_special(1)) +qed + +lemma mult_distr_masks: + "multiply_mask a (add_masks b c) = add_masks (multiply_mask a b) (multiply_mask a c)" +proof (rule ext) + fix x show "multiply_mask a (add_masks b c) x = add_masks (multiply_mask a b) (multiply_mask a c) x" + by (simp add: multiply_mask_def pmult_distr) +qed + +lemma mult_add_states: + "multiply_mask (padd a b) \ = add_masks (multiply_mask a \) (multiply_mask b \)" +proof (rule ext) + fix x show "multiply_mask (padd a b) \ x = add_masks (multiply_mask a \) (multiply_mask b \) x" + by (simp add: multiply_mask_def pmult_comm pmult_distr) +qed + +lemma upper_boundedI: + assumes "\hl. pgte p (\ hl)" + shows "upper_bounded \ p" + by (simp add: assms upper_bounded_def) + +lemma upper_bounded_smaller: + assumes "upper_bounded \ a" + shows "upper_bounded (multiply_mask p \) (pmult p a)" + by (metis assms multiply_mask_def p_greater_exists pmult_distr upper_bounded_def) + +lemma upper_bounded_bigger: + assumes "upper_bounded \ a" + and "pgte b a" + shows "upper_bounded \ b" + by (meson assms(1) assms(2) order_trans pgte.rep_eq upper_bounded_def) + + +lemma valid_mult: + assumes "valid_mask \" + and "pgte pwrite p" + shows "valid_mask (multiply_mask p \)" +proof (rule valid_maskI) + have "upper_bounded \ pwrite" + using assms(1) upper_bounded_def by auto + then have "upper_bounded (multiply_mask p \) (pmult p pwrite)" + by (simp add: upper_bounded_smaller) + then show "\hl. pgte pwrite (multiply_mask p \ hl)" + by (metis assms(2) pmult_comm pmult_special(1) upper_bounded_bigger upper_bounded_def) + show "\f. multiply_mask p \ (null, f) = pnone" + by (metis Rep_prat_inverse add_0_left assms(1) multiply_mask_def padd.rep_eq padd_cancellative pmult_distr pnone.rep_eq valid_mask.elims(1)) +qed + +lemma valid_sum: + assumes "valid_mask a" + and "valid_mask b" + and "upper_bounded a ma" + and "upper_bounded b mb" + and "pgte pwrite (padd ma mb)" + shows "valid_mask (add_masks a b)" + and "upper_bounded (add_masks a b) (padd ma mb)" +proof (rule valid_maskI) + show "\hl. pgte pwrite (add_masks a b hl)" + proof - + fix hl + have "pgte (padd ma mb) (add_masks a b hl)" + by (metis (mono_tags, lifting) add_masks.simps add_mono_thms_linordered_semiring(1) assms(3) assms(4) padd.rep_eq pgte.rep_eq upper_bounded_def) + then show "pgte pwrite (add_masks a b hl)" + by (meson assms(5) dual_order.trans pgte.rep_eq) + qed + show "\f. add_masks a b (null, f) = pnone" + by (metis Rep_prat_inverse add_0_left add_masks.simps assms(1) assms(2) padd.rep_eq pnone.rep_eq valid_mask.simps) + show "upper_bounded (add_masks a b) (padd ma mb)" + using add_mono_thms_linordered_semiring(1) assms(3) assms(4) padd.rep_eq pgte.rep_eq upper_bounded_def by fastforce +qed + +lemma valid_multiply: + assumes "valid_mask a" + and "upper_bounded a ma" + and "pgte pwrite (pmult ma p)" + shows "valid_mask (multiply_mask p a)" + by (metis (no_types, opaque_lifting) assms(1) assms(2) assms(3) multiply_mask_def pmult_comm pmult_special(2) upper_bounded_bigger upper_bounded_def upper_bounded_smaller valid_mask.elims(1)) + +lemma greater_mult: + assumes "greater_mask a b" + shows "greater_mask (multiply_mask p a) (multiply_mask p b)" + by (metis Rep_prat assms greater_mask_equiv_def mem_Collect_eq mult_left_mono multiply_mask_def pgte.rep_eq pmult.rep_eq) + +end diff --git a/thys/Combinable_Wands/PartialHeapSA.thy b/thys/Combinable_Wands/PartialHeapSA.thy new file mode 100755 --- /dev/null +++ b/thys/Combinable_Wands/PartialHeapSA.thy @@ -0,0 +1,604 @@ +subsection \Partial heaps: Partial maps from heap location to values\ + +theory PartialHeapSA + imports Mask "Package_logic.PackageLogic" +begin + +subsubsection \Definitions\ + +type_synonym heap = "heap_loc \ val" +type_synonym pre_state = "mask \ heap" + +definition valid_heap :: "mask \ heap \ bool" where + "valid_heap \ h \ (\hl. ppos (\ hl) \ h hl \ None)" + +fun valid_state :: "pre_state \ bool" where + "valid_state (\, h) \ valid_mask \ \ valid_heap \ h" + +lemma valid_stateI: + assumes "valid_mask \" + and "\hl. ppos (\ hl) \ h hl \ None" + shows "valid_state (\, h)" + using assms(1) assms(2) valid_heap_def valid_state.simps by blast + +definition empty_heap where "empty_heap hl = None" + +lemma valid_pre_unit: + "valid_state (empty_mask, empty_heap)" + using pnone.rep_eq ppos.rep_eq valid_empty valid_stateI by fastforce + +typedef state = "{ \ |\. valid_state \ }" + using valid_pre_unit by blast + +fun get_m :: "state \ mask" where "get_m a = fst (Rep_state a)" +fun get_h :: "state \ heap" where "get_h a = snd (Rep_state a)" + +fun compatible_options where + "compatible_options (Some a) (Some b) \ a = b" +| "compatible_options _ _ \ True" + +definition compatible_heaps :: "heap \ heap \ bool" where + "compatible_heaps h h' \ (\hl. compatible_options (h hl) (h' hl))" + +definition compatible :: "pre_state \ pre_state \ bool" where + "compatible \ \' \ compatible_heaps (snd \) (snd \') \ valid_mask (add_masks (fst \) (fst \'))" + +fun add_states :: "pre_state \ pre_state \ pre_state" where + "add_states (\, h) (\', h') = (add_masks \ \', h ++ h')" + +definition larger_heap where + "larger_heap h' h \ (\hl x. h hl = Some x \ h' hl = Some x)" + +definition unit :: "state" where + "unit = Abs_state (empty_mask, empty_heap)" + +definition plus :: "state \ state \ state" (infixl "\" 63) where + "a \ b = (if compatible (Rep_state a) (Rep_state b) then Some (Abs_state (add_states (Rep_state a) (Rep_state b))) else None)" + +definition core :: "state \ state" (" |_| ") where + "core \ = Abs_state (empty_mask, get_h \)" + +definition stable :: "state \ bool" where + "stable \ \ (\hl. ppos (get_m \ hl) \ get_h \ hl \ None)" + + + + + + + + +subsubsection Lemmas + +lemma valid_heapI: + assumes "\hl. ppos (\ hl) \ h hl \ None" + shows "valid_heap \ h" + using assms valid_heap_def by presburger + +lemma valid_state_decompose: + assumes "valid_state (add_masks a b, h)" + shows "valid_state (a, h)" +proof (rule valid_stateI) + show "valid_mask a" + using assms upper_valid_aux valid_state.simps by blast + fix hl assume "ppos (a hl)" then show "h hl \ None" + by (metis add_masks.simps assms ppos_add valid_heap_def valid_state.simps) +qed + +lemma compatible_heapsI: + assumes "\hl a b. h hl = Some a \ h' hl = Some b \ a = b" + shows "compatible_heaps h h'" + by (metis assms compatible_heaps_def compatible_options.elims(3)) + +lemma compatibleI_old: + assumes "\hl x y. snd \ hl = Some x \ snd \' hl = Some y \ x = y" + and "valid_mask (add_masks (fst \) (fst \'))" + shows "compatible \ \'" + using assms(1) assms(2) compatible_def compatible_heapsI by presburger + +lemma larger_heap_anti: + assumes "larger_heap a b" + and "larger_heap b a" + shows "a = b" +proof (rule ext) + fix x show "a x = b x" + proof (cases "a x") + case None + then show ?thesis + by (metis assms(1) larger_heap_def not_None_eq) + next + case (Some a) + then show ?thesis + by (metis assms(2) larger_heap_def) + qed +qed + +lemma larger_heapI: + assumes "\hl x. h hl = Some x \ h' hl = Some x" + shows "larger_heap h' h" + by (simp add: assms larger_heap_def) + +lemma larger_heap_refl: + "larger_heap h h" + using larger_heap_def by blast + +lemma compatible_heaps_comm: + assumes "compatible_heaps a b" + shows "a ++ b = b ++ a" +proof (rule ext) + fix x show "(a ++ b) x = (b ++ a) x" + proof (cases "a x") + case None + then show ?thesis + by (simp add: domIff map_add_dom_app_simps(2) map_add_dom_app_simps(3)) + next + case (Some a) + then show ?thesis + by (metis (no_types, lifting) assms compatible_heaps_def compatible_options.elims(2) map_add_None map_add_dom_app_simps(1) map_add_dom_app_simps(3)) + qed +qed + +lemma larger_heaps_sum_ineq: + assumes "larger_heap a' a" + and "larger_heap b' b" + and "compatible_heaps a' b'" + shows "larger_heap (a' ++ b') (a ++ b)" +proof (rule larger_heapI) + fix hl x assume "(a ++ b) hl = Some x" + show "(a' ++ b') hl = Some x" + proof (cases "a hl") + case None + then show ?thesis + by (metis \(a ++ b) hl = Some x\ assms(2) larger_heap_def map_add_SomeD map_add_find_right) + next + case (Some aa) + then show ?thesis + by (metis (mono_tags, lifting) \(a ++ b) hl = Some x\ assms(1) assms(2) assms(3) compatible_heaps_comm larger_heap_def map_add_Some_iff) + qed +qed + +lemma larger_heap_trans: + assumes "larger_heap a b" + and "larger_heap b c" + shows "larger_heap a c" + by (metis (no_types, opaque_lifting) assms(1) assms(2) larger_heap_def) + +lemma larger_heap_comp: + assumes "larger_heap a b" + and "compatible_heaps a c" + shows "compatible_heaps b c" +proof (rule compatible_heapsI) + fix hl a ba + assume "b hl = Some a" "c hl = Some ba" + then show "a = ba" + by (metis assms(1) assms(2) compatible_heaps_def compatible_options.simps(1) larger_heap_def) +qed + +lemma larger_heap_plus: + assumes "larger_heap a b" + and "larger_heap a c" + shows "larger_heap a (b ++ c)" +proof (rule larger_heapI) + fix hl x assume "(b ++ c) hl = Some x" + then show "a hl = Some x" + proof (cases "b hl") + case None + then show ?thesis + by (metis \(b ++ c) hl = Some x\ assms(2) larger_heap_def map_add_SomeD) + next + case (Some bb) + then show ?thesis + by (metis \(b ++ c) hl = Some x\ assms(1) assms(2) larger_heap_def map_add_SomeD) + qed +qed + +lemma compatible_heaps_sum: + assumes "compatible_heaps a b" + and "compatible_heaps a c" + shows "compatible_heaps a (b ++ c)" + by (metis (no_types, opaque_lifting) assms(1) assms(2) compatible_heaps_def map_add_dom_app_simps(1) map_add_dom_app_simps(3)) + +lemma larger_compatible_sum_heaps: + assumes "larger_heap a x" + and "larger_heap b y" + and "compatible_heaps a b" + shows "compatible_heaps x y" +proof (rule compatible_heapsI) + fix hl a b assume "x hl = Some a" "y hl = Some b" + then show "a = b" + by (metis assms(1) assms(2) assms(3) compatible_heaps_def compatible_options.simps(1) larger_heap_def) +qed + +lemma get_h_m: + "Rep_state x = (get_m x, get_h x)" by simp + +lemma get_pre: + "get_h x = snd (Rep_state x)" + "get_m x = fst (Rep_state x)" + by simp_all + +lemma plus_ab_defined: + "\ \ \' \ None \ compatible_heaps (get_h \) (get_h \') \ valid_mask (add_masks (get_m \) (get_m \'))" + (is "?A \ ?B") +proof + show "?A \ ?B" + by (metis compatible_def get_pre(1) get_pre(2) plus_def) + show "?B \ ?A" + using compatible_def plus_def by auto +qed + +lemma plus_charact: + assumes "a \ b = Some x" + shows "get_m x = add_masks (get_m a) (get_m b)" + and "get_h x = (get_h a) ++ (get_h b)" +proof - + have "x = (Abs_state (add_states (Rep_state a) (Rep_state b)))" + by (metis assms option.discI option.inject plus_def) + moreover have "compatible (Rep_state a) (Rep_state b)" + using assms(1) plus_def by (metis option.discI) + + moreover have "valid_state (add_states (Rep_state a) (Rep_state b))" + proof - + have "valid_state (add_masks (get_m a) (get_m b), (get_h a) ++ (get_h b))" + proof (rule valid_stateI) + show "valid_mask (add_masks (get_m a) (get_m b))" + using calculation(2) compatible_def by fastforce + fix hl assume "ppos (add_masks (get_m a) (get_m b) hl)" + then show "(get_h a ++ get_h b) hl \ None" + proof (cases "ppos (get_m a hl)") + case True + then show ?thesis + by (metis Rep_state get_h_m map_add_None mem_Collect_eq valid_heap_def valid_state.simps) + next + case False + then have "ppos (get_m b hl)" + using \ppos (add_masks (get_m a) (get_m b) hl)\ padd.rep_eq ppos.rep_eq by auto + then show ?thesis + by (metis Rep_state get_h_m map_add_None mem_Collect_eq valid_heap_def valid_state.simps) + qed + qed + then show ?thesis + using add_states.simps get_h_m by presburger + qed + ultimately show "get_m x = add_masks (get_m a) (get_m b)" + by (metis Abs_state_inverse add_states.simps fst_conv get_h_m mem_Collect_eq) + + show "get_h x = (get_h a) ++ (get_h b)" + by (metis Abs_state_inject CollectI Rep_state Rep_state_inverse \valid_state (add_states (Rep_state a) (Rep_state b))\ \x = Abs_state (add_states (Rep_state a) (Rep_state b))\ add_states.simps eq_snd_iff get_h.simps) +qed + +lemma commutative: + "a \ b = b \ a" +proof (cases "compatible_heaps (get_h a) (get_h b) \ valid_mask (add_masks (get_m a) (get_m b))") + case True + then have "compatible_heaps (get_h b) (get_h a) \ add_masks (get_m a) (get_m b) = add_masks (get_m b) (get_m a)" + by (metis add_masks_comm compatible_heapsI compatible_heaps_def compatible_options.simps(1)) + then have "(get_h a) ++ (get_h b) = (get_h b) ++ (get_h a)" + by (simp add: compatible_heaps_comm) + then show ?thesis + by (metis True \compatible_heaps (get_h b) (get_h a) \ add_masks (get_m a) (get_m b) = add_masks (get_m b) (get_m a)\ add_states.simps get_h_m plus_ab_defined plus_def) +next + case False + then show ?thesis + by (metis add_masks_comm compatible_heapsI compatible_heaps_def compatible_options.simps(1) plus_ab_defined) +qed + +lemma asso1: + assumes "a \ b = Some ab \ b \ c = Some bc" + shows "ab \ c = a \ bc" +proof (cases "ab \ c") + case None + then show ?thesis + proof (cases "compatible_heaps (get_h ab) (get_h c)") + case True + then have "\ valid_mask (add_masks (add_masks (get_m a) (get_m b)) (get_m c))" + by (metis None assms plus_ab_defined plus_charact(1)) + then show ?thesis + by (metis add_masks_asso assms plus_ab_defined plus_charact(1)) + next + case False + then have "\ compatible_heaps (get_h a ++ get_h b) (get_h c)" + using assms plus_charact(2) by force + then obtain l x y where "(get_h a ++ get_h b) l = Some x" "get_h c l = Some y" "x \ y" + using compatible_heapsI by blast + then have "\ compatible_heaps (get_h a) (get_h b ++ get_h c)" + proof (cases "get_h a l") + case None + then show ?thesis + by (metis \(get_h a ++ get_h b) l = Some x\ \get_h c l = Some y\ \x \ y\ assms compatible_heaps_comm map_add_dom_app_simps(1) map_add_dom_app_simps(3) map_add_find_right option.inject option.simps(3) plus_ab_defined) + next + case (Some aa) + then show ?thesis + by (metis \(get_h a ++ get_h b) l = Some x\ \get_h c l = Some y\ \x \ y\ assms commutative compatible_heaps_def compatible_options.elims(2) map_add_find_right option.inject option.simps(3) plus_charact(2)) + qed + then show ?thesis + by (metis None assms plus_ab_defined plus_charact(2)) + qed +next + case (Some x) + then have "compatible_heaps (get_h a ++ get_h b) (get_h c)" + by (metis assms option.simps(3) plus_ab_defined plus_charact(2)) + then have "compatible_heaps (get_h a) (get_h b ++ get_h c)" + by (metis (full_types) assms compatible_heaps_comm compatible_heaps_def compatible_heaps_sum compatible_options.simps(2) domIff map_add_dom_app_simps(1) option.distinct(1) plus_ab_defined) + moreover have "valid_mask (add_masks (get_m a) (add_masks (get_m b) (get_m c)))" + by (metis Some add_masks_asso assms option.distinct(1) plus_ab_defined plus_charact(1)) + ultimately obtain y where "Some y = a \ bc" + by (metis assms plus_ab_defined plus_charact(1) plus_charact(2) plus_def) + then show ?thesis + by (metis (mono_tags, lifting) Some add_masks_asso add_states.simps assms get_h_m map_add_assoc option.distinct(1) plus_charact(1) plus_charact(2) plus_def) +qed + +lemma asso2: + assumes "a \ b = Some ab \ b \ c = None" + shows " ab \ c = None" +proof (cases "valid_mask (add_masks (get_m b) (get_m c))") + case True + then have "\ compatible_heaps (get_h b) (get_h c)" + using assms plus_ab_defined by blast + then obtain l x y where "get_h b l = Some x" "get_h c l = Some y" "x \ y" + using compatible_heapsI by blast + then have "get_h ab l = Some x" + by (metis assms map_add_find_right plus_charact(2)) + then show ?thesis + by (metis \get_h c l = Some y\ \x \ y\ compatible_heaps_def compatible_options.simps(1) plus_ab_defined) +next + case False + then obtain l where "\ (pgte pwrite (add_masks (get_m b) (get_m c) l))" + by (metis Abs_state_cases Rep_state_cases Rep_state_inverse add_masks_equiv_valid_null get_h_m mem_Collect_eq valid_mask.simps valid_null_def valid_state.simps) + then have "\ (pgte pwrite (add_masks (get_m ab) (get_m c) l))" + proof - + have "pgte (add_masks (get_m ab) (get_m c) l) (add_masks (get_m b) (get_m c) l)" + using assms p_greater_exists padd_asso padd_comm plus_charact(1) by auto + then show ?thesis + by (meson \\ pgte pwrite (add_masks (get_m b) (get_m c) l)\ order_trans pgte.rep_eq) + qed + then show ?thesis + using plus_ab_defined valid_mask.simps by blast +qed + +lemma core_defined: + "get_h |\| = get_h \" + "get_m |\| = empty_mask" + using Abs_state_inverse core_def pnone.rep_eq ppos.rep_eq valid_empty valid_stateI apply force + by (metis Abs_state_inverse CollectI core_def empty_mask.simps fst_conv get_pre(2) less_irrefl pnone.rep_eq ppos.rep_eq valid_empty valid_stateI) + +lemma state_ext: + assumes "get_h a = get_h b" + and "get_m a = get_m b" + shows "a = b" + by (metis Rep_state_inverse assms(1) assms(2) get_h_m) + +lemma core_is_smaller: + "Some x = x \ |x|" +proof - + obtain y where "Some y = x \ |x|" + by (metis Rep_state compatible_heapsI core_defined(1) core_defined(2) get_h_m mem_Collect_eq minus_empty option.collapse option.sel plus_ab_defined valid_state.simps) + moreover have "y = x" + proof (rule state_ext) + have "get_h x = get_h x ++ get_h x" + by (simp add: map_add_subsumed1) + then show "get_h y = get_h x" + using calculation core_defined(1) plus_charact(2) by presburger + show "get_m y = get_m x" + by (metis calculation core_defined(2) minus_empty plus_charact(1)) + qed + ultimately show ?thesis by blast +qed + +lemma core_is_pure: + "Some |x| = |x| \ |x|" +proof - + obtain y where "Some y = |x| \ |x|" + by (metis core_def core_defined(1) core_is_smaller) + moreover have "y = |x|" + by (metis calculation core_def core_defined(1) core_is_smaller option.sel) + ultimately show ?thesis by blast +qed + +lemma core_sum: + assumes "Some c = a \ b" + shows "Some |c| = |a| \ |b|" +proof - + obtain x where "Some x = |a| \ |b|" + by (metis assms core_defined(1) core_defined(2) minus_empty option.exhaust_sel plus_ab_defined valid_empty) + moreover have "x = |c|" + by (metis assms calculation core_defined(1) core_defined(2) minus_empty plus_charact(1) plus_charact(2) state_ext) + ultimately show ?thesis by blast +qed + +lemma core_max: + assumes "Some x = x \ c" + shows "\r. Some |x| = c \ r" +proof - + obtain y where "Some y = c \ |x|" + by (metis assms asso2 core_is_smaller plus_def) + moreover have "|x| = y" + by (metis (mono_tags, opaque_lifting) Rep_state_inverse add_masks_cancellative assms calculation commutative core_defined(1) core_sum get_h_m minus_empty option.inject plus_charact(1)) + ultimately show ?thesis by blast +qed + +lemma positivity: + assumes "a \ b = Some c" + and "Some c = c \ c" + shows "Some a = a \ a" +proof - + obtain x where "Some x = a \ a" + by (metis assms(1) assms(2) asso2 commutative option.exhaust_sel) + moreover have "x = a" + by (metis Rep_state_inverse add_masks_cancellative add_masks_comm assms(1) assms(2) calculation core_defined(1) core_defined(2) core_is_smaller get_h_m greater_mask_def greater_mask_properties(3) option.sel plus_charact(1)) + ultimately show ?thesis by blast +qed + +lemma cancellative: + assumes "Some a = b \ x" + and "Some a = b \ y" + and "|x| = |y|" + shows "x = y" + by (metis add_masks_cancellative assms(1) assms(2) assms(3) core_defined(1) plus_charact(1) state_ext) + +lemma unit_charact: + "get_h unit = empty_heap" + "get_m unit = empty_mask" +proof - + have "valid_state (empty_mask, empty_heap)" + using valid_pre_unit by auto + then show "get_h unit = empty_heap" using unit_def + by (simp add: \unit = Abs_state (empty_mask, empty_heap)\ Abs_state_inverse) + show "get_m unit = empty_mask" + using \valid_state (empty_mask, empty_heap)\ unit_def Abs_state_inverse + by fastforce +qed + +lemma empty_heap_neutral: + "a ++ empty_heap = a" +proof (rule ext) + fix x show "(a ++ empty_heap) x = a x" + by (simp add: domIff empty_heap_def map_add_dom_app_simps(3)) +qed + +lemma unit_neutral: + "Some a = a \ unit" +proof - + obtain x where "Some x = a \ unit" + by (metis Abs_state_cases Rep_state_cases Rep_state_inverse compatible_heapsI empty_heap_def fst_conv get_h_m mem_Collect_eq minus_empty option.distinct(1) option.exhaust_sel plus_ab_defined snd_conv unit_def valid_pre_unit valid_state.simps) + moreover have "x = a" + proof (rule state_ext) + show "get_h x = get_h a" + using calculation empty_heap_neutral plus_charact(2) unit_charact(1) by auto + show "get_m x = get_m a" + by (metis calculation minus_empty plus_charact(1) unit_charact(2)) + qed + ultimately show ?thesis by blast +qed + +lemma stableI: + assumes "\hl. ppos (get_m \ hl) \ get_h \ hl \ None" + shows "stable \" + using assms stable_def by blast + +lemma stable_unit: + "stable unit" + by (metis empty_heap_def stable_def unit_charact(1) unit_charact(2) valid_heap_def valid_pre_unit valid_state.simps) + +lemma stable_sum: + assumes "stable a" + and "stable b" + and "Some x = a \ b" + shows "stable x" +proof (rule stableI) + fix hl + show "ppos (get_m x hl) = (get_h x hl \ None)" (is "?A \ ?B") + proof + show "?A \ ?B" + by (metis add_le_same_cancel2 add_masks.simps assms(1) assms(2) assms(3) leI less_le_trans map_add_None padd.rep_eq plus_charact(1) plus_charact(2) ppos.rep_eq stable_def) + show "?B \ ?A" + by (metis add_masks.simps assms(1) assms(2) assms(3) map_add_None padd_comm plus_charact(1) plus_charact(2) ppos_add stable_def) + qed +qed + +lemma multiply_valid: + assumes "pgte pwrite p" + shows "valid_state (multiply_mask p (get_m \), get_h \)" +proof (rule valid_stateI) + show "valid_mask (multiply_mask p (get_m \))" + by (metis Rep_state assms(1) get_h_m mem_Collect_eq valid_mult valid_state.simps) + fix hl show "ppos (multiply_mask p (get_m \) hl) \ get_h \ hl \ None" + by (metis Abs_state_cases Rep_state_cases Rep_state_inverse get_h_m mem_Collect_eq multiply_mask_def pmult_comm pmult_special(2) ppos_eq_pnone valid_heap_def valid_state.simps) +qed + +subsection \This state model corresponds to a separation algebra\ + +global_interpretation PartialSA: package_logic plus core unit stable + defines greater (infixl "\" 50) = "PartialSA.greater" + and add_set (infixl "\" 60) = "PartialSA.add_set" + and defined (infixl "|#|" 60) = "PartialSA.defined" + and greater_set (infixl "|\|" 50) = "PartialSA.greater_set" + and minus (infixl "|\|" 60) = "PartialSA.minus" + apply standard + apply (simp add: commutative) + using asso1 apply blast + using asso2 apply blast + using core_is_smaller apply blast + using core_is_pure apply blast + using core_max apply blast + using core_sum apply blast + using positivity apply blast + using cancellative apply blast + using unit_neutral apply blast + using stable_sum apply blast + using stable_unit by blast + + +lemma greaterI: + assumes "larger_heap (get_h a) (get_h b)" + and "greater_mask (get_m a) (get_m b)" + shows "a \ b" +proof - + let ?m = "\l. SOME p. get_m a l = padd (get_m b l) p" + have "get_m a = add_masks (get_m b) ?m" + proof (rule ext) + fix l + have "pgte (get_m a l) (get_m b l)" + by (meson assms(2) greater_mask_equiv_def) + then have "get_m a l = padd (get_m b l) (SOME p. get_m a l = padd (get_m b l) p)" + by (simp add: p_greater_exists verit_sko_ex') + then show "get_m a l = add_masks (get_m b) (\l. SOME p. get_m a l = padd (get_m b l) p) l" + by simp + qed + moreover have "valid_state (?m, get_h a)" + proof (rule valid_stateI) + show "valid_mask (\l. SOME p. get_m a l = padd (get_m b l) p)" + by (metis (no_types, lifting) Rep_state calculation get_h_m mem_Collect_eq upper_valid valid_state.simps) + fix hl + assume asm0: "ppos (SOME p. get_m a hl = padd (get_m b hl) p)" + then have "ppos (get_m a hl)" + by (metis (no_types, lifting) add_masks.elims add_masks_comm calculation greater_mask_def ppos_add) + then show "get_h a hl \ None" + by (metis Rep_state get_h.simps get_pre(2) mem_Collect_eq prod.collapse valid_heap_def valid_state.simps) + qed + moreover have "compatible_heaps (get_h b) (get_h a)" + by (metis (mono_tags, lifting) assms(1) compatible_heapsI larger_heap_def option.inject) + ultimately have "(get_m a, get_h a) = add_states (get_m b, get_h b) (?m, get_h a)" + proof - + have "get_h b ++ get_h a = get_h a" + proof (rule ext) + fix x show "(get_h b ++ get_h a) x = get_h a x" + by (metis assms(1) domIff larger_heap_def map_add_dom_app_simps(1) map_add_dom_app_simps(3) not_Some_eq) + qed + then show ?thesis + by (metis \get_m a = add_masks (get_m b) (\l. SOME p. get_m a l = padd (get_m b l) p)\ add_states.simps) + qed + moreover have "compatible_heaps (get_h b) (get_h a) \ valid_mask (add_masks (get_m b) ?m)" + by (metis Rep_state \compatible_heaps (get_h b) (get_h a)\ \get_m a = add_masks (get_m b) (\l. SOME p. get_m a l = padd (get_m b l) p)\ get_h_m mem_Collect_eq valid_state.simps) + ultimately have "Some a = b \ Abs_state (?m, get_h a)" + proof - + have "Rep_state (Abs_state (?m, get_h a)) = (?m, get_h a)" + using Abs_state_inverse \valid_state (\l. SOME p. get_m a l = padd (get_m b l) p, get_h a)\ by blast + moreover have "compatible (Rep_state b) (?m, get_h a)" + using \compatible_heaps (get_h b) (get_h a) \ valid_mask (add_masks (get_m b) (\l. SOME p. get_m a l = padd (get_m b l) p))\ compatible_def by auto + moreover have "valid_state (add_states (Rep_state b) (?m, get_h a))" + by (metis Rep_state \(get_m a, get_h a) = add_states (get_m b, get_h b) (\l. SOME p. get_m a l = padd (get_m b l) p, get_h a)\ get_h_m mem_Collect_eq) + ultimately show ?thesis + by (metis (no_types, lifting) Rep_state_inverse \(get_m a, get_h a) = add_states (get_m b, get_h b) (\l. SOME p. get_m a l = padd (get_m b l) p, get_h a)\ get_h_m plus_def) + qed + then show ?thesis + by (meson PartialSA.greater_def) +qed + +lemma larger_implies_greater_mask_hl: + assumes "a \ b" + shows "pgte (get_m a hl) (get_m b hl)" + using PartialSA.greater_def assms p_greater_exists plus_charact(1) by auto + +lemma larger_implies_larger_heap: + assumes "a \ b" + shows "larger_heap (get_h a) (get_h b)" + by (metis (full_types) PartialSA.greater_equiv assms larger_heapI map_add_find_right plus_charact(2)) + +lemma compatibleI: + assumes "compatible_heaps (get_h a) (get_h b)" + and "valid_mask (add_masks (get_m a) (get_m b))" + shows "a |#| b" + using PartialSA.defined_def assms(1) assms(2) plus_ab_defined by presburger + +end diff --git a/thys/Combinable_Wands/PosRat.thy b/thys/Combinable_Wands/PosRat.thy new file mode 100755 --- /dev/null +++ b/thys/Combinable_Wands/PosRat.thy @@ -0,0 +1,340 @@ +section \State Model with Fractional Permissions\ + +text \In this section, we define a concrete state model based on fractional permissions \cite{Boyland03}. +A state is a pair of a permission mask and a partial heap. +A permission mask is a total map from heap locations to a rational between 0 and 1 (included), +while a partial heap is a partial map from heap locations to values. +We also define a partial addition on these states, and show that this state model corresponds to a separation algebra.\ + +subsection \Non-negative rationals (permission amounts)\ + +theory PosRat + imports Main HOL.Rat +begin + + + +subsubsection Definitions + +typedef prat = "{ r :: rat |r. r \ 0}" by fastforce + +setup_lifting type_definition_prat + +lift_definition pwrite :: "prat" is "1" by simp +lift_definition pnone :: "prat" is "0" by simp +lift_definition half :: "prat" is "1 / 2" by fastforce + +lift_definition pgte :: "prat \ prat \ bool" is "(\)" done +lift_definition pgt :: "prat \ prat \ bool" is "(>)" done +(* lift_definition lte :: "prat \ prat \ bool" is "(\)" done *) +lift_definition lt :: "prat \ prat \ bool" is "(<)" done +lift_definition ppos :: "prat \ bool" is "\p. p > 0" done + +lift_definition pmult :: "prat \ prat \ prat" is "(*)" by simp +lift_definition padd :: "prat \ prat \ prat" is "(+)" by simp + +lift_definition pdiv :: "prat \ prat \ prat" is "(/)" by simp + +lift_definition pmin :: "prat \ prat \ prat" is "(min)" by simp +lift_definition pmax :: "prat \ prat \ prat" is "(max)" by simp + +subsubsection Lemmas + +lemma pmin_comm: + "pmin a b = pmin b a" + by (metis Rep_prat_inverse min.commute pmin.rep_eq) + +lemma pmin_greater: + "pgte a (pmin a b)" + by (simp add: pgte.rep_eq pmin.rep_eq) + +lemma pmin_is: + assumes "pgte a b" + shows "pmin a b = b" + by (metis Rep_prat_inject assms min_absorb2 pgte.rep_eq pmin.rep_eq) + +lemma pmax_comm: + "pmax a b = pmax b a" + by (metis Rep_prat_inverse max.commute pmax.rep_eq) + +lemma pmax_smaller: + "pgte (pmax a b) a" + by (simp add: pgte.rep_eq pmax.rep_eq) + +lemma pmax_is: + assumes "pgte a b" + shows "pmax a b = a" + by (metis Rep_prat_inject assms max.absorb_iff1 pgte.rep_eq pmax.rep_eq) + + +lemma pmax_is_smaller: + assumes "pgte x a" + and "pgte x b" + shows "pgte x (pmax a b)" +proof (cases "pgte a b") + case True + then show ?thesis + by (simp add: assms(1) pmax_is) +next + case False + then show ?thesis + using assms(2) pgte.rep_eq pmax.rep_eq by auto +qed + + +lemma half_between_0_1: + "ppos half \ pgt pwrite half" + by (simp add: half.rep_eq pgt.rep_eq ppos.rep_eq pwrite.rep_eq) + +lemma pgt_implies_pgte: + assumes "pgt a b" + shows "pgte a b" + by (meson assms less_imp_le pgt.rep_eq pgte.rep_eq) + +lemma half_plus_half: + "padd half half = pwrite" + by (metis Rep_prat_inject divide_less_eq_numeral1(1) dual_order.irrefl half.rep_eq less_divide_eq_numeral1(1) linorder_neqE_linordered_idom mult.right_neutral one_add_one padd.rep_eq pwrite.rep_eq ring_class.ring_distribs(1)) + +lemma padd_comm: + "padd a b = padd b a" + by (metis Rep_prat_inject add.commute padd.rep_eq) + +lemma padd_asso: + "padd (padd a b) c = padd a (padd b c)" + by (metis Rep_prat_inverse group_cancel.add1 padd.rep_eq) + + +lemma p_greater_exists: + "pgte a b \ (\r. a = padd b r)" +proof (rule iffI) + show "pgte a b \ \r. a = padd b r" + proof - + assume asm: "pgte a b" + obtain aa bb where "aa = Rep_prat a" "bb = Rep_prat b" + by simp + then have "aa \ bb" using asm + using pgte.rep_eq by fastforce + then obtain rr where "rr = aa - bb" + by simp + then have "a = padd b (Abs_prat rr)" + by (metis Abs_prat_inverse Rep_prat_inject \aa = Rep_prat a\ \bb = Rep_prat b\ \bb \ aa\ add.commute diff_add_cancel diff_ge_0_iff_ge mem_Collect_eq padd.rep_eq) + then show "\r. a = padd b r" by blast + qed + show "\r. a = padd b r \ pgte a b" + using Rep_prat padd.rep_eq pgte.rep_eq by force +qed + + +lemma pgte_antisym: + assumes "pgte a b" + and "pgte b a" + shows "a = b" + by (metis Rep_prat_inverse assms(1) assms(2) leD le_less pgte.rep_eq) + +lemma greater_sum_both: + assumes "pgte a (padd b c)" + shows "\a1 a2. a = padd a1 a2 \ pgte a1 b \ pgte a2 c" +proof - + obtain aa bb cc where "aa = Rep_prat a" "bb = Rep_prat b" "cc = Rep_prat c" + by simp + then have "aa \ bb + cc" + using assms padd.rep_eq pgte.rep_eq by auto + then obtain x where "aa = bb + x" "x \ cc" + by (metis add.commute add_le_cancel_left diff_add_cancel) + then show ?thesis + by (metis assms order_refl p_greater_exists padd_asso pgte.rep_eq) +qed + + +lemma padd_cancellative: + assumes "a = padd x b" + and "a = padd y b" + shows "x = y" + by (metis Rep_prat_inject add_le_cancel_right assms(1) assms(2) leD less_eq_rat_def padd.rep_eq) + + +lemma not_pgte_charact: + "\ pgte a b \ pgt b a" + by (meson not_less pgt.rep_eq pgte.rep_eq) + +lemma pgte_pgt: + assumes "pgt a b" + and "pgte c d" + shows "pgt (padd a c) (padd b d)" + using assms(1) assms(2) padd.rep_eq pgt.rep_eq pgte.rep_eq by auto + +lemma pmult_distr: + "pmult a (padd b c) = padd (pmult a b) (pmult a c)" + by (metis Rep_prat_inject distrib_left padd.rep_eq pmult.rep_eq) + +lemma pmult_comm: + "pmult a b = pmult b a" + by (metis Rep_prat_inject mult.commute pmult.rep_eq) + +lemma pmult_special: + "pmult pwrite x = x" + "pmult pnone x = pnone" + apply (metis Rep_prat_inverse comm_monoid_mult_class.mult_1 pmult.rep_eq pwrite.rep_eq) + by (metis Rep_prat_inverse mult_zero_left pmult.rep_eq pnone.rep_eq) + + + +definition pinv where + "pinv p = pdiv pwrite p" + +lemma pinv_double_half: + assumes "ppos p" + shows "pmult half (pinv p) = pinv (padd p p)" +proof - + have "(Fract 1 2) * ((Fract 1 1) / (Rep_prat p)) = (Fract 1 1) / (Rep_prat p + Rep_prat p)" + by (metis (no_types, lifting) One_rat_def comm_monoid_mult_class.mult_1 divide_rat mult_2 mult_rat rat_number_expand(3) times_divide_times_eq) + then show ?thesis + by (metis Rep_prat_inject half.rep_eq mult_2 mult_numeral_1_right numeral_One padd.rep_eq pdiv.rep_eq pinv_def pmult.rep_eq pwrite.rep_eq times_divide_times_eq) +qed + +lemma ppos_mult: + assumes "ppos a" + and "ppos b" + shows "ppos (pmult a b)" + using assms(1) assms(2) pmult.rep_eq ppos.rep_eq by auto + +lemma padd_zero: + "pnone = padd a b \ a = pnone \ b = pnone" + by (metis Rep_prat Rep_prat_inject add.right_neutral leD le_add_same_cancel2 less_eq_rat_def mem_Collect_eq padd.rep_eq pnone.rep_eq) + +lemma ppos_add: + assumes "ppos a" + shows "ppos (padd a b)" + by (metis Rep_prat Rep_prat_inject assms dual_order.strict_iff_order mem_Collect_eq padd_zero pnone.rep_eq ppos.rep_eq) + + + +lemma pinv_inverts: + assumes "pgte a b" + and "ppos b" + shows "pgte (pinv b) (pinv a)" +proof - + have "Rep_prat a \ Rep_prat b" + using assms(1) pgte.rep_eq by auto + then have "(Fract 1 1) / Rep_prat b \ (Fract 1 1) / Rep_prat a" + by (metis One_rat_def assms(2) frac_le le_numeral_extra(4) ppos.rep_eq zero_le_one) + then show ?thesis + by (simp add: One_rat_def pdiv.rep_eq pgte.rep_eq pinv_def pwrite.rep_eq) +qed + + + +lemma pinv_pmult_ok: + assumes "ppos p" + shows "pmult p (pinv p) = pwrite" +proof - + obtain r where "r = Rep_prat p" by simp + then have "r * ((Fract 1 1) / r) = Fract 1 1" + using assms ppos.rep_eq by force + then show ?thesis + by (metis One_rat_def Rep_prat_inject \r = Rep_prat p\ pdiv.rep_eq pinv_def pmult.rep_eq pwrite.rep_eq) +qed + + +lemma pinv_pwrite: + "pinv pwrite = pwrite" + by (metis Rep_prat_inverse div_by_1 pdiv.rep_eq pinv_def pwrite.rep_eq) + +lemma pmult_ppos: + assumes "ppos a" + and "ppos b" + shows "ppos (pmult a b)" + using assms(1) assms(2) pmult.rep_eq ppos.rep_eq by auto + + +lemma ppos_inv: + assumes "ppos p" + shows "ppos (pinv p)" +by (metis Rep_prat Rep_prat_inverse assms less_eq_rat_def mem_Collect_eq not_one_le_zero pinv_pmult_ok pmult_comm pmult_special(2) pnone.rep_eq ppos.rep_eq pwrite.rep_eq) + + +lemma pmin_pmax: + assumes "pgte x (pmin a b)" + shows "x = pmin (pmax x a) (pmax x b)" +proof (cases "pgte x a") + case True + then show ?thesis + by (metis pmax_is pmax_smaller pmin_comm pmin_is) +next + case False + then show ?thesis + by (metis assms not_pgte_charact pgt_implies_pgte pmax_is pmax_smaller pmin_comm pmin_is) +qed + +definition comp_one where + "comp_one p = (SOME r. padd p r = pwrite)" + +lemma padd_comp_one: + assumes "pgte pwrite x" + shows "padd x (comp_one x) = pwrite" + by (metis (mono_tags, lifting) assms comp_one_def p_greater_exists someI_ex) + +lemma ppos_eq_pnone: + "ppos p \ p \ pnone" + by (metis Rep_prat Rep_prat_inject dual_order.strict_iff_order mem_Collect_eq pnone.rep_eq ppos.rep_eq) + + + +lemma pmult_order: + assumes "pgte a b" + shows "pgte (pmult p a) (pmult b p)" + using assms p_greater_exists pmult_comm pmult_distr by force + +lemma multiply_smaller_pwrite: + assumes "pgte pwrite a" + and "pgte pwrite b" + shows "pgte pwrite (pmult a b)" + by (metis assms(1) assms(2) p_greater_exists padd_asso pmult_order pmult_special(1)) + + +lemma pmult_pdiv_cancel: + assumes "ppos a" + shows "pmult a (pdiv x a) = x" + by (metis Rep_prat_inject assms divide_cancel_right dual_order.strict_iff_order nonzero_mult_div_cancel_left pdiv.rep_eq pmult.rep_eq ppos.rep_eq) + +lemma pmult_padd: + "pmult a (padd (pmult b x) (pmult c y)) = padd (pmult (pmult a b) x) (pmult (pmult a c) y)" + by (metis Rep_prat_inject mult.assoc pmult.rep_eq pmult_distr) + + +lemma pdiv_smaller: + assumes "pgte a b" + and "ppos a" + shows "pgte pwrite (pdiv b a)" +proof - + let ?a = "Rep_prat a" + let ?b = "Rep_prat b" + have "?b / ?a \ 1" + by (meson assms(1) assms(2) divide_le_eq_1_pos pgte.rep_eq ppos.rep_eq) + then show ?thesis + by (simp add: pdiv.rep_eq pgte.rep_eq pwrite.rep_eq) +qed + + +lemma sum_coeff: + assumes "ppos a" + and "ppos b" + shows "padd (pdiv a (padd a b)) (pdiv b (padd a b)) = pwrite" +proof - + let ?a = "Rep_prat a" + let ?b = "Rep_prat b" + have "(?a / (?a + ?b)) + (?b / (?a + ?b)) = 1" + by (metis add_divide_distrib add_pos_pos assms(1) assms(2) less_irrefl ppos.rep_eq right_inverse_eq) + then show ?thesis + by (metis Rep_prat_inject padd.rep_eq pdiv.rep_eq pwrite.rep_eq) +qed + +lemma padd_one_ineq_sum: + assumes "padd a b = pwrite" + and "pgte x aa" + and "pgte x bb" + shows "pgte x (padd (pmult a aa) (pmult b bb))" + by (metis (mono_tags, lifting) Rep_prat assms(1) assms(2) assms(3) convex_bound_le mem_Collect_eq padd.rep_eq pgte.rep_eq pmult.rep_eq pwrite.rep_eq) + + +end diff --git a/thys/Combinable_Wands/ROOT b/thys/Combinable_Wands/ROOT new file mode 100644 --- /dev/null +++ b/thys/Combinable_Wands/ROOT @@ -0,0 +1,12 @@ +chapter AFP + +session Combinable_Wands (AFP) = Package_logic + + options [timeout = 300] + theories + PosRat + Mask + PartialHeapSA + CombinableWands + document_files + "root.bib" + "root.tex" diff --git a/thys/Combinable_Wands/document/root.bib b/thys/Combinable_Wands/document/root.bib new file mode 100644 --- /dev/null +++ b/thys/Combinable_Wands/document/root.bib @@ -0,0 +1,100 @@ + + +@inproceedings{Dockins2009, +author = {Dockins, Robert and Hobor, Aquinas and Appel, Andrew W.}, +pages = {161--177}, +title = {{A Fresh Look at Separation Algebras and Share Accounting}}, +booktitle = {Asian Symposium on Programming Languages and Systems (APLAS)}, +editor = {Zhenjiang Hu}, +year = {2009} +} + +@inproceedings{Calcagno2007, +author = {Calcagno, Cristiano and O'Hearn, Peter W. and Yang, Hongseok}, +pages = {366--375}, +title = {{Local Action and Abstract Separation Logic}}, +booktitle = {Logic in Computer Science (LICS)}, +year = {2007} +} + +@inproceedings{SchwerhoffSummers15, + author = {M. Schwerhoff and A. J. Summers}, + title = {{Lightweight Support for Magic Wands in an Automatic Verifier}}, + booktitle = {European Conference on Object-Oriented Programming (ECOOP)}, + pages = {614--638}, + series = {LIPIcs}, + year = {2015}, + volume = {37}, + editor = {J. T. Boyland}, + publisher = {Schloss Dagstuhl}, +} + +@inproceedings{Dardinier22, + author = {Dardinier, Thibault and Parthasarathy, Gaurav and Weeks, No\'e and M\"uller, Peter and Summers, Alexander J.}, + title = {{Sound Automation of Magic Wands}}, + booktitle = {Computer Aided Verification (CAV)}, + year = {2022}, + note = {To appear} +} + +@inproceedings{Reynolds02a, + author = {J. C. Reynolds}, + title = {{Separation Logic: A Logic for Shared Mutable Data Structures}}, + booktitle = {Logic in Computer Science (LICS)}, + Publisher = {IEEE}, + pages = {55--74}, + year = {2002} +} + +@inproceedings{Boyland03, +author="Boyland, John", +editor="Cousot, Radhia", +title="Checking Interference with Fractional Permissions", +booktitle="Static Analysis (SAS)", +year="2003", +pages="55--72", +} + +@article{Boyland10, + author = {John Tang Boyland}, + title = {Semantics of fractional permissions with nesting}, + journal = {Transactions on Programming Languages and Systems (TOPLAS)}, + volume = {32}, + number = {6}, + pages = {22:1--22:33}, + year = {2010}, + doi = {10.1145/1749608.1749611}, + biburl = {https://dblp.org/rec/journals/toplas/Boyland10.bib} +} + +@inproceedings{JacobsPiessens11, + author = {Bart Jacobs and Frank Piessens}, + title = {Expressive modular fine-grained concurrency specification}, + booktitle = {Principles of Programming Languages (POPL)}, + pages = {271--282}, + year = {2011}, + doi = {10.1145/1926385.1926417}, + biburl = {https://dblp.org/rec/conf/popl/JacobsP11.bib} +} + +@inproceedings{LeHobor18, +author="Le, Xuan-Bach +and Hobor, Aquinas", +editor="Ahmed, Amal", +title="Logical Reasoning for Disjoint Permissions", +booktitle="European Symposium on Programming (ESOP)", +year="2018" +} + +@inproceedings{Brotherston20, +author="Brotherston, James +and Costa, Diana +and Hobor, Aquinas +and Wickerson, John", +editor="Lahiri, Shuvendu K. +and Wang, Chao", +title="Reasoning over Permissions Regions in Concurrent Separation Logic", +booktitle="Computer Aided Verification (CAV)", +year="2020" +} + diff --git a/thys/Combinable_Wands/document/root.tex b/thys/Combinable_Wands/document/root.tex new file mode 100644 --- /dev/null +++ b/thys/Combinable_Wands/document/root.tex @@ -0,0 +1,76 @@ +\documentclass[11pt,a4paper]{article} +\usepackage[T1]{fontenc} +\usepackage{isabelle,isabellesym} + +% further packages required for unusual symbols (see also +% isabellesym.sty), use only when needed + +%\usepackage{amssymb} + %for \, \, \, \, \, \, + %\, \, \, \, \, + %\, \, \ + +%\usepackage{eurosym} + %for \ + +%\usepackage[only,bigsqcap,bigparallel,fatsemi,interleave,sslash]{stmaryrd} + %for \, \, \, \, \ + +%\usepackage{eufrak} + %for \ ... \, \ ... \ (also included in amssymb) + +%\usepackage{textcomp} + %for \, \, \, \, \, + %\ + +% this should be the last package used +\usepackage{pdfsetup} + +% urls in roman style, theory text in math-similar italics +\urlstyle{rm} +\isabellestyle{it} + +% for uniform font size +%\renewcommand{\isastyle}{\isastyleminor} + +\newcommand{\wand}{\ensuremath{\mathbin{-\!\!*}}} + +\begin{document} + +\title{A Restricted Definition of the Magic Wand to Soundly Combine Fractions of a Wand} + +\author{Thibault Dardinier} +\maketitle + +\begin{abstract} +Many separation logics support \emph{fractional permissions}~\cite{Boyland03} to distinguish between read and write access to a heap location, for instance, to allow concurrent reads while enforcing exclusive writes. +The concept has been generalized to fractional assertions~\cite{Boyland10,JacobsPiessens11,LeHobor18,Brotherston20}. $A^p$ (where $A$ is a separation logic assertion and $p$ a fraction between $0$ and $1$) represents a fraction $p$ of $A$. +$A^p$ holds in a state $\sigma$ iff there exists a state $\sigma_A$ in which $A$ holds and $\sigma$ is obtained from $\sigma_A$ by multiplying all permission amounts held by $p$. + +While $A^{p + q}$ can always be split into $A^p * A^q$, recombining $A^p * A^q$ into $A^{p+q}$ is not always sound. +We say that $A$ is \emph{combinable} iff the entailment $A^p * A^q \models A^{p+q}$ holds for any two positive fractions $p$ and $q$ such that $p + q \le 1$. +Combinable assertions are particularly useful to reason about concurrent programs, for instance, to combine the postconditions of parallel branches when they terminate. +Unfortunately, the magic wand assertion $A \wand B$, commonly used to specify properties of partial data structures, is typically \emph{not} combinable. + +In this entry, we formalize a novel, restricted definition of the magic wand, described in a paper at CAV 22~\cite{Dardinier22}, which we call the \emph{combinable wand}. +We prove some key properties of the combinable wand; in particular, a combinable wand is combinable if its right-hand side is combinable. +\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/DPRM_Theorem/DPRM.thy b/thys/DPRM_Theorem/DPRM.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/DPRM.thy @@ -0,0 +1,88 @@ +section \Proof of the DPRM theorem\ + +theory DPRM + imports "Machine_Equations/Machine_Equation_Equivalence" +begin + +definition is_recenum :: "nat set \ bool" where + "is_recenum A = + (\ p :: program. + \ n :: nat. + \ a :: nat. \ ic. ic = initial_config n a \ is_valid_initial ic p a \ + (a \ A) = (\ q::nat. terminates ic p q))" + +theorem DPRM: "is_recenum A \ is_dioph_set A" +proof - + assume "is_recenum A" + hence "(\ p :: program. + \ n :: nat. \ a :: nat. + \ ic. ic = initial_config n a \ is_valid_initial ic p a \ + (a \ A) = (\ q::nat. terminates ic p q))" using is_recenum_def by auto + then obtain p n where p: + "\ a :: nat. + \ ic. ic = initial_config n a \ is_valid_initial ic p a \ + (a \ A) = (\ q::nat. terminates ic p q)" by auto + + interpret rm: register_machine p "Suc n" apply (unfold_locales) + proof - + from p have + "\ ic. ic = initial_config n 0 \ is_valid_initial ic p 0 \ + (0 \ A) = (\ q::nat. terminates ic p q)" by auto + then obtain ic where ic: "ic = initial_config n 0" and is_val: "is_valid_initial ic p 0" by auto + + show "length p > 0" + using is_val unfolding is_valid_initial_def is_valid_def by auto + + have "length (snd ic) = Suc n" + unfolding ic initial_config_def by auto + + moreover have "snd ic \ []" + using is_val unfolding is_valid_initial_def is_valid_def tape_check_initial.simps by auto + + ultimately show "Suc n > 0" + by auto + + show "program_register_check p (Suc n)" + using is_val unfolding is_valid_initial_def is_valid_def using \length (snd ic) = Suc n\ + by auto + qed + + + have equiv: "a \ A \ register_machine.rm_equations p (Suc n) a" for a + proof - + from p have "\ ic. ic = initial_config n a \ is_valid_initial ic p a \ + (a \ A) = (\ q::nat. terminates ic p q)" by auto + then obtain ic where ic: "ic = initial_config n a \ is_valid_initial ic p a \ + (a \ A) = (\ q::nat. terminates ic p q)" by blast + + have ic_def: "ic = initial_config n a" using ic by auto + hence n_is_length: "Suc n = length (snd ic)" using initial_config_def[of "n" "a"] by auto + have is_val: "is_valid_initial ic p a" using ic by auto + have "(a \ A) = (\q. terminates ic p q)" using ic by auto + moreover have "(\q. terminates ic p q) = register_machine.rm_equations p (Suc n) a" + using is_val n_is_length rm.conclusion_4_5 + by auto + + ultimately show ?thesis by auto + qed + + hence A_characterization: "A = {a::nat. register_machine.rm_equations p (Suc n) a}" by auto + + have eq_dioph: "\P\<^sub>1 P\<^sub>2. \a. register_machine.rm_equations p (Suc n) (peval A a) + = (\v. ppeval P\<^sub>1 a v = ppeval P\<^sub>2 a v)" for A + using rm.rm_dioph[of A] using is_dioph_rel_def[of "rm.rm_equations_relation A"] + unfolding rm.rm_equations_relation_def by(auto simp: unary_eval) + + have "\P\<^sub>1 P\<^sub>2. \b. register_machine.rm_equations p (Suc n) (peval (Param 0) (\x. b)) + = (\v. ppeval P\<^sub>1 (\x. b) v = ppeval P\<^sub>2 (\x. b) v)" + using eq_dioph[of "Param 0"] by blast + + hence "\P1 P2. \a. register_machine.rm_equations p (Suc n) a + = (\v. ppeval P1 (\x. a) v = ppeval P2 (\x. a) v)" + by auto + + thus ?thesis + unfolding A_characterization is_dioph_set_def by simp +qed + +end diff --git a/thys/DPRM_Theorem/Diophantine/Alpha_Sequence.thy b/thys/DPRM_Theorem/Diophantine/Alpha_Sequence.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Diophantine/Alpha_Sequence.thy @@ -0,0 +1,80 @@ +subsection \Diophantine description of alpha function\ + +theory Alpha_Sequence + imports Modulo_Divisibility "Exponentiation" +begin + +text \The alpha function is diophantine\ +definition alpha ("[_ = \ _ _]" 1000) + where "[X = \ B N] \ (TERNARY (\b n x. b > 3 \ x = Exp_Matrices.\ b n) B N X)" + +lemma alpha_dioph[dioph]: + fixes B N X + defines "D \ [X = \ B N]" + shows "is_dioph_rel D" +proof - + define r s t u v w x y where param_defs: + "r == (Param 0)" "s == (Param 1)" "t == (Param 2)" "u == (Param 3)" "v == (Param 4)" + "w == (Param 5)" "x == (Param 6)" "y == (Param 7)" + define B' X' N' where pushed_defs: "B' == (push_param B 8)" "X' == (push_param X 8)" + "N' == (push_param N 8)" + + (* eqns. (3.41) – (3.55) from YuMat lecture notes (p. 36) where "a" = X and "c" = N here *) + (* don't confuse capital X with x == (param 6) here, this is unhappy notation *) + define DR1 where "DR1 \ B' [>] (Const 3) [\] (Const 1 [+] B' [*] u [*] t [=] u[^2] [+] t[^2])" + define DR2 where "DR2 \ (Const 1 [+] B' [*] s [*] r [=] s[^2] [+] r[^2]) [\] r [<] s" + define DR3 where "DR3 \ (DVD (u[^2]) s) [\] (v [+] (Const 2) [*] r [=] B' [*] s)" + define DR4 where "DR4 \ (MOD B' v w) [\] (MOD (Const 2) u w) [\] (Const 2) [<] w" + define DR5 where "DR5 \ (Const 1 [+] w [*] x [*] y [=] x[^2] [+] y[^2])" + define DR6 where "DR6 \ (Const 2) [*] X' [<] u [\] (Const 2) [*] X' [<] v + [\] (MOD x v X') [\] (Const 2) [*] N' [<] u [\] MOD x u N'" + + define DR where "DR \ [\8] DR1 [\] DR2 [\] DR3 [\] DR4 [\] DR5 [\] DR6" + (* definition would otherwise be too long to handle for Isabelle *) + + note DR_defs = DR1_def DR2_def DR3_def DR4_def DR5_def DR6_def + + have "is_dioph_rel DR" + unfolding DR_def DR_defs + by (auto simp: dioph) + + moreover have "eval D a = eval DR a" for a + proof - + define x_ev b n where evaled_defs: "x_ev \ peval X a" "b \ peval B a" "n \ peval N a" + have h: "eval D a = (\r s t u v w x y::nat. Exp_Matrices.alpha_equations x_ev b n r s t u v w x y)" + unfolding D_def alpha_def evaled_defs defs using alpha_equivalence by simp + + show ?thesis + proof (rule) + assume "eval D a" + then obtain r s t u v w x y :: nat where "Exp_Matrices.alpha_equations x_ev b n r s t u v w x y" + using h by auto + then show "eval DR a" + unfolding evaled_defs Exp_Matrices.alpha_equations_def + unfolding DR_def DR_defs defs param_defs apply (auto simp: sq_p_eval) + apply (rule exI[of _ "[r, s, t, u, v, w, x, y]"]) + unfolding pushed_defs by (auto simp add: push_push[where ?n = 8] push_list_eval) + next + assume "eval DR a" + then show "eval D a" + (* simplify "eval DR a" and undo all the pushes *) + unfolding DR_def DR_defs defs param_defs apply (auto simp: sq_p_eval) + unfolding pushed_defs apply (auto simp add: push_push[where ?n = 8] push_list_eval) + (* simplify "eval D a" using the above fact h *) + unfolding h Exp_Matrices.alpha_equations_def evaled_defs + subgoal for ks + apply (rule exI[of _ "ks!0"]) apply (rule exI[of _ "ks!1"]) apply (rule exI[of _ "ks!2"]) + apply (rule exI[of _ "ks!3"]) apply (rule exI[of _ "ks!4"]) apply (rule exI[of _ "ks!5"]) + apply (rule exI[of _ "ks!6"]) apply (rule exI[of _ "ks!7"]) + by simp_all + done + qed + qed + + ultimately show ?thesis + by (auto simp: is_dioph_rel_def) +qed + +declare alpha_def[defs] + +end \ No newline at end of file diff --git a/thys/DPRM_Theorem/Diophantine/Assignments.thy b/thys/DPRM_Theorem/Diophantine/Assignments.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Diophantine/Assignments.thy @@ -0,0 +1,249 @@ +subsection \Variable Assignments\ + +text \The following theory defines manipulations of variable assignments and proves elementary facts about + these. Such preliminary results will later be necesary to e.g. prove that conjunction is + diophantine.\ + +theory Assignments + imports Parametric_Polynomials +begin + +definition shift :: "nat list \ nat \ assignment" where + "shift l a \ \i. l ! (i + a)" + +definition push :: "assignment \ nat \ assignment" where + "push a n i = (if i = 0 then n else a (i-1))" + +definition push_list :: "assignment \ nat list \ nat \ nat" where + "push_list a ns i = (if i < length ns then (ns!i) else a (i - length ns))" + +lemma push0: "push a n 0 = n" + by (auto simp: push_def) + +lemma push_list_empty: "push_list a [] = a" + unfolding push_list_def by auto + +lemma push_list_singleton: "push_list a [n] = push a n" + unfolding push_list_def push_def by auto + +lemma push_list_eval: "i < length ns \ push_list a ns i = ns!i" + unfolding push_list_def by auto + +lemma push_list1: "push (push_list a ns) n = push_list a (n # ns)" + unfolding push_def push_list_def by fastforce + +lemma push_list2_aux: "(push_list (push a n) ns) i = push_list a (ns @ [n]) i" + unfolding push_def push_list_def by (auto simp: nth_append) + +lemma push_list2: "(push_list (push a n) ns) = push_list a (ns @ [n])" + unfolding push_list2_aux by auto + +fun pull_param :: "ppolynomial \ ppolynomial \ ppolynomial" where + "pull_param (ppolynomial.Param 0) repl = repl" | + "pull_param (ppolynomial.Param (Suc n)) _ = (ppolynomial.Param n)" | + "pull_param (D1 \<^bold>+ D2) repl = (pull_param D1 repl) \<^bold>+ (pull_param D2 repl)" | + "pull_param (D1 \<^bold>- D2) repl = (pull_param D1 repl) \<^bold>- (pull_param D2 repl)" | + "pull_param (D1 \<^bold>* D2) repl = (pull_param D1 repl) \<^bold>* (pull_param D2 repl)" | + "pull_param P repl = P" + +(* FROM PREVIOUS FILE *) + +fun var_set :: "ppolynomial \ nat set" where + "var_set (ppolynomial.Const c) = {}" | + "var_set (ppolynomial.Param x) = {}" | + "var_set (ppolynomial.Var x) = {x}" | + "var_set (D1 \<^bold>+ D2) = var_set D1 \ var_set D2" | + "var_set (D1 \<^bold>- D2) = var_set D1 \ var_set D2" | + "var_set (D1 \<^bold>* D2) = var_set D1 \ var_set D2" + +definition disjoint_var :: "ppolynomial \ ppolynomial \ bool" where + "disjoint_var P Q = (var_set P \ var_set Q = {})" + +named_theorems disjoint_vars + +lemma disjoint_var_sym: "disjoint_var P Q = disjoint_var Q P" + unfolding disjoint_var_def by auto + +lemma disjoint_var_sum[disjoint_vars]: "disjoint_var (P1 \<^bold>+ P2) Q = (disjoint_var P1 Q \ disjoint_var P2 Q)" + unfolding disjoint_var_def by auto + +lemma disjoint_var_diff[disjoint_vars]: "disjoint_var (P1 \<^bold>- P2) Q = (disjoint_var P1 Q \ disjoint_var P2 Q)" + unfolding disjoint_var_def by auto + +lemma disjoint_var_prod[disjoint_vars]: "disjoint_var (P1 \<^bold>* P2) Q = (disjoint_var P1 Q \ disjoint_var P2 Q)" + unfolding disjoint_var_def by auto + +lemma aux_var_set: + assumes "\i \ var_set P. x i = y i" + shows "ppeval P a x = ppeval P a y" + using assms by (induction P, auto) + +text \First prove that disjoint variable sets allow the unification into one variable assignment\ +definition zip_assignments :: "ppolynomial \ ppolynomial \ assignment \ assignment \ assignment" + where "zip_assignments P Q v w i = (if i \ var_set P then v i else w i)" + +lemma help_eval_zip_assignments1: + shows "ppeval P1 a (\i. if i \ var_set P1 \ var_set P2 then v i else w i) + = ppeval P1 a (\i. if i \ var_set P1 then v i else w i)" + using aux_var_set by auto + +lemma help_eval_zip_assignments2: + shows "ppeval P2 a (\i. if i \ var_set P1 \ var_set P2 then v i else w i) + = ppeval P2 a (\i. if i \ var_set P2 then v i else w i)" + using aux_var_set by auto + +lemma eval_zip_assignments1: + fixes v w + assumes "disjoint_var P Q" + defines "x \ zip_assignments P Q v w" + shows "ppeval P a v = ppeval P a x" + using assms + apply (induction P arbitrary: x) + unfolding x_def zip_assignments_def + using help_eval_zip_assignments1 help_eval_zip_assignments2 + by (auto simp add: disjoint_vars) + +lemma eval_zip_assignments2: + fixes v w + assumes "disjoint_var P Q" + defines "x \ zip_assignments P Q v w" + shows "ppeval Q a w = ppeval Q a x" + using assms + apply (induction Q arbitrary: P x) + unfolding x_def zip_assignments_def + using disjoint_var_sym disjoint_vars + by (auto simp: disjoint_var_def) (smt (z3) inf_commute)+ + +lemma zip_assignments_correct: + assumes "ppeval P1 a v = ppeval P2 a v" and "ppeval Q1 a w = ppeval Q2 a w" + and "disjoint_var (P1 \<^bold>+ P2) (Q1 \<^bold>+ Q2)" + defines "x \ zip_assignments (P1 \<^bold>+ P2) (Q1 \<^bold>+ Q2) v w" + shows "ppeval P1 a x = ppeval P2 a x" and "ppeval Q1 a x = ppeval Q2 a x" +proof - + from assms(3) have "disjoint_var P1 (Q1 \<^bold>+ Q2)" + by (auto simp: disjoint_var_sum) + moreover have "ppeval P1 a x = ppeval P1 a (zip_assignments P1 (Q1 \<^bold>+ Q2) v w)" + unfolding x_def zip_assignments_def using help_eval_zip_assignments1 by auto + ultimately have p1: "ppeval P1 a x = ppeval P1 a v" + using eval_zip_assignments1[of "P1"] by auto + + from assms(3) have "disjoint_var P2 (Q1 \<^bold>+ Q2)" + by (auto simp: disjoint_var_sum) + moreover have "ppeval P2 a x = ppeval P2 a (zip_assignments P2 (Q1 \<^bold>+ Q2) v w)" + unfolding x_def zip_assignments_def using help_eval_zip_assignments2 by auto + ultimately have p2: "ppeval P2 a x = ppeval P2 a v" + using eval_zip_assignments1[of "P2"] by auto + + from p1 p2 show "ppeval P1 a x = ppeval P2 a x" + using assms(1) by auto +next + have "disjoint_var (P1 \<^bold>+ P2) Q1" + using assms(3) disjoint_var_sum disjoint_var_sym by auto + moreover have "ppeval Q1 a x = ppeval Q1 a (zip_assignments (P1 \<^bold>+ P2) Q1 v w)" + unfolding x_def zip_assignments_def using help_eval_zip_assignments1 by auto + ultimately have q1: "ppeval Q1 a x = ppeval Q1 a w" + using eval_zip_assignments2[of _ "Q1"] by auto + + from assms(3) have "disjoint_var (P1 \<^bold>+ P2) Q2" + using assms(3) disjoint_var_sum disjoint_var_sym by auto + moreover have "ppeval Q2 a x = ppeval Q2 a (zip_assignments (P1 \<^bold>+ P2) Q2 v w)" + unfolding x_def zip_assignments_def using help_eval_zip_assignments2 by auto + ultimately have q2: "ppeval Q2 a x = ppeval Q2 a w" + using eval_zip_assignments2[of _ "Q2"] by auto + + from q1 q2 show "ppeval Q1 a x = ppeval Q2 a x" + using assms(2) by auto +qed + +lemma disjoint_var_unifies: + assumes "\v1. ppeval P1 a v1 = ppeval P2 a v1" and "\v2. ppeval Q1 a v2 = ppeval Q2 a v2" + and "disjoint_var (P1 \<^bold>+ P2) (Q1 \<^bold>+ Q2)" + shows "\v. ppeval P1 a v = ppeval P2 a v \ ppeval Q1 a v = ppeval Q2 a v" + using assms zip_assignments_correct by (auto) metis + +(* Next prove that one can always find a polynomial with disjoint variables given some other polys*) +text \A function to manipulate variables in ppolynomials\ +fun push_var :: "ppolynomial \ nat \ ppolynomial" where + "push_var (ppolynomial.Var x) n = ppolynomial.Var (x + n)" | + "push_var (D1 \<^bold>+ D2) n = push_var D1 n \<^bold>+ push_var D2 n" | + "push_var (D1 \<^bold>- D2) n = push_var D1 n \<^bold>- push_var D2 n" | + "push_var (D1 \<^bold>* D2) n = push_var D1 n \<^bold>* push_var D2 n" | + "push_var D n = D" + +lemma push_var_bound: "x \ var_set (push_var P (Suc n)) \ x > n" + by (induction P, auto) + +definition pull_assignment :: "assignment \ nat \ assignment" where + "pull_assignment v n = (\x. v (x+n))" + +lemma push_var_pull_assignment: + shows "ppeval (push_var P n) a v = ppeval P a (pull_assignment v n)" + by (induction P, auto simp: pull_assignment_def) + +lemma max_set: "finite A \ \x\A. x \ Max A" + using Max_ge by blast + + +(* FROM PREVIOUS FILE SIMPLEDIOPHANTINE_NAT *) + +fun push_param :: "polynomial \ nat \ polynomial" where + "push_param (Const c) n = Const c" | + "push_param (Param x) n = Param (x + n)" | + "push_param (Sum D1 D2) n = Sum (push_param D1 n) (push_param D2 n)" | + "push_param (NatDiff D1 D2) n = NatDiff (push_param D1 n) (push_param D2 n)" | + "push_param (Prod D1 D2) n = Prod (push_param D1 n) (push_param D2 n)" + +definition push_param_list :: "polynomial list \ nat \ polynomial list" where + "push_param_list s k \ map (\x. push_param x k) s" + + +lemma push_param0: "push_param P 0 = P" + by (induction P, auto) + +lemma push_push_aux: "peval (push_param P (Suc m)) (push a n) = peval (push_param P m) a" + by (induction P, auto simp: push_def) + +lemma push_push: + shows "length ns = n \ peval (push_param P n) (push_list a ns) = peval P a" +proof (induction ns arbitrary: n) + case Nil + then show ?case by (auto simp: push_list_empty push_param0) +next + case (Cons n ns) + thus ?case + using push_push_aux[where ?a = "push_list a ns"] + by (auto simp add: length_Cons push_list1) +qed + +lemma push_push_simp: + shows "peval (push_param P (length ns)) (push_list a ns) = peval P a" +proof (induction ns) + case Nil + then show ?case by (auto simp: push_list_empty push_param0) +next + case (Cons n ns) + thus ?case + using push_push_aux[where ?a = "push_list a ns"] + by (auto simp add: length_Cons push_list1) +qed + + +lemma push_push1: "peval (push_param P 1) (push a k) = peval P a" + using push_push[where ?ns = "[k]"] by (auto simp: push_list_singleton) + +lemma push_push_map: "length ns = n \ + list_eval (map (\x. push_param x n) ls) (push_list a ns) = list_eval ls a" + unfolding list_eval_def apply (induction ls, simp) + apply (induction ns, auto) + apply (metis length_map list.size(3) nth_equalityI push_push) + by (metis length_Cons length_map map_nth push_push) + +lemma push_push_map_i: "length ns = n \ i < length ls \ + peval (map (\x. push_param x n) ls ! i) (push_list a ns) = list_eval ls a i" + unfolding list_eval_def by (auto simp: push_push_map push_push) + +lemma push_push_map1: "i < length ls \ + peval (map (\x. push_param x 1) ls ! i) (push a n) = list_eval ls a i" + unfolding list_eval_def using push_push1 by (auto) + +end \ No newline at end of file diff --git a/thys/DPRM_Theorem/Diophantine/Binary_And.thy b/thys/DPRM_Theorem/Diophantine/Binary_And.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Diophantine/Binary_And.thy @@ -0,0 +1,150 @@ +subsection \Binary and is Diophantine\ + +theory Binary_And + imports Binary_Masking Binary_Orthogonal +begin + +lemma lm0244: "(a && b) \ a" +proof (induct a b rule: bitAND_nat.induct) + case (1 uu) + then show ?case by simp +next + case (2 v n) + then show ?case + apply (auto simp add: mult.commute) + by (smt One_nat_def add_cancel_left_right even_succ_div_two masks.elims(3) mod_Suc_le_divisor + mod_by_Suc_0 mod_mod_trivial mod_mult_self4 mult_numeral_1_right mult_zero_right + nonzero_mult_div_cancel_left not_mod2_eq_Suc_0_eq_0 numeral_2_eq_2 numeral_One + odd_two_times_div_two_succ zero_neq_numeral) +qed + +lemma lm0245: "(a && b) \ b" + by (subst bitAND_commutes) (simp add: lm0244) + +lemma bitAND_lt_left: "m && n \ m" + using lm0244 masks_leq by auto +lemma bitAND_lt_right: "m && n \ n" + using lm0245 masks_leq by auto + +lemmas bitAND_lt = bitAND_lt_right bitAND_lt_left + +lemma auxm3_lm0246: + shows "bin_carry a b k = bin_carry a b k mod 2" + using bin_carry_bounded by auto + +lemma auxm2_lm0246: + assumes "(\r< n.(nth_bit a r + nth_bit b r \ 1))" + shows "(nth_bit (a+b) n) = (nth_bit a n + nth_bit b n) mod 2" + using assms no_carry by auto + +lemma auxm1_lm0246: "a \ (a+b) \ (\n. nth_bit a n + nth_bit b n \ 1)" (is "?P \ ?Q") +proof- +{ + assume asm: "\?Q" + then obtain n where n1:"\(nth_bit a n + nth_bit b n \ 1)" + and n2:"\r < n. (nth_bit a r + nth_bit b r \ 1)" + using obtain_smallest by (auto dest: obtain_smallest) + hence ab1: "nth_bit a n =1 \ nth_bit b n = 1" using nth_bit_def by auto + hence "nth_bit (a+b) n = 0" using n2 auxm2_lm0246 by auto + hence "\?P" using masks_leq_equiv ab1 by auto (metis One_nat_def not_one_le_zero) +} then show "?P \ ?Q" by auto +qed + +lemma aux0_lm0246:"a \ (a+b) \(a+b)\ n = a \ n + b \ n" +proof- + show ?thesis using auxm1_lm0246 auxm2_lm0246 less_Suc_eq_le numeral_2_eq_2 by auto +qed + +lemma aux1_lm0246:"a\b \ (\n. nth_bit (b-a) n = nth_bit b n - nth_bit a n)" + using aux0_lm0246 masks_leq by auto (metis add_diff_cancel_left' le_add_diff_inverse) + +lemma lm0246:"(a - (a && b)) \ (b - (a && b))" + apply (subst ortho_mult_equiv) + apply (rule allI) subgoal for k + proof(cases "nth_bit a k = 0") + case True + have "nth_bit (a- (a && b)) k = 0" by (auto simp add: lm0244 aux1_lm0246 "True") + then show ?thesis by simp + next + case False + then show ?thesis proof(cases "nth_bit b k = 0") + case True + have "nth_bit (b- (a && b)) k = 0" by (auto simp add: lm0245 aux1_lm0246 "True") + then show ?thesis by simp + next + case False2: False + have "nth_bit a k = 1" using False nth_bit_def by auto + moreover have "nth_bit b k = 1" using False2 nth_bit_def by auto + ultimately have "nth_bit (b- (a && b)) k = 0" + by (auto simp add: lm0245 aux1_lm0246 bitAND_digit_mult) + then show ?thesis by simp + qed + qed +done + +lemma aux0_lm0247:"(nth_bit a k) * (nth_bit b k) \ 1" + using eq_iff nth_bit_def by fastforce + +lemma lm0247_masking_equiv: + fixes a b c :: nat + shows "(c = a && b) \ (c \ a \ c \ b \ (a - c) \ (b - c))" (is "?P \ ?Q") +proof (rule) + assume ?P + thus ?Q + apply (auto simp add: lm0244 lm0245) + using lm0246 orthogonal.simps by blast +next + assume Q: ?Q + have "(\k. nth_bit c k \ nth_bit a k \ nth_bit c k \ nth_bit b k)" + using Q masks_leq_equiv by auto + moreover have "(\k x. nth_bit x k \ 1)" + by (auto simp add: nth_bit_def) + ultimately have f0:"(\k. nth_bit c k \ ((nth_bit a k) * (nth_bit b k)))" + by (metis mult.right_neutral mult_0_right not_mod_2_eq_0_eq_1 nth_bit_def) + show "?Q \ ?P" + proof (rule ccontr) + assume contr:"c \ a && b" + have k_exists:"(\k. (nth_bit c k) < ((nth_bit a k) * (nth_bit b k)))" + using bitAND_mult_equiv by (meson f0 contr le_less) + then obtain k + where "(nth_bit c k) < ((nth_bit a k) * (nth_bit b k))" .. + hence abc_kth:"((nth_bit c k) = 0) \ ((nth_bit a k) = 1) \ ((nth_bit b k) = 1)" + using aux0_lm0247 less_le_trans + by (metis One_nat_def Suc_leI nth_bit_bounded less_le less_one one_le_mult_iff) + hence "(nth_bit (a - c) k) = 1 \ (nth_bit (b - c) k) = 1" + by (auto simp add: abc_kth aux1_lm0246 Q) + hence "\ ((a - c) \ (b - c))" + by (metis mult.left_neutral not_mod_2_eq_0_eq_1 ortho_mult_equiv) + then show False + using Q by blast + qed +qed + +definition binary_and ("[_ = _ && _]" 1000) + where "[A = B && C] \ (TERNARY (\a b c. a = b && c) A B C)" + +lemma binary_and_dioph[dioph]: + fixes A B C :: polynomial + defines "DR \ [A = B && C]" + shows "is_dioph_rel DR" +proof - + define DS where "DS \ (A [\] B) [\] (A [\] C) [\] (B [-] A) [\] (C [-] A)" + + have "eval DS a = eval DR a" for a + unfolding DS_def DR_def binary_and_def defs + by (simp add: lm0247_masking_equiv) + + moreover have "is_dioph_rel DS" + unfolding DS_def by (auto simp: dioph) + + ultimately show ?thesis + by (auto simp: is_dioph_rel_def) +qed + +declare binary_and_def[defs] + + +definition binary_and_attempt :: "polynomial \ polynomial \ polynomial" ("_ &? _") where + "A &? B \ Const 0" + +end \ No newline at end of file diff --git a/thys/DPRM_Theorem/Diophantine/Binary_Masking.thy b/thys/DPRM_Theorem/Diophantine/Binary_Masking.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Diophantine/Binary_Masking.thy @@ -0,0 +1,79 @@ +subsection \Binary masking is Diophantine\ + +theory Binary_Masking + imports Binary_Orthogonal +begin + +lemma lm0243_masks_binom_equiv: "(b \ c) \ odd (c choose b)" (is "?P \ ?Q") +proof- + consider (lt) "b < c" | (eq) "b = c" | (gt) "b > c" using nat_neq_iff by blast + then show ?thesis + proof(cases) + case lt + hence "\a. c = a + b" using less_imp_add_positive semiring_normalization_rules(24) by blast + then obtain a where a_def:"c = a + b" .. + have "a \ b \ b \ a + b" (is "?P \ ?Q") + proof + assume ?P + then show ?Q + using ortho_mult_equiv no_carry_mult_equiv masks_leq_equiv[of b "a+b"] + sum_digit_formula nth_bit_bounded + by auto (metis add.commute add.right_neutral lessI less_one mod_less + nat_less_le one_add_one plus_1_eq_Suc zero_le) + next + assume ?Q + have "?Q \ \k. a \ k + b \ k \ 1" + proof(rule ccontr) + assume "\(\k. a \ k + b \ k \ 1) " + then obtain k where k1:"\(a \ k + b \ k \ 1)" and k2:"\r r + b \ r \ 1" + by (auto dest: obtain_smallest) + have c1: "bin_carry a b k = 1" + using `?Q` masks_leq_equiv sum_digit_formula carry_bounded nth_bit_bounded k1 + by (metis add.commute add.left_neutral add_self_mod_2 less_one nat_less_le not_le) + then show False using carry_digit_impl[of a b k] k2 by auto + qed + then show ?P + using `?Q` ortho_mult_equiv no_carry_mult_equiv masks_leq_equiv[of b "a+b"] + sum_digit_formula nth_bit_bounded + by auto (metis add_le_same_cancel2 le_0_eq le_SucE) + qed + then show ?thesis using lm0241_ortho_binom_equiv a_def by auto + next + case eq + hence "odd (c choose b)" by simp + moreover have "b \ c" using digit_wise_equiv masks_leq_equiv eq by blast + ultimately show ?thesis by simp + next + case gt + hence "\ odd (c choose b)" by (simp add: binomial_eq_0) + moreover have "\ (b \ c)" using masks_leq_equiv masks_leq gt not_le by blast + ultimately show ?thesis by simp + qed +qed + +definition masking ("_ [\] _" 60) + where "P [\] Q \ (BINARY (\a b. a \ b) P Q)" + +lemma masking_dioph[dioph]: + fixes P Q + defines "DR \ (P [\] Q)" + shows "is_dioph_rel DR" +proof - + define P' Q' where pushed_def: "P' \ push_param P 1" "Q' \ push_param Q 1" + + define DS where "DS \ [\] [Param 0 = Q' choose P'] [\] ODD Param 0" + + have "eval DS a = eval DR a" for a + unfolding DS_def DR_def defs pushed_def masking_def + using push_push1 by (simp add: push0 lm0243_masks_binom_equiv) + + moreover have "is_dioph_rel DS" + unfolding DS_def by (simp add: dioph) + + ultimately show ?thesis + by (auto simp: is_dioph_rel_def) +qed + +declare masking_def[defs] + +end \ No newline at end of file diff --git a/thys/DPRM_Theorem/Diophantine/Binary_Orthogonal.thy b/thys/DPRM_Theorem/Diophantine/Binary_Orthogonal.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Diophantine/Binary_Orthogonal.thy @@ -0,0 +1,144 @@ +subsection \Binary orthogonality is Diophantine\ + +theory Binary_Orthogonal + imports Binomial_Coefficient "Digit_Expansions.Binary_Operations" "Lucas_Theorem.Lucas_Theorem" +begin + +lemma equiv_with_lucas: "nth_digit = Lucas_Theorem.nth_digit_general" + unfolding nth_digit_def Lucas_Theorem.nth_digit_general_def by simp + +lemma lm0241_ortho_binom_equiv:"(a \ b) \ odd ((a + b) choose b)" (is "?P \ ?Q") +proof + assume "?P" + hence dig0:"(\i. (nth_bit a i) * (nth_bit b i) = 0)" + using ortho_mult_equiv + by auto + hence "(\i. (nth_bit a i) * (nth_bit b i) \ 1)" + by presburger + hence dcons:"(\i. \(((nth_bit a i) = 1) \ ((nth_bit b i) = 1)))" + by auto + hence "(\i. (bin_carry a b i) = 0)" using no_carry_mult_equiv dig0 + by blast + hence dsum:"(\i. (nth_bit (a + b) i) = (nth_bit a i) + (nth_bit b i))" + by (metis One_nat_def add.commute add_cancel_right_left add_self_mod_2 + dig0 mult_is_0 not_mod2_eq_Suc_0_eq_0 nth_bit_def one_mod_two_eq_one + sum_digit_formula) + + have bdd_ab_exists:"(\p. (a + b) < 2^(Suc p))" + using aux1_lm0241_pow2_up_bound by auto + then obtain p where bdd_ab:"(a + b) < 2^(Suc p)" by blast + moreover from bdd_ab have "b < 2^(Suc p)" by auto + + ultimately have "((a + b) choose b) mod 2 = + (\i\p. ((nth_digit (a + b) i 2) choose (nth_digit b i 2))) mod 2" + using lucas_theorem[of "a+b" 2 p b] bdd_ab two_is_prime_nat + by (simp add: equiv_with_lucas) + + then have a_choose_b_digit_prod: "((a + b) choose b) mod 2 = + (\i\p. ((nth_bit (a + b) i) choose (nth_bit b i))) mod 2" + using nth_digit_base2_equiv + by (auto cong: prod.cong) + + have "(\i. ((nth_bit (a + b) i) choose (nth_bit b i) = 1))" + using aux2_lm0241_single_digit_binom[where ?a="nth_bit (a + b) i" + and ?b="nth_bit b i"] + by (metis add.commute add.right_neutral binomial_n_0 binomial_n_n dig0 dsum + mult_is_0) + hence f0:"1 = (\i\i. (a + b) \ i choose b \ i = 1\) + then show "?Q" using f0 by fastforce +next + assume "?Q" + hence a_choose_b_odd:"((a + b) choose b) mod 2 = 1" + using odd_iff_mod_2_eq_one by blast + + have bdd_ab_exists:"(\p. (a + b) < 2^(Suc p))" + using aux1_lm0241_pow2_up_bound by auto + then obtain p where bdd_ab:"(a + b) < 2^(Suc p)" by blast + moreover from bdd_ab have bdd_b: "b < 2^(Suc p)" by auto + + ultimately have "((a + b) choose b) mod 2 = + (\i\p. ((nth_digit (a + b) i 2) choose (nth_digit b i 2))) mod 2" + using lucas_theorem[of "a+b" 2 p b] bdd_ab two_is_prime_nat + by (simp add: equiv_with_lucas) + + then have a_choose_b_digit_prod: "((a + b) choose b) mod 2 = + (\i\p. ((nth_bit (a + b) i) choose (nth_bit b i))) mod 2" + using nth_digit_base2_equiv nth_digit_def + by (auto cong: prod.cong) + hence all_prod_one_mod2:"... = 1" using a_choose_b_odd by linarith + + have choose_bdd:"(\i. 1 \ (nth_bit (a + b) i) choose (nth_bit b i))" + using nth_bit_bounded + by (metis One_nat_def binomial_n_0 choose_one not_mod2_eq_Suc_0_eq_0 + nth_bit_def order_refl) + hence "1 \ (\i\p. ((nth_bit (a + b) i) choose (nth_bit b i)))" + using all_prod_one_mod2 by (meson prod_le_1 zero_le) + hence "(\i\p. ((nth_bit (a + b) i) choose (nth_bit b i))) mod 2 = + (\i\p. ((nth_bit (a + b) i) choose (nth_bit b i)))" + using all_prod_one_mod2 by linarith + hence "... = 1" + using all_prod_one_mod2 by linarith + hence sub_pq_one:"\i\p. (nth_bit (a + b) i) choose (nth_bit b i) = 1" + using + aux4_lm0241_prod_one[where ?n="p" and ?f="(\i. (nth_bit (a + b) i) choose (nth_bit b i))"] + choose_bdd by blast + + have "\r > p. (a + b) < 2^r" using bdd_ab + by(metis One_nat_def Suc_lessI lessI less_imp_add_positive numeral_2_eq_2 + power_strict_increasing_iff trans_less_add1) + hence "\r > p. r \ p \ (a + b) < 2^r" by auto + hence ab_digit_bdd:"\r > p. r \ p \ nth_bit (a + b) r = 0" + using nth_bit_def by simp + + have "\k > p. b < 2 ^ k" using bdd_b + by(metis One_nat_def Suc_lessI lessI less_imp_add_positive numeral_2_eq_2 + power_strict_increasing_iff trans_less_add1) + hence b_digit_bdd:"\k > p. k \ p \ nth_bit b k = 0" + using nth_bit_def + by (simp add: \\k>p. b < 2 ^ k\) + + from b_digit_bdd ab_digit_bdd aux3_lm0241_binom_bounds + have "\i. i \ p \ (nth_bit (a + b) i) choose (nth_bit b i) = 1" + by (simp add: le_less sub_pq_one) + + hence "\i. ((nth_bit (a + b) i) choose (nth_bit b i)) = 1" + using sub_pq_one not_less by (metis linear) + hence "\i. \(nth_bit a i = 1 \ nth_bit b i = 1)" using aux5_lm0241 by blast + hence "\i. ((nth_bit a i = 0 \ nth_bit b i = 1) \ + (nth_bit a i = 1 \ nth_bit b i = 0) \ + (nth_bit a i = 0 \ nth_bit b i = 0))" + by (auto simp add:nth_bit_def nth_digit_bounded; metis nat.simps(3)) + hence "\i. (nth_bit a i) * (nth_bit b i) = 0" using mult_is_0 by blast + then show "?P" using ortho_mult_equiv by blast +qed + +definition orthogonal (infix "[\]" 50) + where "P [\] Q \ (BINARY (\a b. a \ b) P Q)" + +lemma orthogonal_dioph[dioph]: + fixes P Q + defines "DR \ (P [\] Q)" + shows "is_dioph_rel DR" +proof - + define P' Q' where pushed_def: "P' \ push_param P 1" "Q' \ push_param Q 1" + + define DS where "DS \ [\] [Param 0 = (P' [+] Q') choose Q'] [\] ODD (Param 0)" + + have "eval DS a = eval DR a" for a + unfolding DS_def DR_def orthogonal_def pushed_def defs + using push_push1 lm0241_ortho_binom_equiv by (simp add: push0) + + moreover have "is_dioph_rel DS" + unfolding DS_def by (simp add: dioph) + + ultimately show ?thesis + by (auto simp: is_dioph_rel_def) +qed + +declare orthogonal_def[defs] + +end \ No newline at end of file diff --git a/thys/DPRM_Theorem/Diophantine/Binomial_Coefficient.thy b/thys/DPRM_Theorem/Diophantine/Binomial_Coefficient.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Diophantine/Binomial_Coefficient.thy @@ -0,0 +1,88 @@ +subsection \Binomial Coefficient is Diophantine\ + +theory Binomial_Coefficient + imports Digit_Function +begin + +lemma bin_coeff_diophantine: + shows "c = a choose b \ (\u.(u = 2^(Suc a) \ c = nth_digit ((u+1)^a) b u))" +proof- + have "(u + 1)^a = (\k\a. (a choose k) * u ^ k)" for u + using binomial[of u 1 a] by auto + moreover have "a choose k < 2 ^ Suc a" for k + using binomial_le_pow2[of a k] by (simp add: le_less_trans) + ultimately have "nth_digit (((2 ^ Suc a) + 1)^a) b (2 ^ Suc a) = a choose b" + using nth_digit_gen_power_series[of "\k.(a choose k)" a a b] by (simp add: atLeast0AtMost) + then show ?thesis by auto +qed + +definition binomial_coefficient ("[_ = _ choose _]" 1000) + where "[A = B choose C] \ (TERNARY (\a b c. a = b choose c) A B C)" + +lemma binomial_coefficient_dioph[dioph]: + fixes A B C :: polynomial + defines "DR \ [C = A choose B]" + shows "is_dioph_rel DR" +proof - + define A' B' C' where pushed_def: + "A' \ (push_param A 2)" "B' \ (push_param B 2)" "C' \ (push_param C 2)" + + (* Param 0 = u = 2^(a + 1), Param 1 = (u+1)^a *) + define DS where "DS \ [\2] [Param 0 = Const 2 ^ (A' [+] \<^bold>1)] + [\] [Param 1 = (Param 0 [+] \<^bold>1) ^ A'] + [\] [C' = Digit (Param 1) B' (Param 0)]" + + have "eval DS a = eval DR a" for a + proof - + have "eval DS a = (peval C a = nth_digit ((2 ^ Suc (peval A a) + 1)^ peval A a) + (peval B a) (2 ^ Suc (peval A a)))" + unfolding DS_def defs pushed_def apply (auto simp add: push_push) + apply (rule exI[of _ "[2 * 2 ^ peval A a, Suc (2 * 2 ^ peval A a) ^ peval A a]"]) + apply (auto simp add: push_push push_list_eval) + by (metis (mono_tags, lifting) Suc_lessI mult_pos_pos n_not_Suc_n + numeral_2_eq_2 one_eq_mult_iff pos2 zero_less_power) + + then show ?thesis + unfolding DR_def binomial_coefficient_def defs by (simp add: bin_coeff_diophantine) + qed + + moreover have "is_dioph_rel DS" + unfolding DS_def by (auto simp: dioph) + + ultimately show ?thesis + by (auto simp: is_dioph_rel_def) +qed + +declare binomial_coefficient_def[defs] + + +text \odd function is diophantine\ + +lemma odd_dioph_repr: + fixes a :: nat + shows "odd a \ (\x::nat. a = 2*x + 1)" + by (meson dvd_triv_left even_plus_one_iff oddE) + +definition odd_lift ("ODD _" [999] 1000) + where "ODD A \ (UNARY (odd) A)" + +lemma odd_dioph[dioph]: + fixes A + defines "DR \ (ODD A)" + shows "is_dioph_rel DR" +proof - + define DS where "DS \ [\] (push_param A 1) [=] Const 2 [*] Param 0 [+] Const 1" + + have "eval DS a = eval DR a" for a + unfolding DS_def DR_def odd_lift_def defs using push_push1 by (simp add: odd_dioph_repr push0) + + moreover have "is_dioph_rel DS" + unfolding DS_def by (auto simp: dioph) + + ultimately show ?thesis + by (auto simp: is_dioph_rel_def) +qed + +declare odd_lift_def[defs] + +end \ No newline at end of file diff --git a/thys/DPRM_Theorem/Diophantine/Digit_Function.thy b/thys/DPRM_Theorem/Diophantine/Digit_Function.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Diophantine/Digit_Function.thy @@ -0,0 +1,86 @@ +subsection \Digit function is Diophantine\ + +theory Digit_Function + imports Exponential_Relation "Digit_Expansions.Bits_Digits" +begin + +definition digit ("[ _ = Digit _ _ _]" [999] 1000) + where "[D = Digit AA K BASE] \ (QUATERNARY (\d a k b. b > 1 + \ d = nth_digit a k b) D AA K BASE)" +lemma mod_dioph2[dioph]: + fixes A B C + defines "D \ (MOD A B C)" + shows "is_dioph_rel D" +proof - + define A' B' C' where pushed_defs: "A' \ push_param A 2" "B' \ push_param B 2" "C' \ push_param C 2" + define DS where "DS \ [\2] (Param 0 [*] B' [+] C' [=] Param 1 [*] B' [+] A')" + + have "eval DS a = eval D a" for a + proof + show "eval DS a \ eval D a" + unfolding DS_def defs D_def mod_def + by auto (metis add.commute mod_mult_self1 push_push_simp pushed_defs(1) + pushed_defs(2) pushed_defs(3)) + show "eval D a \ eval DS a" + unfolding DS_def defs D_def mod_def + apply (auto simp: mod_repr) + subgoal for x y + apply (rule exI[of _ "[x, y]"]) + unfolding pushed_defs by (simp add: push_push[where ?n = 2] push_list_eval) + done + qed + + moreover have "is_dioph_rel DS" + unfolding DS_def by (simp add: dioph) + + ultimately show ?thesis + by (auto simp: is_dioph_rel_def) +qed + +lemma digit_dioph[dioph]: + fixes D A B K :: polynomial + defines "DR \ [D = Digit A K B]" + shows "is_dioph_rel DR" +proof - + define D' A' B' K' where pushed_defs: + "D' == (push_param D 4)" "A' == (push_param A 4)" "B' == (push_param B 4)" "K' == (push_param K 4)" + (* Param 2 = b^(k+1), Param 3 = b^k *) + define x y where param_defs: + "x == (Param 0)" "y == (Param 1)" + + define DS where "DS \ [\4] ( B' [>] Const 1 [\] + [(Param 2) = B' ^ (K' [+] Const 1)] [\] + [(Param 3) = B' ^ K'] [\] + A' [=] x [*] (Param 2) [+] D' [*] (Param 3) [+] y [\] + D' [<] B' [\] + y [<] (Param 3)) " + have "eval DS a = eval DR a" for a + proof + show "eval DS a \ eval DR a" + unfolding DS_def defs DR_def digit_def apply auto + unfolding pushed_defs push_push using pushed_defs push_push digit_gen_equiv by auto + + assume asm: "eval DR a" + then obtain x_val y_val where cond: "(peval A a) = x_val * (peval B a)^( (peval K a)+1) + + (peval D a) * (peval B a)^ (peval K a) + y_val + \ (peval D a) < (peval B a) + \ y_val < (peval B a)^ (peval K a)" + unfolding DS_def defs DR_def digit_def using digit_gen_equiv by auto metis + show "eval DS a" + using asm unfolding DS_def defs DR_def digit_def apply auto + apply (rule exI[of _ "[x_val, y_val, (peval B a) ^ ((peval K a) + 1), + (peval B a) ^ (peval K a)]"]) + unfolding pushed_defs using param_defs push_push push_list_def cond by auto+ + qed + + moreover have "is_dioph_rel DS" + unfolding DS_def by (simp add: dioph) + + ultimately show ?thesis + by (auto simp: is_dioph_rel_def) +qed + +declare digit_def[defs] + + +end \ No newline at end of file diff --git a/thys/DPRM_Theorem/Diophantine/Diophantine_Relations.thy b/thys/DPRM_Theorem/Diophantine/Diophantine_Relations.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Diophantine/Diophantine_Relations.thy @@ -0,0 +1,246 @@ +subsection \Diophantine Relations and Predicates\ + +theory Diophantine_Relations + imports Assignments +begin + +datatype relation = + NARY "nat list \ bool" "polynomial list" + | AND relation relation (infixl "[\]" 35) + | OR relation relation (infixl "[\]" 30) + | EXIST_LIST nat relation ("[\_] _" 10) + +fun eval :: "relation \ assignment \ bool" where + "eval (NARY R PL) a = R (map (\P. peval P a) PL)" + | "eval (AND D1 D2) a = (eval D1 a \ eval D2 a)" + | "eval (OR D1 D2) a = (eval D1 a \ eval D2 a)" + | "eval ([\n] D) a = (\ks::nat list. n = length ks \ eval D (push_list a ks))" + +definition is_dioph_rel :: "relation \ bool" where + "is_dioph_rel DR = (\P\<^sub>1 P\<^sub>2::ppolynomial. \a. (eval DR a) \ (\v. ppeval P\<^sub>1 a v = ppeval P\<^sub>2 a v))" + + +definition UNARY :: "(nat \ bool) \ polynomial \ relation" where + "UNARY R P = NARY (\l. R (l!0)) [P]" + +lemma unary_eval: "eval (UNARY R P) a = R (peval P a)" + unfolding UNARY_def by simp + +definition BINARY :: "(nat \ nat \ bool) \ polynomial \ polynomial \ relation" where + "BINARY R P\<^sub>1 P\<^sub>2 = NARY (\l. R (l!0) (l!1)) [P\<^sub>1, P\<^sub>2]" + +lemma binary_eval: "eval (BINARY R P\<^sub>1 P\<^sub>2) a = R (peval P\<^sub>1 a) (peval P\<^sub>2 a)" + unfolding BINARY_def by simp + +definition TERNARY :: "(nat \ nat \ nat \ bool) + \ polynomial \ polynomial \ polynomial \ relation" where + "TERNARY R P\<^sub>1 P\<^sub>2 P\<^sub>3 = NARY (\l. R (l!0) (l!1) (l!2)) [P\<^sub>1, P\<^sub>2, P\<^sub>3]" + +lemma ternary_eval: "eval (TERNARY R P\<^sub>1 P\<^sub>2 P\<^sub>3) a = R (peval P\<^sub>1 a) (peval P\<^sub>2 a) (peval P\<^sub>3 a)" + unfolding TERNARY_def by simp + +definition QUATERNARY :: "(nat \ nat \ nat \ nat \ bool) + \ polynomial \ polynomial \ polynomial \ polynomial \ relation" where + "QUATERNARY R P\<^sub>1 P\<^sub>2 P\<^sub>3 P\<^sub>4 = NARY (\l. R (l!0) (l!1) (l!2) (l!3)) [P\<^sub>1, P\<^sub>2, P\<^sub>3, P\<^sub>4]" + +definition EXIST :: "relation \ relation" ("[\] _" 10) where + "([\] D) = ([\1] D)" + +definition TRUE where "TRUE = UNARY ((=) 0) (Const 0)" + +text \Bounded constant all quantifier (i.e. recursive conjunction)\ +fun ALLC_LIST :: "nat list \ (nat \ relation) \ relation" ("[\ in _] _") where + "[\ in []] DF = TRUE" | + "[\ in (l # ls)] DF = (DF l [\] [\ in ls] DF)" + +lemma ALLC_LIST_eval_list_all: "eval ([\ in L] DF) a = list_all (\l. eval (DF l) a) L" + by (induction L, auto simp: TRUE_def UNARY_def) + +lemma ALLC_LIST_eval: "eval ([\ in L] DF) a = (\k (nat \ relation) \ relation" ("[\<_] _") where + "[\ [\ in [0..k 'a list" where + "concat [] = []" | + "concat (l # ls) = l @ concat ls" + +fun splits :: "'a list \ nat list \ 'a list list" where + "splits L [] = []" | + "splits L (n # ns) = (take n L) # (splits (drop n L) ns)" + +lemma split_concat: + "splits (map f (concat pls)) (map length pls) = map (map f) pls" + by (induction pls, auto) + +definition LARY :: "(nat list list \ bool) \ (polynomial list list) \ relation" where + "LARY R PLL = NARY (\l. R (splits l (map length PLL))) (concat PLL)" + +lemma LARY_eval: + fixes PLL :: "polynomial list list" + shows "eval (LARY R PLL) a = R (map (map (\P. peval P a)) PLL)" + unfolding LARY_def apply (induction PLL, simp) + subgoal for pl pls by (induction pl, auto simp: split_concat) + done + +lemma or_dioph: + assumes "is_dioph_rel A" and "is_dioph_rel B" + shows "is_dioph_rel (A [\] B)" +proof - + from assms obtain PA1 PA2 where PA: "\a. (eval A a) \ (\v. ppeval PA1 a v = ppeval PA2 a v)" + by (auto simp: is_dioph_rel_def) + from assms obtain PB1 PB2 where PB: "\a. (eval B a) \ (\v. ppeval PB1 a v = ppeval PB2 a v)" + by (auto simp: is_dioph_rel_def) + + (* OR means (A1 - A2) * (B1 - B2) = 0 + Rewrite as A1*B1 + A2*B2 = A1*B2 + A2*B1 to eliminate subtraction. *) + show ?thesis + unfolding is_dioph_rel_def + apply (rule exI[of _ "PA1 \<^bold>* PB1 \<^bold>+ PA2 \<^bold>* PB2"]) + apply (rule exI[of _ "PA1 \<^bold>* PB2 \<^bold>+ PA2 \<^bold>* PB1"]) + using PA PB by (auto) (metis crossproduct_eq add.commute)+ + (* For each subgoal, a different fact is unused. The warning is due to 'metis+' being used. *) +qed + +lemma exists_disjoint_vars: + fixes Q1 Q2 :: ppolynomial + fixes A :: relation + assumes "is_dioph_rel A" + shows "\P1 P2. disjoint_var (P1 \<^bold>+ P2) (Q1 \<^bold>+ Q2) + \ (\a. eval A a \ (\v. ppeval P1 a v = ppeval P2 a v))" +proof - + obtain P1 P2 where p_defs: "\a. eval A a \ (\v. ppeval P1 a v = ppeval P2 a v)" + using assms is_dioph_rel_def by auto + + define n::nat where "n \ Max (var_set (Q1 \<^bold>+ Q2))" + + define P1' P2' where p'_defs: "P1' \ push_var P1 (Suc n)" "P2' \ push_var P2 (Suc n)" + + have "disjoint_var (P1' \<^bold>+ P2') (Q1 \<^bold>+ Q2)" + proof - + have "finite (var_set (Q1 \<^bold>+ Q2))" + apply (induction Q1, auto) + by (induction Q2, auto)+ + + hence "\x \ var_set (Q1 \<^bold>+ Q2). x \ n" + unfolding n_def using Max.coboundedI by blast + + moreover have "\x \ var_set (P1' \<^bold>+ P2'). x > n" + unfolding p'_defs using push_var_bound by auto + + ultimately show ?thesis + unfolding disjoint_var_def by fastforce + qed + + moreover have "\a. eval A a \ (\v. ppeval P1' a v = ppeval P2' a v)" + unfolding p'_defs apply (auto simp add: p_defs push_var_pull_assignment pull_assignment_def) + subgoal for a v by (rule exI[of _ "\i. v (i - Suc n)"]) auto + done + + ultimately show ?thesis + by auto +qed + +(* Combine the two results to show that AND has a diophantine representation *) +lemma and_dioph: + assumes "is_dioph_rel A" and "is_dioph_rel B" + shows "is_dioph_rel (A [\] B)" +proof - + from assms(1) obtain PA1 PA2 where PA: "\a. (eval A a) \ (\v. ppeval PA1 a v = ppeval PA2 a v)" + by (auto simp: is_dioph_rel_def) + from assms(2) obtain PB1 PB2 where disj: "disjoint_var (PB1 \<^bold>+ PB2) (PA1 \<^bold>+ PA2)" + and PB: "(\a. eval B a \ (\v. ppeval PB1 a v = ppeval PB2 a v))" + using exists_disjoint_vars[of B] by blast + + from disjoint_var_unifies have unified: "\a. (eval (A [\] B) a) + \ (\v. ppeval PA1 a v = ppeval PA2 a v \ ppeval PB1 a v = ppeval PB2 a v)" + using PA PB disj disjoint_var_sym by simp blast + + (* AND means (A1 - A2)^2 + (B1 - B2)^2 = 0 + Rewrite as A1^2 + A2^2 + B1^2 + B2^2 = 2*A1*A2 + 2*B1*B2 to eliminate subtraction. *) + have h0: "p1 = p2 \ p1^2 + p2^2 = 2*p1*p2" for p1 p2 :: nat + apply (auto simp: algebra_simps power2_eq_square) + using crossproduct_eq by fastforce + + have "p1 = p2 \ q1 = q2 \ p1^2 + p2^2 + q1^2 + q2^2 = 2*p1*p2 + 2*q1*q2" for p1 p2 q1 q2 :: nat + proof (rule) + assume "p1 = p2 \ q1 = q2" + thus "p1\<^sup>2 + p2\<^sup>2 + q1\<^sup>2 + q2\<^sup>2 = 2 * p1 * p2 + 2 * q1 * q2" + by (auto simp: algebra_simps power2_eq_square) + next + assume "p1\<^sup>2 + p2\<^sup>2 + q1\<^sup>2 + q2\<^sup>2 = 2 * p1 * p2 + 2 * q1 * q2" + hence "(int p1)\<^sup>2 + (int p2)\<^sup>2 + (int q1)\<^sup>2 + (int q2)\<^sup>2 - 2 * int p1 * int p2 - 2 * int q1 * int q2 = 0" + by (auto) (smt (verit, best) mult_2 of_nat_add of_nat_mult power2_eq_square) + hence "(int p1 - int p2)^2 + (int q1 - int q2)^2 = 0" + by (simp add: power2_diff) + hence "int p1 = int p2" and "int q1 = int q2" + by (simp add: sum_power2_eq_zero_iff)+ + thus "p1 = p2 \ q1 = q2" + by auto + qed + + thus ?thesis + apply (simp only: is_dioph_rel_def) + apply (rule exI[of _ "PA1\<^bold>^\<^bold>2 \<^bold>+ PA2\<^bold>^\<^bold>2 \<^bold>+ PB1\<^bold>^\<^bold>2 \<^bold>+ PB2\<^bold>^\<^bold>2"]) + apply (rule exI[of _ "(ppolynomial.Const 2) \<^bold>* PA1 \<^bold>* PA2 \<^bold>+ (ppolynomial.Const 2) \<^bold>* PB1 \<^bold>* PB2"]) + apply (subst unified) + by (simp add: Sq_pp_def power2_eq_square) +qed + + +(* Some basic relations are diophantine *) +definition eq (infix "[=]" 50) where "eq Q R \ BINARY (=) Q R" +definition lt (infix "[<]" 50) where "lt Q R \ BINARY (<) Q R" +definition le (infix "[\]" 50) where "le Q R \ Q [<] R [\] Q [=] R" +definition gt (infix "[>]" 50) where "gt Q R \ R [<] Q" +definition ge (infix "[\]" 50) where "ge Q R \ Q [>] R [\] Q [=] R" + +named_theorems defs +lemmas [defs] = zero_p_def one_p_def eq_def lt_def le_def gt_def ge_def LARY_eval + UNARY_def BINARY_def TERNARY_def QUATERNARY_def ALLC_LIST_eval ALLC_eval + +named_theorems dioph +lemmas [dioph] = or_dioph and_dioph + +lemma true_dioph[dioph]: "is_dioph_rel TRUE" + unfolding TRUE_def UNARY_def is_dioph_rel_def by auto + +lemma eq_dioph[dioph]: "is_dioph_rel (Q [=] R)" + unfolding is_dioph_rel_def + apply (rule exI[of _ "convert Q"]) + apply (rule exI[of _ "convert R"]) + using convert_eval BINARY_def by (auto simp: eq_def) + +lemma lt_dioph[dioph]: "is_dioph_rel (Q [<] R)" + unfolding is_dioph_rel_def + apply (rule exI[of _ "(ppolynomial.Const 1) \<^bold>+ (ppolynomial.Var 0) \<^bold>+ convert Q"]) + apply (rule exI[of _ "convert R"]) + using convert_eval BINARY_def apply (auto simp: lt_def) + by (metis add.commute add.right_neutral less_natE) + +definition zero ("[0=] _" [60] 60) where[defs]: "zero Q \ \<^bold>0 [=] Q" +lemma zero_dioph[dioph]: "is_dioph_rel ([0=] Q)" + unfolding zero_def by (auto simp: eq_dioph) + +lemma gt_dioph[dioph]: "is_dioph_rel (Q [>] R)" + unfolding gt_def by (auto simp: lt_dioph) + +lemma le_dioph[dioph]: "is_dioph_rel (Q [\] R)" + unfolding le_def by (auto simp: lt_dioph eq_dioph or_dioph) + +lemma ge_dioph[dioph]: "is_dioph_rel (Q [\] R)" + unfolding ge_def by (auto simp: gt_dioph eq_dioph or_dioph) + +text \Bounded Constant All Quantifier, dioph rules\ + +lemma ALLC_LIST_dioph[dioph]: "list_all (is_dioph_rel \ DF) L \ is_dioph_rel ([\ in L] DF)" + by (induction L, auto simp add: dioph) + +lemma ALLC_dioph[dioph]: "\i is_dioph_rel ([\Existential quantification is Diophantine\ + +theory Existential_Quantifier + imports Diophantine_Relations +begin + +lemma exist_list_dioph[dioph]: + fixes D + assumes "is_dioph_rel D" + shows "is_dioph_rel ([\n] D)" +proof (induction n) + case 0 + then show ?case + using assms unfolding is_dioph_rel_def by (auto simp: push_list_empty) +next + case (Suc n) + + have h: "(\i. if i = 0 then v 0 else v i) = v" for v::assignment + by auto + + have "eval ([\Suc n] D) a = (\k::nat. eval ([\n] D) (push a k))" for a + apply (simp add: push_list2) + by (smt (z3) Zero_not_Suc add_Suc_right append_Nil2 length_Cons + length_append list.size(3) nat.inject rev_exhaust) + moreover from Suc is_dioph_rel_def obtain P\<^sub>1 P\<^sub>2 where + "\a. eval ([\n] D) a = (\v. ppeval P\<^sub>1 a v = ppeval P\<^sub>2 a v)" + by auto + ultimately have t1: "eval ([\Suc n] D) a = (\k::nat. (\v. ppeval P\<^sub>1 (push a k) v + = ppeval P\<^sub>2 (push a k) v))" for a + by simp + + define f :: "ppolynomial \ ppolynomial" where + "f \ \P. pull_param (push_var P 1) (Var 0)" + have "ppeval P (push a k) v = ppeval (f P) a (push v k)" for P a k v + apply (induction P, auto simp: push_def f_def) + by (metis (no_types, lifting) Suc_pred ppeval.simps(2) pull_param.simps(2)) + then have t2: "eval ([\Suc n] D) a = (\k::nat. (\v. ppeval (f P\<^sub>1) a (push v k) + = ppeval (f P\<^sub>2) a (push v k)))" for a + using t1 by auto + moreover have "(\k::nat. \v. ppeval P a (push v k) = ppeval Q a (push v k)) + \ (\v. ppeval P a v = ppeval Q a v)" for P Q a + unfolding push_def + apply auto + subgoal for v + apply (rule exI[of _ "v 0"]) + apply (rule exI[of _ "\i. v (i + 1)"]) + by (auto simp: h cong: if_cong) + done + ultimately have "eval ([\Suc n] D) a = (\v. ppeval (f P\<^sub>1) a v = ppeval (f P\<^sub>2) a v)" for a + by auto + + thus ?case + unfolding is_dioph_rel_def by auto +qed + +lemma exist_dioph[dioph]: + fixes D + assumes "is_dioph_rel D" + shows "is_dioph_rel ([\] D)" + unfolding EXIST_def using assms by (auto simp: exist_list_dioph) + +lemma exist_eval[defs]: + shows "eval ([\] D) a = (\k. eval D (push a k))" + unfolding EXIST_def apply (simp add: push_list_def) + by (metis length_Suc_conv list.exhaust list.size(3) nat.simps(3) push_list_singleton) + +end \ No newline at end of file diff --git a/thys/DPRM_Theorem/Diophantine/Exponential_Relation.thy b/thys/DPRM_Theorem/Diophantine/Exponential_Relation.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Diophantine/Exponential_Relation.thy @@ -0,0 +1,173 @@ +subsection \Exponentiation is a Diophantine Relation\ + +theory Exponential_Relation + imports Alpha_Sequence "Exponentiation" +begin + + +(* Exponentiation is diophantine *) +definition exp_equations :: "nat \ nat \ nat \ nat \ nat \ bool" where + "exp_equations p q r b m = (b = Exp_Matrices.\ (q + 4) (r + 1) + q * q + 2 \ + m + q^2 + 1 = b * q \ + p < m \ + (p + b * Exp_Matrices.\ b r) mod m = (q * Exp_Matrices.\ b r + + Exp_Matrices.\ b (r + 1)) mod m)" + +lemma exp_repr: + fixes p q r :: nat + shows "p = q^r \ ((q = 0 \ r = 0 \ p = 1) \ + (q = 0 \ 0 < r \ p = 0) \ + (q > 0 \ (\b m :: nat. exp_equations p q r b m)))" (is "?P \ ?Q") +proof + assume P: ?P + (* 3 disjunction elims applied to assumption; makes cases 1 and 2 trivial *) + consider (c1)"q = 0 \ r = 0 \ p = 1" | (c2) "q = 0 \ 0 < r \ p = 0" | (c3) "q > 0 \ + (\b m. b = Exp_Matrices.\ (q + 4) (r + 1) + q * q + 2 \ m = b * q - q * q - 1 \ + p < m \ p mod m = (q * Exp_Matrices.\ b r - (b * Exp_Matrices.\ b r - + Exp_Matrices.\ b (r + 1))) mod m)" using exp_alpha[of p q r] P by auto + then show ?Q using P + proof cases + case c1 + then show ?thesis by auto + next + case c2 + then show ?thesis by auto + next + case c3 + obtain b m where + b_def: "b = Exp_Matrices.\ (q + 4) (r + 1) + q * q + 2" and + "m = b * q - q * q - 1" and + "p < m" and + "int (p mod m) = (int q * Exp_Matrices.\ b r - (int b * Exp_Matrices.\ b r - + Exp_Matrices.\ b (r + 1))) mod int m" + using exp_alpha[of p q r] c3 by blast + then have "exp_equations p q r b m" unfolding exp_equations_def + apply(intro conjI, auto simp add: power2_eq_square) using mod_add_right_eq by smt + then show ?thesis using c3 by blast + qed +next + assume ?Q + then show ?P + proof (elim disjE) + (* eliminate disjs, first two trivial cases by auto *) + show "q = 0 \ r = 0 \ p = 1 \ p = q ^ r" by auto + show "q = 0 \ 0 < r \ p = 0 \ p = q ^ r" by auto + (* third, non-trivial case *) + assume prems: "0 < q \ (\b m. exp_equations p q r b m)" + obtain b m where cond: "exp_equations p q r b m" using prems by auto + (* show that the four relevant conditions in exp_alpha hold; first three are easy *) + hence "int b = Exp_Matrices.\ (q + 4) (r + 1) + int (q * q) + 2 \ + m = b * q - q * q - 1 \ p < m" + unfolding exp_equations_def power2_eq_square by auto + (* the last one requires some extra care; but it's mainly mod_diff_cong *) + moreover have "int (p mod m) = (int q * Exp_Matrices.\ b r - + (int b * Exp_Matrices.\ b r - Exp_Matrices.\ b (r + 1))) mod int m" + using cond unfolding exp_equations_def + using mod_diff_cong[of "(p + b * Exp_Matrices.\ b r)" m "(q * Exp_Matrices.\ b r + + Exp_Matrices.\ b (r + 1))" "b * Exp_Matrices.\ b r" "b * Exp_Matrices.\ b r"] + unfolding diff_diff_eq2 by auto + ultimately show "p = q ^ r" using prems exp_alpha by auto + qed +qed + +definition exp ("[_ = _ ^ _]" 1000) + where "[Q = R ^ S] \ (TERNARY (\a b c. a = b ^ c) Q R S)" + +lemma exp_dioph[dioph]: + fixes P Q R :: polynomial + defines "D \ [P = Q ^ R]" + shows "is_dioph_rel D" +proof - + define P' Q' R' where pushed_def: + "P' \ (push_param P 5)" "Q' \ (push_param Q 5)" "R' \ (push_param R 5)" + define b m a0 a1 a2 where params_def: "b = Param 0" "m = Param 1" "a0 = Param 2" + "a1 = Param 3" "a2 = Param 4" + + define S1 where "S1 \ [0=] Q [\] [0=] R [\] P [=] \<^bold>1 [\] + [0=] Q [\] (Const 0) [<] R [\] [0=] P" + define S2 where "S2 \ [a0 = \ (Q' [+] (Const 4)) (R' [+] \<^bold>1)] + [\] b [=] (a0 [+] Q'[^2] [+] Const 2)" + define S3 where "S3 \ (m [+] Q'[^2] [+] Const 1) [=] b [*] Q' + [\] P' [<] m" + define S4 where "S4 \ [a1 = \ b R'] + [\] [a2 = \ b (R' [+] \<^bold>1)] + [\] MOD (P' [+] b [*] a1) m (Q' [*] a1 [+] a2)" + + note S_defs = S1_def S2_def S3_def S4_def + + define S where "S \ S1 [\] (Q [>] Const 0) [\] ([\5] S2 [\] S3 [\] S4)" + + have "is_dioph_rel S" + unfolding S_def S_defs by (auto simp: dioph) + + moreover have "eval S a = eval D a" for a + proof - + define p q r where evaled_defs: "p = peval P a" "q = peval Q a" "r = peval R a" + + show ?thesis + proof (rule) + assume "eval S a" + then show "eval D a" + unfolding S_def S_defs defs apply (simp add: sq_p_eval) + unfolding D_def exp_def defs apply simp_all + unfolding pushed_def params_def apply (auto simp add: push_push[where ?n = 5] push_list_eval) + unfolding exp_repr exp_equations_def apply simp + subgoal for ks + apply (rule exI[of _ "ks!0"], auto) + subgoal by (simp add: power2_eq_square) + subgoal apply (rule exI[of _ "ks!1"], auto) + by (smt int_ops(7) mult_Suc of_nat_Suc of_nat_add power2_eq_square zmod_int) + done + done + next + assume "eval D a" + then obtain b_val m_val where cond: "(q = 0 \ r = 0 \ p = 1) \ + (q = 0 \ 0 < r \ p = 0) \ + (q > 0 \ exp_equations p q r b_val m_val)" + unfolding D_def exp_def exp_repr evaled_defs ternary_eval by auto + + moreover define a0_val a1_val a2_val where + "a0_val \ nat (Exp_Matrices.\ (q + 4) (r + 1))" + "a1_val \ nat (Exp_Matrices.\ b_val r)" + "a2_val \ nat (Exp_Matrices.\ b_val (r + 1))" + ultimately show "eval S a" + unfolding S_def S_defs defs evaled_defs apply (simp add: sq_p_eval) + apply (elim disjE) + subgoal unfolding defs by simp + subgoal unfolding defs by simp + subgoal apply(elim conjE) apply(intro disjI2, intro conjI) + subgoal by simp + subgoal premises prems + proof- + have bg3: "3 < b_val" + proof- + have "b_val = Exp_Matrices.\ (q + 4) (r + 1) + int q * int q + 2" + using cond prems(4) evaled_defs(2) unfolding exp_equations_def by linarith + moreover have "int q * int q > 0" using evaled_defs(2) prems by simp + moreover have "Exp_Matrices.\ (q + 4) (r + 1) > 0" + using Exp_Matrices.alpha_superlinear[of "q+4" "r+1"] by linarith + ultimately show ?thesis by linarith + qed + show ?thesis apply (rule exI[of _ "[b_val, m_val, a0_val, a1_val, a2_val]"], intro conjI) + using prems + unfolding exp_equations_def pushed_def params_def + using push_list_def push_push bg3 Exp_Matrices.alpha_nonnegative apply simp_all + subgoal using push_list_def by (smt Exp_Matrices.alpha_strictly_increasing int_nat_eq + nat_int numeral_Bit0 numeral_One of_nat_1 of_nat_add of_nat_power plus_1_eq_Suc + power2_eq_square) + subgoal using push_list_def apply auto by (smt One_nat_def Suc_1 Suc_less_eq + int_nat_eq less_Suc_eq nat_int numeral_3_eq_3 of_nat_add of_nat_mult zmod_int) + done + qed + done + done + qed + qed + + ultimately show ?thesis + by (auto simp: is_dioph_rel_def) +qed + +declare exp_def[defs] + +end \ No newline at end of file diff --git a/thys/DPRM_Theorem/Diophantine/Exponentiation.thy b/thys/DPRM_Theorem/Diophantine/Exponentiation.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Diophantine/Exponentiation.thy @@ -0,0 +1,1692 @@ +section \Exponentiation is Diophaninte\ + +subsection \Expressing Exponentiation in terms of the alpha function\ + +theory Exponentiation + imports "HOL-Library.Discrete" +begin + +locale Exp_Matrices + begin + +subsubsection \2x2 matrices and operations\ +datatype mat2 = mat (mat_11 : int) (mat_12 : int) (mat_21 : int) (mat_22 : int) +datatype vec2 = vec (vec_1: int) (vec_2: int) + +fun mat_plus:: "mat2 \ mat2 \ mat2" where + "mat_plus A B = mat (mat_11 A + mat_11 B) (mat_12 A + mat_12 B) + (mat_21 A + mat_21 B) (mat_22 A + mat_22 B)" + +fun mat_mul:: "mat2 \ mat2 \ mat2" where + "mat_mul A B = mat (mat_11 A * mat_11 B + mat_12 A * mat_21 B) + (mat_11 A * mat_12 B + mat_12 A * mat_22 B) + (mat_21 A * mat_11 B + mat_22 A * mat_21 B) + (mat_21 A * mat_12 B + mat_22 A * mat_22 B)" + +fun mat_pow:: "nat \ mat2 \ mat2" where + "mat_pow 0 _ = mat 1 0 0 1" | + "mat_pow n A = mat_mul A (mat_pow (n - 1) A)" + +lemma mat_pow_2[simp]: "mat_pow 2 A = mat_mul A A" + by (simp add: numeral_2_eq_2) + +fun mat_det::"mat2 \ int" where + "mat_det M = mat_11 M * mat_22 M - mat_12 M * mat_21 M" + +fun mat_scalar_mult::"int \ mat2 \ mat2" where + "mat_scalar_mult a M = mat (a * mat_11 M) (a * mat_12 M) (a * mat_21 M) (a * mat_22 M)" + +fun mat_minus:: "mat2 \ mat2 \ mat2" where + "mat_minus A B = mat (mat_11 A - mat_11 B) (mat_12 A - mat_12 B) + (mat_21 A - mat_21 B) (mat_22 A - mat_22 B)" + +fun mat_vec_mult:: "mat2 \ vec2 \ vec2" where + "mat_vec_mult M v = vec (mat_11 M * vec_1 v + mat_12 M * vec_2 v) + (mat_21 M * vec_1 v + mat_21 M * vec_2 v)" + +definition ID :: "mat2" where "ID = mat 1 0 0 1" +declare mat_det.simps[simp del] + +subsubsection \Properties of 2x2 matrices\ +lemma mat_neutral_element: "mat_mul ID N = N" by (auto simp: ID_def) + +lemma mat_associativity: "mat_mul (mat_mul D B) C = mat_mul D (mat_mul B C)" + apply auto by algebra+ + +lemma mat_exp_law: "mat_mul (mat_pow n M) (mat_pow m M) = mat_pow (n+m) M" + apply (induction n, auto) by (metis mat2.sel(1,2) mat_associativity mat_mul.simps)+ + +lemma mat_exp_law_mult: "mat_pow (n*m) M = mat_pow n (mat_pow m M)" (is "?P n") + apply (induction n, auto) using mat_exp_law by (metis mat_mul.simps) + +lemma det_mult: "mat_det (mat_mul M1 M2) = (mat_det M1) * (mat_det M2)" + by (auto simp: mat_det.simps algebra_simps) + +subsubsection \Special second-order recurrent sequences\ +text \Equation 3.2\ +fun \:: "nat \ nat \ int" where + "\ b 0 = 0" | + "\ b (Suc 0) = 1" | + alpha_n: "\ b (Suc (Suc n)) = (int b) * (\ b (Suc n)) - (\ b n)" + +text \Equation 3.3\ +lemma alpha_strictly_increasing: + shows "int b \ 2 \ \ b n < \ b (Suc n) \ 0 < \ b (Suc n)" +proof (induct n) + case 0 + show ?case by simp +next + case (Suc n) + have pos: "0 < \ b (Suc n)" by (simp add:Suc) + have "\ b (Suc n) \ (int b) * (\ b (Suc n)) - \ b (Suc n)" using pos Suc by simp + also have "... < \ b (Suc (Suc n))" by (simp add: Suc) + finally show ?case using pos Suc by simp +qed + +lemma alpha_strictly_increasing_general: + fixes b n m::nat + assumes "b > 2 \ m > n" + shows "\ b m > \ b n" +proof - + from alpha_strictly_increasing assms have S2: "\ b n < \ b m" + by (smt less_imp_of_nat_less lift_Suc_mono_less of_nat_0_less_iff pos2) + show ?thesis using S2 by simp +qed + + +text \Equation 3.4\ +lemma alpha_superlinear: "b > 2 \ int n \ \ b n" + apply (induction n, auto) + by (smt Suc_1 alpha_strictly_increasing less_imp_of_nat_less of_nat_1 of_nat_Suc) + +text \A simple consequence that's often useful; could also be generalized to alpha using + alpha linear\ + +lemma alpha_nonnegative: + shows "b > 2 \ \ b n \ 0" + using of_nat_0_le_iff alpha_superlinear order_trans by blast + +text \Equation 3.5\ +lemma alpha_linear: "\ 2 n = n" +proof(induct n rule: nat_less_induct) + case (1 n) + have s0: "n=0 \ \ 2 n = n" by simp + have s1: "n=1 \ \ 2 n = n" by simp + note hyp = \\m < n. \ 2 m = m\ + from hyp have s2: "n>1 \ \ 2 (n-1) = n-1 \ \ 2 (n-2) = n-2" by simp + have s3: "n>1 \ \ 2 (Suc (Suc (n-2))) = 2*\ 2 (Suc (n-2)) - \ 2 (n-2)" by simp + have s4: "n>1 \ Suc (Suc (n-2)) = n" by simp + have s5: "n>1 \ Suc (n-2) = n-1" by simp + from s3 s4 s5 have s6: "n>1 \ \ 2 n = 2*\ 2 (n-1) - \ 2 (n-2)" by simp + from s2 s6 have s7: "n>1 \ \ 2 n = 2*(n-1) - (n-2)" by simp + from s7 have s8: "n>1 \ \ 2 n = n" by simp + from s0 s1 s8 show ?case by linarith +qed + +text \Equation 3.6 (modified)\ +lemma alpha_exponential_1: "b > 0 \ int b ^ n \ \ (b + 1) (n+1)" +proof(induction n) +case 0 + thus ?case by(simp) +next + case (Suc n) + hence "((int b)*(int b)^n) \ (int b)*(\ (b+1) (n+1))" by simp + hence r2: "((int b)^(Suc n)) \ (int (b+1))*(\ (b+1) (n+1)) - (\ (b+1) (n+1))" + by (simp add: algebra_simps) + have "(int b+1) *(\ (b+1) (n+1)) - (\ (b+1) (n+1)) \ (int b+1)*(\ (b+1) (n+1)) - \ (b+1) n" + using alpha_strictly_increasing Suc by (smt Suc_eq_plus1 of_nat_0_less_iff of_nat_Suc) + thus ?case using r2 by auto +qed + +lemma alpha_exponential_2: "int b>2 \ \ b (n+1) \ (int b)^(n)" +proof(induction n) + case 0 + thus ?case by simp +next + case (Suc n) + hence s1: "\ b (n+2) \ (int b)^(n+1) - \ b n" by simp + have "(int b)^(n+1) - (\ b n) \ (int b)^(n+1)" + using alpha_strictly_increasing Suc by (smt \.simps(1) alpha_superlinear of_nat_1 of_nat_add + of_nat_le_0_iff of_nat_less_iff one_add_one) + thus ?case using s1 by simp +qed + +subsubsection \First order relation\ +text \Equation 3.7 - Definition of A\ +fun A :: "nat \ nat \ mat2" where + "A b 0 = mat 1 0 0 1" | + A_n: "A b n = mat (\ b (n + 1)) (-(\ b n)) (\ b n) (-(\ b (n - 1)))" + +text \Equation 3.9 - Definition of B\ +fun B :: "nat \ mat2" where + "B b = mat (int b) (-1) 1 0" + +declare A.simps[simp del] +declare B.simps[simp del] + +text \Equation 3.8\ +lemma A_rec: "b>2 \ A b (Suc n) = mat_mul (A b n) (B b)" + by (induction n, auto simp: A.simps B.simps) + +text \Equation 3.10\ +lemma A_pow: "b>2 \ A b n = mat_pow n (B b)" + apply (induction n, auto simp: A.simps B.simps) + subgoal by (smt A.elims Suc_eq_plus1 \.simps \.simps(2) mat2.sel) + subgoal for n apply (cases "n=0", auto) + using A.simps(2)[of b "n-1"] gr0_conv_Suc mult.commute by auto + subgoal by (metis A.simps(2) Suc_eq_plus1 \.simps(2) mat2.sel(1) mat_pow.elims) + subgoal by (metis A.simps(2) \.simps(1) add.inverse_neutral mat2.sel(2) mat_pow.elims) + done + + +subsubsection \Characteristic equation\ +text \Equation 3.11\ +lemma A_det: "b>2 \ mat_det (A b n) = 1" + apply (auto simp: A_pow, induction n, simp add: mat_det.simps) + using det_mult apply (auto simp del: mat_mul.simps) by (simp add: B.simps mat_det.simps) + +text \Equation 3.12\ +lemma alpha_det1: + assumes "b>2" + shows "(\ b (Suc n))^2 - (int b) * \ b (Suc n) * \ b n + (\ b n)^2 = 1" +proof(cases "n = 0") + case True + thus ?thesis by auto +next + case False + hence "A b n = mat (\ b (n + 1)) (-(\ b n)) (\ b n) (-(\ b (n - 1)))" using A.elims neq0_conv by blast + hence "mat_det (A b n) = (\ b n)^2 - (\ b (Suc n)) * \ b (n-1)" + apply (auto simp: mat_det.simps) by (simp add: power2_eq_square) + moreover hence "... = (\ b (Suc n))^2 - b * (\ b (Suc n)) * \ b n + (\ b n)^2" + using False alpha_n[of b "n-1"] apply(auto simp add: algebra_simps) + by (metis Suc_1 distrib_left mult.commute mult.left_commute power_Suc power_one_right) + ultimately show ?thesis using A_det assms by auto +qed + +text \Equation 3.12\ +lemma alpha_det2: + assumes "b>2" "n>0" + shows "(\ b (n-1))^2 - (int b) * (\ b (n-1) * (\ b n)) + (\ b n)^2 = 1" + using alpha_det1 assms by (smt One_nat_def Suc_diff_Suc diff_zero mult.commute mult.left_commute) + +text \Equations 3.14 to 3.17\ +lemma alpha_char_eq: + fixes x y b:: nat + shows "(y < x \ x * x + y * y = 1 + b * x * y) \ (\m. int y = \ b m \ int x = \ b (Suc m))" +proof (induct y arbitrary: x rule:nat_less_induct) + case (1 n) + + note pre = \n < x \ (x * x + n * n = 1 + b * x * n)\ + + have h0: "int (x * x + n * n) = int (x * x) + int (n * n)" by simp + from pre h0 have pre1: "int x * int x + int(n * n) = int 1 + int(b * x * n)" by simp + + have i0: "int (n * n) = int n * int n" by simp + have i1: "int (b * x * n) = int b * int x * int n" by simp + from pre1 i0 i1 have pre2: "int x * int x + int n * int n = 1 + int b * int x * int n" by simp + + from pre2 have j0: "int n * int n - 1 = int b * int x * int n - int x * int x" by simp + have j1:"\ = int x * (int b * int n - int x)" by (simp add: right_diff_distrib) + from j0 j1 have pre3:"int n * int n - 1 = int x * (int b * int n - int x)" by simp + + have k0: "int n * int n - 1 < int n * int n" by simp + from pre3 k0 have k1:"int n * int n > int x * (int b * int n - int x)" by simp + from pre have k2: "int n \ int x" by simp + from k2 have k3: "int x * int n \ int n * int n" by (simp add: mult_mono) + from k1 k3 have k4: "int x * int n > int x * (int b * int n - int x)" by linarith + from pre k4 have k5: "int n > int b * int n - int x" by simp + + from pre have l0:"n = 0 \ x = 1" by simp + from l0 have l1: "n = 0 \ x = Suc 0" by simp + from l1 have l2: "n = 0 \ int n = \ b 0 \ int x = \ b (Suc 0)" by simp + from l2 have l3: "n = 0 \ \m. int n = \ b m \ int x = \ b (Suc m)" by blast + + have m0: "n > 0 \ int n * int n - 1 \ 0" by simp + from pre3 m0 have m1: "n > 0 \ int x * (int b * int n - int x) \ 0" by simp + from m1 have m2: "n > 0 \ int b * int n - int x \ 0" using zero_le_mult_iff by force + + from j0 have n0: "int x * int x - int b * int x * int n + int n * int n = 1" by simp + have n1: "(int b * int n - int x) * (int b * int n - int x) = int b * int n * (int b * int n - int x) - int x * (int b * int n - int x)" by (simp add: left_diff_distrib) + from n1 have n2: "int n * int n - int b * int n * (int b * int n - int x) + (int b * int n - int x) * (int b * int n - int x) = int n * int n - int x * (int b * int n - int x)" by simp + from n0 n2 j1 have n3: "int n * int n - int b * int n * (int b * int n - int x) + (int b * int n - int x) * (int b * int n - int x) = 1" by linarith + from n3 have n4: "int n * int n + (int b * int n - int x) * (int b * int n - int x) = 1 + int b * int n * (int b * int n - int x)" by simp + have n5: "int b * int n = int (b * n)" by simp + from n5 m2 have n6: "n > 0 \ int b * int n - int x = int (b * n - x)" by linarith + from n4 n6 have n7: "n > 0 \ int (n * n + (b * n - x) * (b * n - x)) = int (1 + b * n * (b * n - x))" by simp + from n7 have n8: "n > 0 \ n * n + (b * n - x) * (b * n - x) = 1 + b * n * (b * n - x)" using of_nat_eq_iff by blast + + note hyp = \\mx. m < x \ x * x + m * m = 1 + b * x * m \ + (\ma. int m = \ b ma \ int x = \ b (Suc ma))\ + + from k5 n6 n8 have o0: "n > 0 \ (b * n - x) < n \ n * n + (b * n - x) * (b * n - x) = 1 + b * n * (b * n - x)" by simp + from o0 hyp have o1: "n > 0 \ (\ma. int (b * n - x) = \ b ma \ int n = \ b (Suc ma))" by simp + + from o1 l3 n6 show ?case by force +qed + +lemma alpha_char_eq2: + assumes "(x*x + y*y = 1 + b * x * y)" "b>2" + shows "(\n. int x = \ b n)" +proof - + have "x \ y" + proof(rule ccontr, auto) + assume "x=y" + hence "2*x*x = 1+b*x*x" using assms by simp + hence "2*x*x \ 1+2*x*x" using assms by (metis add_le_mono le_less mult_le_mono1) + thus False by auto + qed + thus ?thesis + proof(cases "xn. int x = \ b n \ int y = \ b (Suc n)" using alpha_char_eq assms + by (simp add: add.commute power2_eq_square) + thus ?thesis by auto + next + case False + hence "\j. int y = \ b j \ int x = \ b (Suc j)" using alpha_char_eq assms \x \ y\ by auto + thus ?thesis by blast + qed +qed + + +subsubsection \Divisibility properties\ +text \The following lemmas are needed in the proof of equation 3.25\ +lemma representation: + fixes k m :: nat + assumes "k > 0" "n = m mod k" "l = (m-n)div k" + shows "m = n+k*l \ 0\n \ n\k-1" by (metis Suc_pred' assms le_add2 le_add_same_cancel2 + less_Suc_eq_le minus_mod_eq_div_mult minus_mod_eq_mult_div mod_div_mult_eq + mod_less_divisor neq0_conv nonzero_mult_div_cancel_left) + +lemma div_3251: + fixes b k m:: nat + assumes "b>2" and "k>0" + defines "n \ m mod k" + defines "l \ (m-n) div k" + shows "A b m = mat_mul (A b n) (mat_pow l (A b k))" +proof - + from assms(2) l_def n_def representation have m: "m = n+k*l \ 0\n \ n\k-1" by simp + from A_pow assms(1) have Abm2: "A b m = mat_pow m (B b)" by simp + from m have Bm: "mat_pow m (B b) =mat_pow (n+k*l) (B b)" by simp + from mat_exp_law have as1: "mat_pow (n+k*l) (B b) + = mat_mul (mat_pow n (B b)) (mat_pow (k*l) (B b))" by simp + from mat_exp_law_mult have as2: "mat_pow (k*l) (B b) = mat_pow l (mat_pow k (B b))" + by (metis mult.commute) + from A_pow assms have Abn: "mat_pow n (B b) = A b n" by simp + from A_pow assms(1) have Ablk: "mat_pow l (mat_pow k (B b)) = mat_pow l (A b k)" by simp + from Ablk Abm2 Abn Bm as1 as2 show Abm: "A b m = mat_mul (A b n) (mat_pow l (A b k))" by simp +qed + +lemma div_3252: + fixes a b c d m :: int and l :: nat + defines "M \ mat a b c d" + assumes "mat_21 M mod m = 0" + shows "(mat_21 (mat_pow l M)) mod m = 0 " (is "?P l") +proof(induction l) + show "?P 0" by simp +next + fix l assume IH: "?P l" + define Ml where "Ml = mat_pow l M" + have S1: "mat_pow (Suc(l)) M = mat_mul M (mat_pow l M)" by simp + have S2: "mat_21 (mat_mul M Ml) = mat_21 M * mat_11 Ml + mat_22 M * mat_21 Ml" + by (rule_tac mat_mul.induct mat_plus.induct, auto) + have S3: "mat_21 (mat_pow (Suc(l)) M) = mat_21 M * mat_11 Ml + mat_22 M * mat_21 Ml" + using S1 S2 Ml_def by simp + from assms(2) have S4: "(mat_21 M * mat_11 Ml) mod m = 0" by auto + from IH Ml_def have S5: " mat_22 M * mat_21 Ml mod m = 0" by auto + from S4 S5 have S6: "(mat_21 M * mat_11 Ml + mat_22 M * mat_21 Ml) mod m = 0" by auto + from S3 S6 show "?P (Suc(l))" by simp +qed + +lemma div_3253: + fixes a b c d m:: int and l :: nat + defines "M \ mat a b c d" + assumes "mat_21 M mod m = 0" + shows "((mat_11 (mat_pow l M)) - a^l) mod m = 0" (is "?P l") +proof(induction l) + show "?P 0" by simp +next + fix l assume IH: "?P l" + define Ml where "Ml = mat_pow l M" + from Ml_def have S1: "mat_pow (Suc(l)) M = mat_mul M Ml" by simp + have S2: "mat_11 (mat_mul M Ml) = mat_11 M * mat_11 Ml + mat_12 M * mat_21 Ml" + by (rule_tac mat_mul.induct mat_plus.induct, auto) + hence S3: "mat_11 (mat_pow (Suc(l)) M) = mat_11 M * mat_11 Ml + mat_12 M * mat_21 Ml" + using S1 by simp + from M_def Ml_def assms(2) div_3252 have S4: "mat_21 Ml mod m = 0" by auto + from IH Ml_def have S5: "(mat_11 Ml - a ^ l) mod m = 0" by auto + from IH M_def have S6: "(mat_11 M -a) mod m = 0" by simp + from S4 have S7: "(mat_12 M * mat_21 Ml) mod m = 0" by auto + from S5 S6 have S8: "(mat_11 M * mat_11 Ml- a^(Suc(l))) mod m = 0" + by (metis M_def mat2.sel(1) mod_0 mod_mult_right_eq mult_zero_right power_Suc right_diff_distrib) + have S9: "(mat_11 M * mat_11 Ml - a^(Suc(l)) + mat_12 M * mat_21 Ml ) mod m = 0" + using S7 S8 by auto + from S9 have S10: "(mat_11 M * mat_11 Ml + mat_12 M * mat_21 Ml - a^(Suc(l))) mod m = 0" by smt + from S3 S10 show "?P (Suc(l))" by auto +qed + +text \Equation 3.25\ +lemma divisibility_lemma1: + fixes b k m:: nat + assumes "b>2" and "k>0" + defines "n \ m mod k" + defines "l \ (m-n) div k" + shows "\ b m mod \ b k = \ b n * (\ b (k+1)) ^ l mod \ b k" +proof - + from assms(2) l_def n_def representation have m: "m = n+k*l \ 0\n \ n\k-1" by simp + consider (eq0) "n = 0" | (neq0) "n > 0" by auto + thus ?thesis + proof cases + case eq0 + have Abm_gen: "A b m = mat_mul (A b n) (mat_pow l (A b k))" + using assms div_3251 l_def n_def by blast + have Abk: "mat_pow l (A b k) = mat_pow l (mat (\ b (k+1)) (-\ b k) (\ b k) (-\ b (k-1)))" + using assms(2) neq0_conv by (metis A.elims) + from eq0 have Abm: "A b m = mat_pow l (mat (\ b (k+1)) (-\ b k) (\ b k) (-\ b (k-1)))" + using A_pow \b>2\ apply (auto simp: A.simps B.simps) + by (metis Abk Suc_eq_plus1 add.left_neutral m mat_exp_law_mult mult.commute) + have Abm1: "mat_21 (A b m) = \ b m" by (metis A.elims \.simps(1) mat2.sel(3)) + have Abm2: "mat_21 (mat_pow l (mat (\ b (k+1)) (-\ b k) (\ b k) (-\ b (k-1)))) mod (\ b k) = 0" + using Abm div_3252 by simp + from Abm Abm1 Abm2 have MR0: "\ b m mod \ b k = 0" by simp + from MR0 eq0 show ?thesis by simp + next case neq0 + from assms have Abm_gen: "A b m = mat_mul (A b n) (mat_pow l (A b k))" + using div_3251 l_def n_def by blast + from assms(2) neq0_conv have Abk: "mat_pow l (A b k) + = mat_pow l (mat (\ b (k+1)) (-\ b k) (\ b k) (-\ b (k-1)))" by (metis A.elims) + from n_def neq0 have N0: "n>0" by simp + define M where "M = mat (\ b (n + 1)) (-(\ b n)) (\ b n) (-(\ b (n - 1)))" + define N where "N = mat_pow l (mat (\ b (k+1)) (-\ b k) (\ b k) (-\ b (k-1)))" + from Suc_pred' neq0 have Abn: "A b n = mat (\ b (n + 1)) (-(\ b n)) (\ b n) (-(\ b (n - 1)))" + by (metis A.elims neq0_conv) + from Abm_gen Abn Abk M_def N_def have Abm: "A b m = mat_mul M N" by simp + (* substitutions done! next: calculations *) + from Abm have S1: "mat_21 (mat_mul M N) = mat_21 M * mat_11 N + mat_22 M * mat_21 N" + by (rule_tac mat_mul.induct mat_plus.induct, auto) + have S2: "mat_21 (A b m) = \ b m" by (metis A.elims \.simps(1) mat2.sel(3)) + from S1 S2 Abm have S3: "\ b m = mat_21 M * mat_11 N + mat_22 M * mat_21 N" by simp + from S3 have S4: "(\ b m - (mat_21 M * mat_11 N + mat_22 M * mat_21 N)) mod (\ b k) = 0" by simp + from M_def have S5: "mat_21 M = \ b n" by simp + from div_3253 N_def have S6: "(mat_11 N - (\ b (k+1)) ^ l) mod (\ b k) = 0" by simp + from N_def Abm div_3252 have S7: "mat_21 N mod (\ b k) = 0" by simp + from S4 S7 have S8: "(\ b m - mat_21 M * mat_11 N) mod (\ b k) = 0" by algebra + from S5 S6 have S9: "(mat_21 M * mat_11 N - (\ b n) * (\ b (k+1)) ^ l) mod (\ b k) = 0" + by (metis mod_0 mod_mult_left_eq mult.commute mult_zero_left right_diff_distrib') + from S8 S9 show ?thesis + proof - + have "(mat_21 M * mat_11 N - \ b m) mod \ b k = 0" + using S8 by presburger + hence "\i. (\ b m - (mat_21 M * mat_11 N - i)) mod \ b k = i mod \ b k" + by (metis (no_types) add.commute diff_0_right diff_diff_eq2 mod_diff_right_eq) + thus ?thesis + by (metis (no_types) S9 diff_0_right mod_diff_right_eq) + qed + qed + qed + +text \Prerequisite lemma for 3.27\ +lemma div_coprime: + assumes "b>2" "n \ 0" + shows "coprime (\ b k) (\ b (k+1))" (is "?P") +proof(rule ccontr) + assume as: "\ ?P" + define n where "n = gcd (\ b k) (\ b (k+1))" + from n_def have S1: "n > 1" + using alpha_det1 as assms(1) coprime_iff_gcd_eq_1 gcd_pos_int right_diff_distrib' + by (smt add.commute plus_1_eq_Suc) + have S2: "(\ b (Suc k))^2 - (int b) * \ b (Suc k) * (\ b k) + (\ b k)^2 = 1" + using alpha_det1 assms by auto + from n_def have D1: " n dvd (\ b (k+1))^2" by (simp add: numeral_2_eq_2) + from n_def have D2: " n dvd (- (int b) * \ b (k+1) * (\ b k))" by simp + from n_def have D3: "n dvd (\ b k)^2" by (simp add: gcd_dvdI1) + have S3: "n dvd ((\ b (Suc k))^2 - (int b) * \ b (Suc k) * (\ b k) + (\ b k)^2)" + using D1 D2 D3 by simp + from S2 S3 have S4: "n dvd 1" by simp + from S4 n_def as is_unit_gcd show "False" by blast +qed + +text \Equation 3.27\ +lemma divisibility_lemma2: + fixes b k m:: nat + assumes "b>2" and "k>0" + defines "n \ m mod k" + defines "l \ (m-n) div k" + assumes "\ b k dvd \ b m" + shows "\ b k dvd \ b n" +proof - + from assms(2) l_def n_def representation have m: "0\n \ n\k-1" by simp + from divisibility_lemma1 assms(1) assms(2) l_def n_def have S1: + "(\ b m) mod (\ b k) = (\ b n) * (\ b (k+1)) ^ l mod (\ b k)" by blast + from S1 assms(5) have S2: "(\ b k) dvd ((\ b n) * (\ b (k+1)) ^ l)" by auto + show ?thesis + using S1 div_coprime S2 assms(1) apply auto + using coprime_dvd_mult_left_iff coprime_power_right_iff by blast +qed + +text \Equation 3.23 - main result of this section\ +theorem divisibility_alpha: + assumes "b>2" and "k>0" + shows "\ b k dvd \ b m \ k dvd m" (is "?P \ ?Q") +proof + assume Q: "?Q" + define n where "n = m mod k" + have N: "n=0" by (simp add: Q n_def) + from N have Abn: "\ b n = 0" by simp + from Abn divisibility_lemma1 assms(1) assms(2) mult_eq_0_iff n_def show "?P" + by (metis dvd_0_right dvd_imp_mod_0 mod_0_imp_dvd) +next + assume P: "?P" + define n where "n = m mod k" + define l where "l = (m-n) div k" + define B where "B = (mat (int b) (-1) 1 0)" + have S1: "(\ b n) mod (\ b k) = 0" + using divisibility_lemma2 assms(1) assms(2) n_def P by simp + from n_def assms(2) have m: "n < k" using mod_less_divisor by blast + from alpha_strictly_increasing m assms(1) have S2: "\ b n < \ b k" + by (smt less_imp_of_nat_less lift_Suc_mono_less of_nat_0_less_iff pos2) + from S1 S2 have S3: "n=0" + by (smt alpha_superlinear assms(1) mod_pos_pos_trivial neq0_conv of_nat_0_less_iff) + from S3 n_def show "?Q" by auto +qed + +subsubsection \Divisibility properties (continued)\ + +text \Equation 3.28 - main result of this section\ + +lemma divisibility_equations: + assumes 0: "m = k*l" and "b>2" "m>0" + shows "A b m = mat_pow l (mat_minus (mat_scalar_mult (\ b k) (B b)) + (mat_scalar_mult (\ b (k-1)) ID))" + apply (auto simp del: mat_pow.simps mat_mul.simps mat_minus.simps mat_scalar_mult.simps + simp add: A_pow mult.commute[of k l] assms mat_exp_law_mult) + using A_pow[of b k] \m>0\ + apply (auto simp: A.simps \m>0\ ID_def B.simps) + using A.simps(2) alpha_n One_nat_def Suc_eq_plus1 Suc_pred assms \m>0\ assms + mult.commute nat_0_less_mult_iff + by (smt mat_exp_law_mult) + +lemma divisibility_cong: + fixes e f :: int + fixes l :: nat + fixes M :: mat2 + assumes "mat_22 M = 0" "mat_21 M = 1" + shows "(mat_21 (mat_pow l (mat_minus (mat_scalar_mult e M) (mat_scalar_mult f ID)))) mod e^2 = (-1)^(l-1)*l*e*f^(l-1)*(mat_21 M) mod e^2 + \ mat_22 (mat_pow l (mat_minus (mat_scalar_mult e M) (mat_scalar_mult f ID))) mod e^2 = (-1)^l *f^l mod e^2" +(is "?P l \ ?Q l" ) +proof(induction l) + case 0 + then show ?case by simp +next + case (Suc l) + have S2: "mat_pow (Suc(l)) (mat_minus (mat_scalar_mult e M) (mat_scalar_mult f ID)) = + mat_mul (mat_pow l (mat_minus (mat_scalar_mult e M) (mat_scalar_mult f ID))) (mat_minus (mat_scalar_mult e M) (mat_scalar_mult f ID))" + using mat_exp_law[of l _ 1] mat2.sel by (auto, metis)+ + define a1 where "a1 = mat_11 (mat_minus (mat_scalar_mult e M) (mat_scalar_mult f ID))" + define b1 where "b1 = mat_12 (mat_minus (mat_scalar_mult e M) (mat_scalar_mult f ID))" + define c1 where "c1 = mat_21 (mat_minus (mat_scalar_mult e M) (mat_scalar_mult f ID))" + define d1 where "d1 = mat_22 (mat_minus (mat_scalar_mult e M) (mat_scalar_mult f ID))" + define a where "a = mat_11 M" + define b where "b = mat_12 M" + define c where "c = mat_21 M" + define d where "d = mat_22 M" + define g where "g = mat_21 (mat_pow l (mat_minus (mat_scalar_mult e M) (mat_scalar_mult f ID)))" + define h where "h = mat_22 (mat_pow l (mat_minus (mat_scalar_mult e M) (mat_scalar_mult f ID)))" + from S2 g_def a1_def h_def c1_def have S3: "mat_21 (mat_pow (Suc(l)) (mat_minus (mat_scalar_mult e M) (mat_scalar_mult f ID))) = g*a1 + h*c1" + by simp + from S2 g_def b1_def h_def d1_def have S4: "mat_22 (mat_pow (Suc(l)) (mat_minus (mat_scalar_mult e M) (mat_scalar_mult f ID))) + = g*b1+h*d1" by simp + have S5: "mat_11 (mat_scalar_mult e M) = e*a" by (simp add: a_def) + have S6: "mat_12 (mat_scalar_mult e M) = e*b" by (simp add: b_def) + have S7: "mat_21 (mat_scalar_mult e M) = e*c" by (simp add: c_def) + have S8: "mat_22 (mat_scalar_mult e M) = e*d" by (simp add: d_def) + from a1_def S5 have S9: "a1 = e*a-f"by (simp add: Exp_Matrices.ID_def) + from b1_def S6 have S10: "b1 = e*b" by (simp add: Exp_Matrices.ID_def) + from c1_def S7 have S11: "c1 = e*c" by (simp add: Exp_Matrices.ID_def) + from S11 assms(2) c_def have S115: "c1 = e" by simp + from d1_def S8 have S12: "d1 = e*d - f" by (simp add: Exp_Matrices.ID_def) + from S12 assms(1) d_def have S125: "d1 = - f" by simp + from assms(2) c_def Suc g_def c_def have S13: "g mod e^2 = (-1)^(l-1)*l*e*f^(l-1)*c mod e^2" by blast + from assms(2) c_def S13 have S135: "g mod e^2 = (-1)^(l-1)*l*e*f^(l-1) mod e^2" by simp + from Suc h_def have S14: "h mod e^2 = (-1)^l *f^l mod e^2" by simp + from S10 S135 have S27: "g*b1 mod e^2 = (-1)^(l-1)*l*e*f^(l-1)*e*b mod e^2" by (metis mod_mult_left_eq mult.assoc) + from S27 have S28: "g*b1 mod e^2 = 0 mod e^2" by (simp add: power2_eq_square) + from S125 S14 mod_mult_cong have S29: "h*d1 mod e^2 = (-1)^l *f^l*(- f) mod e^2" by blast + from S29 have S30: "h*d1 mod e^2 = (-1)^(l+1) *f^l*f mod e^2" by simp + from S30 have S31: "h*d1 mod e^2 = (-1)^(l+1) *f^(l+1) mod e^2" by (metis mult.assoc power_add power_one_right) + from S31 have F2: "?Q (Suc(l))" by (metis S28 S4 Suc_eq_plus1 add.left_neutral mod_add_cong) + from S9 S13 have S15: "g*a1 mod e^2 = ((-1)^(l-1)*l*e*f^(l-1)*c*(e*a-f))mod e^2" by (metis mod_mult_left_eq) + have S16: "((-1)^(l-1)*l*e*f^(l-1)*c*(e*a-f)) = ((-1)^(l-1)*l*e^2*f^(l-1)*c*a) - f*(-1)^(l-1)*l*e*f^(l-1)*c" by algebra + have S17: "((-1)^(l-1)*l*e^2*f^(l-1)*c*a) mod e^2 = 0 mod e^2" by simp + from S17 have S18: "(((-1)^(l-1)*l*e^2*f^(l-1)*c*a) - f*(-1)^(l-1)*l*e*f^(l-1)*c) mod e^2 = + - f*(-1)^(l-1)*l*e*f^(l-1)*c mod e^2" + proof - + have f1: "\i ia. (ia::int) - (0 - i) = ia + i" + by auto + have "\i ia. ((0::int) - ia) * i = 0 - ia * i" + by auto + then show ?thesis using f1 + proof - + have f1: "\i. (0::int) - i = - i" + by presburger + then have "\i. (i - - ((- 1) ^ (l - 1) * int l * e\<^sup>2 * f ^ (l - 1) * c * a)) mod e\<^sup>2 = i mod e\<^sup>2" + by (metis (no_types) S17 \\i ia. ia - (0 - i) = ia + i\ add.right_neutral mod_add_right_eq) + then have "\i. ((- 1) ^ (l - 1) * int l * e\<^sup>2 * f ^ (l - 1) * c * a - i) mod e\<^sup>2 = - i mod e\<^sup>2" + using f1 by (metis \\i ia. ia - (0 - i) = ia + i\ uminus_add_conv_diff) + then show ?thesis + using f1 \\i ia. (0 - ia) * i = 0 - ia * i\ by presburger + qed + qed + from S15 S16 S18 have S19: "g*a1 mod e^2 = - f*(-1)^(l-1)*l*e*f^(l-1)*c mod e^2" by presburger + from S11 S14 have S20: "h*c1 mod e^2 = (-1)^l *f^l*e*c mod e^2" by (metis mod_mult_left_eq mult.assoc) + from S19 S20 have S21: "(g*a1 + h*c1) mod e^2 = (- f*(-1)^(l-1)*l*e*f^(l-1)*c + (-1)^l *f^l*e*c) mod e^2" using mod_add_cong by blast + from assms(2) c_def have S22: "(- f*(-1)^(l-1)*l*e*f^(l-1)*c + (-1)^l *f^l*e*c) mod e^2=(- f*(-1)^(l-1)*l*e*f^(l-1) + (-1)^l *f^l*e) mod e^2" by simp + have S23: "(- f*(-1)^(l-1)*l*e*f^(l-1) + (-1)^l *f^l*e) mod e^2 = (f*(-1)^(l)*l*e*f^(l-1) + (-1)^l *f^l*e) mod e^2" + by (smt One_nat_def Suc_pred mult.commute mult_cancel_left2 mult_minus_left neq0_conv of_nat_eq_0_iff power.simps(2)) + have S24: "(f*(-1)^(l)*l*e*f^(l-1) + (-1)^l *f^l*e) mod e^2 = ((-1)^(l)*l*e*f^l + (-1)^l *f^l*e) mod e^2" + by (smt One_nat_def Suc_pred mult.assoc mult.commute mult_eq_0_iff neq0_conv of_nat_eq_0_iff power.simps(2)) + have S25: "((-1)^(l)*l*e*f^l + (-1)^l *f^l*e) mod e^2 = ((-1)^(l)*(l+1)*e*f^l) mod e^2" + proof - + have f1: "\i ia. (ia::int) * i = i * ia" + by simp + then have f2: "\i ia. (ia::int) * i - - i = i * (ia - - 1)" + by (metis (no_types) mult.right_neutral mult_minus_left right_diff_distrib') + have "\n. int n - - 1 = int (n + 1)" + by simp + then have "e * (f ^ l * (int l * (- 1) ^ l - - ((- 1) ^ l))) mod e\<^sup>2 = e * (f ^ l * ((- 1) ^ l * int (l + 1))) mod e\<^sup>2" + using f2 by presburger + then have "((- 1) ^ l * int l * e * f ^ l - - ((- 1) ^ l) * f ^ l * e) mod e\<^sup>2 = (- 1) ^ l * int (l + 1) * e * f ^ l mod e\<^sup>2" + using f1 + proof - + have f1: "\i ia ib. (i::int) * (ia * ib) = ia * (i * ib)" + by simp + then have "\i ia ib. (i::int) * (ia * ib) - - (i * ib) = (ia - - 1) * (i * ib)" + by (metis (no_types) \\i ia. ia * i = i * ia\ f2) + then show ?thesis + using f1 by (metis (no_types) \\i ia. ia * i = i * ia\ \e * (f ^ l * (int l * (- 1) ^ l - - ((- 1) ^ l))) mod e\<^sup>2 = e * (f ^ l * ((- 1) ^ l * int (l + 1))) mod e\<^sup>2\ f2 mult_minus_right) + qed + then show ?thesis + by simp + qed + from S21 S22 S23 S24 S25 have S26: "(g*a1 + h*c1) mod e^2 = ((-1)^(l)*(l+1)*e*f^l) mod e^2" by presburger + from S3 S26 have F1: "?P (Suc(l))" by (metis Suc_eq_plus1 assms(2) diff_Suc_1 mult.right_neutral) + from F1 F2 show ?case by simp +qed + +lemma divisibility_congruence: + assumes "m = k*l" and "b>2" "m>0" + shows "\ b m mod (\ b k)^2 = ((-1)^(l-1)*l*(\ b k)*(\ b (k-1))^(l-1)) mod (\ b k)^2" +proof - + have S0: "\ b m = mat_21 (A b m)" by (metis A.elims assms(3) mat2.sel(3) neq0_conv) + from assms S0 divisibility_equations have S1: "\ b m = + mat_21 ( mat_pow l (mat_minus (mat_scalar_mult (\ b k) (B b)) + (mat_scalar_mult (\ b (k-1)) ID)))" by auto + have S2: "mat_21 (B b) = 1" using Binomial.binomial_ring by (simp add: Exp_Matrices.B.simps) + have S3: "mat_22 (B b) = 0" by (simp add: Exp_Matrices.B.simps) + from S1 S2 S3 divisibility_cong show ?thesis by (metis mult.right_neutral) +qed + +text \ Main result section 3.5 \ +theorem divisibility_alpha2: + assumes "b>2" "m>0" + shows "(\ b k)^2 dvd (\ b m) \ k*(\ b k) dvd m" (is "?P \ ?Q") +proof + assume Q: "?Q" + then show "?P" + proof(cases "k dvd m") + case True + then obtain l where mkl: "m = k * l" by blast + from Q assms mkl have S0: "l mod \ b k = 0" by simp + from S0 have S1: "l*(\ b k) mod (\ b k)^2 = 0" by (simp add: power2_eq_square) + from S1 have S2: "((-1)^(l-1)*l*(\ b k)*(\ b (k-1))^(l-1)) mod (\ b k)^2 = 0" + proof - + have "\i. \ b k * (int l * i) mod (\ b k)\<^sup>2 = 0" + by (metis (no_types) S1 mod_0 mod_mult_left_eq mult.assoc mult.left_commute mult_zero_left) + then show ?thesis + by (simp add: mult.assoc mult.left_commute) + qed + from assms divisibility_congruence mkl have S3: + "\ b m mod (\ b k)^2 = ((-1)^(l-1)*l*(\ b k)*(\ b (k-1))^(l-1)) mod (\ b k)^2" by simp + from S2 S3 have S4: "\ b m mod (\ b k)^2 = 0" by linarith + then show ?thesis by auto + next + case False + then show ?thesis using Q dvd_mult_left int_dvd_int_iff by blast + qed +next + assume P: "?P" + show "?Q" + proof(cases "k dvd m") + case True + then obtain l where mkl: "m = k * l" by blast + from assms mkl divisibility_congruence have S0: + "\ b m mod (\ b k)^2 = ((-1)^(l-1)*l*(\ b k)*(\ b (k-1))^(l-1)) mod (\ b k)^2" by simp + from S0 P have S1: "(\ b k)^2 dvd ((-1)^(l-1)*l*(\ b k)*(\ b (k-1))^(l-1))" by auto + from S1 have S2: "(\ b k)^2 dvd l*(\ b k)*(\ b (k-1))^(l-1)" + by (metis (no_types, opaque_lifting) Groups.mult_ac(1) dvd_trans dvd_triv_right left_minus_one_mult_self) + from S2 have S3: "(\ b k) dvd l*(\ b (k-1))^(l-1)" + by (metis (full_types) Exp_Matrices.alpha_superlinear assms(1) assms(2) mkl + mult.assoc mult.commute mult_0 not_less_zero of_nat_le_0_iff power2_eq_square zdvd_mult_cancel) + from div_coprime Suc_eq_plus1 Suc_pred' assms(1) assms(2) mkl less_imp_le_nat nat_0_less_mult_iff + have S4: "coprime (\ b k) (\ b (k-1))" by (metis coprime_commute) + hence "coprime (\ b k) ((\ b (k-1))^(l-1))" using coprime_power_right_iff by blast + hence "(\ b k) dvd l" using S3 using coprime_dvd_mult_left_iff by blast + then show ?thesis by (simp add: mkl) + next + case False + then show ?thesis + apply(cases "0Congruence properties\ +text \In this section we will need the inverse matrices of A and B\ +fun A_inv :: "nat \ nat \ mat2" where + "A_inv b n = mat (-\ b (n-1)) (\ b n) (-\ b n) (\ b (n+1))" + +fun B_inv :: "nat \ mat2" where + "B_inv b = mat 0 1 (-1) b" + +lemma A_inv_aux: "b>2 \ n>0 \ \ b n * \ b n - \ b (Suc n) * \ b (n - Suc 0) = 1" + apply (induction n, auto) subgoal for n using alpha_det1[of b n] apply auto by algebra done + +lemma A_inverse[simp]: "b>2 \ n>0 \ mat_mul (A_inv b n) (A b n) = ID" + using mat2.expand[of "mat_mul (A_inv b n) (A b n)" ID] apply rule + using ID_def A.simps(2)[of _ "n-1"] ID_def apply (auto) + subgoal using mat2.sel(1)[of 1 0 0 1] apply (auto) + using A_inv_aux[of b n] by (auto simp: mult.commute) + subgoal by (metis mat2.sel(2)) + subgoal by (metis mat2.sel(3)) + subgoal using mat2.sel(4)[of 1 0 0 1] apply (auto) + using A_inv_aux[of b n] by (auto simp: mult.commute) + done + +lemma B_inverse[simp]: "mat_mul (B b) (B_inv b) = ID" using B.simps ID_def by auto + +declare A_inv.simps B_inv.simps[simp del] + + +text \Equation 3.33\ +lemma congruence: + assumes "b1 mod q = b2 mod q" + shows "\ b1 n mod q = \ b2 n mod q" +proof (induct n rule:nat_less_induct) + case (1 n) + note hyps = \\m b1 m mod q = \ b2 m mod q\ + have n0:"(\ b1 0) mod q = (\ b2 0) mod q" by simp + have n1:"(\ b1 1) mod q = (\ b2 1) mod q" by simp + from hyps have s1: "n>1\\ b1 (n-1) mod q = \ b2 (n-1) mod q" by auto + from hyps have s2: "n>1\\ b1 (n-2) mod q = \ b2 (n-2) mod q" by auto + have s3: "n>1 \ \ b1 (Suc (Suc n)) = (int b1) * (\ b1 (Suc n)) - (\ b1 n)" by simp + from s3 have s4: "n>1 \ (\ b1 n = (int b1*(\ b1 (n-1)) - \ b1 (n-2)))" + by (smt Suc_1 Suc_diff_Suc diff_Suc_1 alpha_n lessE) + have sw: "n>1 \ \ b2 (Suc (Suc n)) = (int b2) * (\ b2 (Suc n)) - (\ b2 n)" by simp + from sw have sx: "n>1 \ (\ b2 n = (int b2*(\ b2 (n-1)) - \ b2 (n-2)))" + by (smt Suc_1 Suc_diff_Suc diff_Suc_1 alpha_n lessE) + from n0 n1 s1 s2 s3 s4 assms(1) mod_mult_cong have s5: "n>1 + \ b1*(\ b1 (n-1)) mod q = b2*(\ b2 (n-1)) mod q " by (smt mod_mult_eq of_nat_mod) + from hyps have sq: "n>1 \ \ b1 (n-2) mod q = \ b2 (n-2) mod q " by simp + from s5 sq have sd: "n>1 \-( (\ b1 (n-2))) mod q = -((\ b2 (n-2))) mod q " + by (metis mod_minus_eq) + from sd s5 mod_add_cong have s6: "n>1 \ ( b1*(\ b1 (n-1)) - \ b1 (n-2)) mod q + = (b2*(\ b2 (n-1)) - \ b2 (n-2)) mod q" by force + from s4 have sa: "n>1 \( b1*(\ b1 (n-1)) - \ b1 (n-2)) mod q = (\ b1 n) mod q" by simp + from sx have sb: "n>1 \( b2*(\ b2 (n-1)) - \ b2 (n-2)) mod q = (\ b2 n) mod q" by simp + from sb sa s6 sx have s7: "n>1 \ (\ b1 n) mod q = (b2*(\ b2 (n-1)) - \ b2 (n-2)) mod q" by simp + from s7 sx s6 have s9: "\ b1 n mod q = \ b2 n mod q" + by (metis One_nat_def \.simps(1) \.simps(2) less_Suc0 nat_neq_iff) + from s9 n0 n1 show ?case by simp +qed + +text \Equation 3.34\ +lemma congruence2: + fixes b1 :: nat + assumes "b>=2" + shows "(\ b n) mod (b - 2) = n mod (b - 2)" +proof- + from alpha_linear have S1: "\ (nat 2) n = n" by simp + define q where "q = b - (nat 2)" + from q_def assms le_mod_geq have S4: "b mod q = 2 mod q" by auto + from assms S4 congruence have SN: "(\ b n) mod q = (\ 2 n) mod q" by blast + from S1 SN q_def zmod_int show ?thesis by simp +qed + +lemma congruence_jpos: + fixes b m j l :: nat + assumes "b>2" and "2*l*m+j>0" + defines "n \ 2*l*m+j" + shows "A b n = mat_mul (mat_pow l (mat_pow 2 (A b m))) (A b j)" +proof- + from A_pow assms(1) have Abm2: "A b n = mat_pow n (B b)" by simp + from Abm2 n_def have Bn: "mat_pow n (B b) =mat_pow (2*l*m+j) (B b)" by simp + from mat_exp_law have as1: "mat_pow (2*l*m+j) (B b) = mat_mul (mat_pow l (mat_pow m (mat_pow 2 (B b)))) (mat_pow (j) (B b))" + by (metis (no_types, lifting) mat_exp_law_mult mult.commute) + from A_pow assms(1) B.elims mult.commute mat_exp_law_mult have as2: "mat_mul (mat_pow l (mat_pow m (mat_pow 2 (B b)))) (mat_pow (j) (B b)) + = mat_mul (mat_pow l (mat_pow 2 (A b m))) (A b j)" by metis + from as2 as1 Abm2 Bn show ?thesis by auto +qed + + +lemma congruence_inverse: "b>2 \ mat_pow (n+1) (B_inv b) = A_inv b (n+1)" + apply (induction n, simp add: B_inv.simps, auto) by (auto simp add: B_inv.simps) + +lemma congruence_inverse2: + fixes n b :: nat + assumes "b>2" + shows "mat_mul (mat_pow n (B b)) (mat_pow n (B_inv b)) = mat 1 0 0 1" +proof(induct n) + case 0 + thus ?case by simp +next + case (Suc n) + have S1: "mat_pow (Suc(n)) (B b) = mat_mul (B b) (mat_pow n (B b))" by simp + have S2: "mat_pow (Suc(n)) (B_inv b) = mat_mul (mat_pow n (B_inv b)) (B_inv b)" + proof - + have "\i ia ib ic. mat_pow 1 (mat ic ib ia i) = mat ic ib ia i" + by simp + hence "\m ma mb. mat_pow 1 m = m \ mat_mul mb m \ ma" by (metis mat2.exhaust) + thus ?thesis + by (metis (no_types) One_nat_def add_Suc_right diff_Suc_Suc diff_zero mat_exp_law mat_pow.simps(1) mat_pow.simps(2)) + qed + define "C" where "C= (B b)" + define "D" where "D = mat_pow n C" + define "E" where "E = B_inv b" + define "F" where "F = mat_pow n E" + from S1 S2 C_def D_def E_def F_def have S3: "mat_mul (mat_pow (Suc(n)) C) (mat_pow (Suc(n)) E) = mat_mul (mat_mul C D) (mat_mul F E)" by simp + from S3 mat_associativity mat2.exhaust C_def D_def E_def F_def have S4: "mat_mul (mat_pow (Suc(n)) C) (mat_pow (Suc(n)) E) + = mat_mul C (mat_mul (mat_mul D F) E)" by metis + from S4 Suc.hyps mat_neutral_element C_def D_def E_def F_def have S5: "mat_mul (mat_pow (Suc(n)) C) (mat_pow (Suc(n)) E) = mat_mul C E" by simp + from S5 C_def E_def show ?case using B_inverse ID_def by auto +qed + +lemma congruence_mult: + fixes m :: nat + assumes "b>2" + shows "n>m ==> mat_pow (nat(int n- int m)) (B b) = mat_mul (mat_pow n (B b)) (mat_pow m (B_inv b))" +proof(induction n) + case 0 + thus ?case by simp +next + case (Suc n) + consider (eqm) "n == m" | (gm) "n < m" | (lm) "n>m" by linarith + thus ?case + proof cases + case gm + from Suc.prems gm not_less_eq show ?thesis by simp + next case lm + have S1: "mat_pow (nat(int (Suc(n)) - int m)) (B b) = mat_mul (B b) (mat_pow (nat(int n - int m)) (B b))" + by (metis Suc.prems Suc_diff_Suc diff_Suc_1 diff_Suc_Suc mat_pow.simps(2) nat_minus_as_int) + from lm S1 Suc.IH have S2: "mat_pow (nat(int (Suc(n)) - int m)) (B b) = mat_mul (B b) (mat_mul (mat_pow n (B b)) (mat_pow m (B_inv b)))" by simp + from S2 mat_associativity mat2.exhaust have S3: "mat_pow (nat(int (Suc(n)) - int m)) (B b) = mat_mul (mat_mul (B b) (mat_pow n (B b))) (mat_pow m (B_inv b))" by metis + from S3 show ?thesis by simp + next case eqm + from eqm have S1: "nat(int (Suc(n))- int m) = 1" by auto + from S1 have S2: "mat_pow (nat(int (Suc(n))- int m)) (B b) == B b" by simp + from eqm have S3: "(mat_pow (Suc(n)) (B b)) = mat_mul (B b) (mat_pow m (B b))" by simp + from S3 have S35: "mat_mul (mat_pow (Suc(n)) (B b)) (mat_pow m (B_inv b)) = mat_mul (mat_mul (B b) (mat_pow m (B b))) (mat_pow m (B_inv b))" by simp + from mat2.exhaust S35 mat_associativity have S4: "mat_mul (mat_pow (Suc(n)) (B b)) (mat_pow m (B_inv b)) + = mat_mul (B b) (mat_mul (mat_pow m (B b)) (mat_pow m (B_inv b)))" by smt + from congruence_inverse2 assms have S5: "mat_mul (mat_pow m (B b)) (mat_pow m (B_inv b)) = mat 1 0 0 1" by simp + have S6: "mat_mul (B b) (B_inv b) = mat 1 0 0 1" using ID_def B_inverse by auto + from S5 S6 eqm have S7: "mat_mul (mat_pow n (B b)) (mat_pow m (B_inv b)) = mat 1 0 0 1" by metis + from S7 have S8: "mat_mul (B b) (mat_mul (mat_pow n (B b)) (mat_pow m (B_inv b))) == B b" by simp + from eqm S2 S4 S8 show ?thesis by simp + qed +qed + +lemma congruence_jneg: + fixes b m j l :: nat + assumes "b>2" and "2*l*m > j" and "j>=1" + defines "n \ nat(int 2*l*m- int j)" + shows "A b n = mat_mul (mat_pow l (mat_pow 2 (A b m))) (A_inv b j)" +proof- + from A_pow assms(1) have Abm2: "A b n = mat_pow n (B b)" by simp + from Abm2 n_def have Bn: "A b n = mat_pow (nat(int 2*l*m- int j)) (B b)" by simp + from Bn congruence_mult assms(1) assms(2) have Bn2: "A b n = mat_mul (mat_pow (2*l*m) (B b)) (mat_pow j (B_inv b))" by fastforce + from assms(1) assms(3) congruence_inverse Bn2 add.commute le_Suc_ex have Bn3: "A b n = mat_mul (mat_pow (2*l*m) (B b)) (A_inv b j)" by smt + from Bn3 A_pow assms(1) mult.commute B.simps mat_exp_law_mult have as3: "A b n = mat_mul (mat_pow l (mat_pow 2 (A b m))) (A_inv b j)" by metis + from as3 A_pow add.commute assms(1) mat_exp_law mat_exp_law_mult show ?thesis by simp +qed + +lemma matrix_congruence: + fixes Y Z :: mat2 + fixes b m j l :: nat + assumes "b>2" + defines "X \ mat_mul Y Z" + defines "a \ mat_11 Y" and "b0\ mat_12 Y" and "c \ mat_21 Y" and "d \ mat_22 Y" + defines "e \ mat_11 Z" and "f \ mat_12 Z" and "g \ mat_21 Z" and "h \ mat_22 Z" + defines "v \ \ b (m+1) - \ b (m-1)" + assumes "a mod v = a1 mod v" and "b0 mod v = b1 mod v" and "c mod v = c1 mod v" and "d mod v = d1 mod v" + shows "mat_21 X mod v = (c1*e+d1*g) mod v \ mat_22 X mod v = (c1*f+ d1*h) mod v" (is "?P \ ?Q") +proof - + (* proof of ?P *) + from X_def mat2.exhaust_sel c_def e_def d_def g_def have P1: "mat_21 X = (c*e+d*g)" + using mat2.sel by auto + from assms(14) mod_mult_cong have P2: "(c*e) mod v = (c1*e) mod v" by blast + from assms(15) mod_mult_cong have P3: "(d*g) mod v = (d1*g) mod v" by blast + from P2 P3 mod_add_cong have P4: "(c*e+d*g) mod v = (c1*e+d1*g) mod v" by blast + from P1 P4 have F1: ?P by simp + (* proof of ?Q *) + from X_def mat2.exhaust_sel c_def f_def d_def h_def mat2.sel(4) mat_mul.simps + have Q1: "mat_22 X = (c*f+d*h)" by metis + from assms(14) mod_mult_cong have Q2: "(c*f) mod v = (c1*f) mod v" by blast + from assms(15) mod_mult_cong have Q3: "(d*h) mod v = (d1*h) mod v" by blast + from Q1 Q2 Q3 mod_add_cong have F2: ?Q by fastforce + from F1 F2 show ?thesis by auto +qed + +text \3.38\ +lemma congruence_Abm: + fixes b m n :: nat + assumes "b>2" + defines "v \ \ b (m+1) - \ b (m-1)" + shows "(mat_21 (mat_pow n (mat_pow 2 (A b m))) mod v = 0 mod v) + \ (mat_22 (mat_pow n (mat_pow 2 (A b m))) mod v = ((-1)^n) mod v)" (is "?P n \ ?Q n") +proof(induct n) +case 0 + from mat2.exhaust have S1: "mat_pow 0 (mat_pow 2 (A b m)) = mat 1 0 0 1" by simp + thus ?case by simp +next + case (Suc n) + define Z where "Z = mat_pow 2 (A b m)" + define Y where "Y = mat_pow n Z" + define X where "X = mat_mul Y Z" + define c where "c = mat_21 Y" + define d where "d = mat_22 Y" + define e where "e = mat_11 Z" + define f where "f = mat_12 Z" + define g where "g = mat_21 Z" + define h where "h = mat_22 Z" + define d1 where "d1 = (-1)^n mod v" + from d_def d1_def Z_def Y_def Suc.hyps have S1: "d mod v = d1 mod v" by simp + from matrix_congruence assms(1) X_def v_def c_def d_def e_def d1_def g_def S1 + have S2: "mat_21 X mod v = (c*e+d1*g) mod v" by blast + from Z_def Y_def c_def Suc.hyps have S3: "c mod v = 0 mod v" by simp + consider (eq0) "m = 0" | (g0) "m>0" by blast + hence S4: "g mod v = 0" + proof cases + case eq0 + from eq0 have S1: "A b m = mat 1 0 0 1" using A.simps by simp + from S1 Z_def div_3252 g_def show ?thesis by simp + next + case g0 + from g0 A.elims neq0_conv + have S1: "A b m = mat (\ b (m + 1)) (-(\ b m)) (\ b m) (-(\ b (m - 1)))" by metis + from S1 assms(1) mat2.sel(3) mat_mul.simps mat_pow.simps + have S2: "mat_21 (mat_pow 2 (A b m)) = (\ b m)*(\ b (m+1)) + (-\ b (m-1))*(\ b m)" + by (auto) + from S2 g_def Z_def g0 A.elims neq0_conv + have S3: "g = (\ b (m+1))*(\ b m)- (\ b m)*(\ b (m-1))" by simp + from S3 g_def v_def mod_mult_self1_is_0 mult.commute right_diff_distrib show ?thesis by metis + qed + from S2 S3 S4 Z_def div_3252 g_def mat2.exhaust_sel mod_0 have F1: "?P (Suc(n))" by metis + (* Now proof of Q *) + from d_def d1_def Z_def Y_def Suc.hyps have Q1: "d mod v = d1 mod v" by simp + from matrix_congruence assms(1) X_def v_def c_def d_def f_def d1_def h_def S1 + have Q2: "mat_22 X mod v = (c*f+d1*h) mod v" by blast + from Z_def Y_def c_def Suc.hyps have Q3: "c mod v = 0 mod v" by simp + consider (eq0) "m = 0" | (g0) "m>0" by blast + hence Q4: "h mod v = (-1) mod v" + proof cases + case eq0 + from eq0 have S1: "A b m = mat 1 0 0 1" using A.simps by simp + from eq0 v_def have S2: "v = 1" by simp + from S1 S2 show ?thesis by simp + next + case g0 + from g0 A.elims neq0_conv have S1: "A b m = mat (\ b (m + 1)) (-(\ b m)) (\ b m) (-(\ b (m - 1)))" by metis + from S1 A_pow assms(1) mat2.sel(4) mat_exp_law mat_exp_law_mult mat_mul.simps mult_2 + have S2: "mat_22 (mat_pow 2 (A b m)) = (\ b m)*(-(\ b m)) + (-(\ b (m - 1)))*(-(\ b (m - 1)))" + by auto + from S2 Z_def h_def have S3: "h = -(\ b m)*(\ b m) + (\ b (m - 1))*(\ b (m - 1))" by simp + from v_def add.commute diff_add_cancel mod_add_self2 have S4: "(\ b (m - 1)) mod v = \ b (m+1) mod v" by metis + from S3 S4 mod_diff_cong mod_mult_left_eq mult.commute mult_minus_right uminus_add_conv_diff + have S5: "h mod v = (-(\ b m)*(\ b m) + (\ b (m - 1))*(\ b (m + 1))) mod v" by metis + from One_nat_def add.right_neutral add_Suc_right \.elims diff_Suc_1 g0 le_imp_less_Suc le_simps(1) neq0_conv Suc_diff_1 alpha_n + have S6: "\ b (m + 1) = b* (\ b m)- \ b (m-1)" + by (smt Suc_eq_plus1 Suc_pred' \.elims alpha_superlinear assms(1) g0 nat.inject of_nat_0_less_iff of_nat_1 of_nat_add) + from S6 have S7: "(\ b (m - 1))*(\ b (m + 1)) = (int b) * (\ b (m-1) * (\ b m)) - (\ b (m-1))^2" + proof - + have f1: "\i ia. - ((ia::int) * i) = ia * - i" by simp + have "\i ia ib ic. (ic::int) * (ib * ia) + ib * i = ib * (ic * ia + i)" by (simp add: distrib_left) + thus ?thesis using f1 by (metis S6 ab_group_add_class.ab_diff_conv_add_uminus power2_eq_square) + qed + from S7 have S8: "(-(\ b m)*(\ b m) + (\ b (m - 1))*(\ b (m + 1))) + = -1*(\ b (m-1))^2 + (int b) * (\ b (m-1) * (\ b m)) - (\ b m)^2" by (simp add: power2_eq_square) + from alpha_det2 assms(1) g0 have S9: "-1*(\ b (m-1))^2 + (int b) * (\ b (m-1) * (\ b m)) - (\ b m)^2 = -1" by smt + from S5 S8 S9 show ?thesis by simp + qed + from Q2 Q3 Q4 Suc_eq_plus1 add.commute add.right_neutral d1_def mod_add_right_eq mod_mult_left_eq mod_mult_right_eq mult.right_neutral + mult_minus1 mult_minus_right mult_zero_left power_Suc have Q5: "mat_22 X mod v = (-1)^(n+1) mod v" by metis + from Q5 Suc_eq_plus1 X_def Y_def Z_def mat_exp_law mat_exp_law_mult mult.commute mult_2 one_add_one have F2: "?Q (Suc(n))" by metis + from F1 F2 show ?case by blast +qed + +text \ 3.36 requires two lemmas 361 and 362 \ + +lemma 361: + fixes b m j l :: nat + assumes "b>2" + defines "n \ 2*l*m + j" + defines "v \ \ b (m+1) - \ b (m-1)" + shows "(\ b n) mod v = ((-1)^l * \ b j) mod v" +proof - + define Y where "Y = mat_pow l (mat_pow 2 (A b m))" + define Z where "Z = A b j" + define X where "X = mat_mul Y Z" + define c where "c = mat_21 Y" + define d where "d = mat_22 Y" + define e where "e = mat_11 Z" + define g where "g = mat_21 Z" + define d1 where "d1 = (-1)^l mod v" + from congruence_Abm assms(1) d_def v_def Y_def d1_def have S0: "d mod v = d1 mod v" by simp_all + from matrix_congruence assms(1) X_def v_def c_def d_def e_def d1_def g_def S0 have S1: "mat_21 X mod v = (c*e+d1*g) mod v" by blast + from congruence_Abm d1_def v_def mod_mod_trivial have S2: "d1 mod v = (-1)^l mod v" by blast + from congruence_Abm Y_def assms(1) c_def v_def have S3: "c mod v = 0" by simp + from Z_def g_def A.elims \.simps(1) mat2.sel(3) mat2.exhaust have S4: "g = \ b j" by metis + from A_pow assms(1) mat_exp_law mat_exp_law_mult mult_2 mult_2_right n_def X_def Y_def Z_def have S5: "A b n = X" by metis + from S5 A.elims \.simps(1) mat2.sel(3) Z_def Y_def have S6: "mat_21 X = \ b n" by metis + from S2 S3 S4 S6 S1 add.commute mod_0 mod_mult_left_eq mod_mult_self2 mult_zero_left zmod_eq_0_iff show ?thesis by metis +qed + +lemma 362: +fixes b m j l :: nat + assumes "b>2" and "2*l*m > j" and "j>=1" + defines "n \ 2*l*m - j" + defines "v \ \ b (m+1) - \ b (m-1)" + shows "(\ b n) mod v = -((-1)^l * \ b j) mod v" +proof - + define Y where "Y = mat_pow l (mat_pow 2 (A b m))" + define Z where "Z = A_inv b j" + define X where "X = mat_mul Y Z" + define c where "c = mat_21 Y" + define d where "d = mat_22 Y" + define e where "e = mat_11 Z" + define g where "g = mat_21 Z" + define d1 where "d1 = (-1)^l mod v" + from congruence_Abm assms(1) d_def v_def Y_def d1_def have S0: "d mod v = d1 mod v" by simp_all + from matrix_congruence assms(1) X_def v_def c_def d_def e_def d1_def g_def S0 have S1: "mat_21 X mod v = (c*e+d1*g) mod v" by blast + from congruence_Abm d1_def v_def mod_mod_trivial have S2: "d1 mod v = (-1)^l mod v" by blast + from congruence_Abm Y_def assms(1) c_def v_def have S3: "c mod v = 0" by simp + from Z_def g_def have S4: "g = - \ b j" by simp + from congruence_jneg assms(1) assms(2) assms(3) n_def X_def Y_def Z_def have S5: "A b n = X" by (simp add: nat_minus_as_int) + from S5 A.elims \.simps(1) mat2.sel(3) Z_def Y_def have S6: "mat_21 X = \ b n" by metis + from S2 S3 S4 S6 S1 add.commute mod_0 mod_mult_left_eq mod_mult_self2 mult_minus_right mult_zero_left zmod_eq_0_iff show ?thesis by metis +qed + +text \Equation 3.36\ +lemma 36: +fixes b m j l :: nat + assumes "b>2" + assumes "(n = 2 * l * m + j \ (n = 2 * l * m - j \ 2 * l * m > j \ j \ 1)) " + defines "v \ \ b (m+1) - \ b (m-1)" + shows "(\ b n) mod v = \ b j mod v \ (\ b n) mod v = -\ b j mod v" using assms(2) + apply(auto) + subgoal using 361 assms(1) v_def + apply(cases "even l" ) + by simp+ + subgoal using 362 assms(1) v_def + apply(cases "even l" ) + by simp+ + done + +subsubsection \Diophantine definition of a sequence alpha\ +definition alpha_equations :: "nat \ nat \ nat + \ nat \ nat \ nat \ nat \ nat \ nat \ nat \ nat \ bool" where + "alpha_equations a b c r s t u v w x y = ( + \ \3.41\ b > 3 \ + \ \3.42\ u^2 + t ^ 2 = 1 + b * u * t \ + \ \3.43\ s^2 + r ^ 2 = 1 + b * s * r \ + \ \3.44\ r < s \ + \ \3.45\ u ^ 2 dvd s \ + \ \3.46\ v + 2 * r = (b) * s \ + \ \3.47\ w mod v = b mod v \ + \ \3.48\ w mod u = 2 mod u \ + \ \3.49\ 2 < w \ + \ \3.50\ x ^ 2 + y ^ 2 = 1 + w * x * y \ + \ \3.51\ 2 * a < u \ + \ \3.52\ 2 * a < v \ + \ \3.53\ a mod v = x mod v \ + \ \3.54\ 2 * c < u \ + \ \3.55\ c mod u = x mod u)" + +text \The sufficiency\ +lemma alpha_equiv_suff: + fixes a b c::nat + assumes "\r s t u v w x y. alpha_equations a b c r s t u v w x y" + shows "3 < b \ int a = (\ b c)" +proof - + from assms obtain r s t u v w x y where eq: "alpha_equations a b c r s t u v w x y" by auto + have 41: "b > 3" using alpha_equations_def eq by auto + have 42: "u^2 + t ^ 2 = 1 +b * u * t" using alpha_equations_def eq by auto + have 43: "s^2 + r ^ 2 = 1 + b * s * r" using alpha_equations_def eq by auto + have 44: "r < s" using alpha_equations_def eq by auto + have 45: "u ^ 2 dvd s" using alpha_equations_def eq by auto + have 46: "v + 2 * r = b * s" using alpha_equations_def eq by auto + have 47: "w mod v = b mod v" using alpha_equations_def eq by auto + have 48: "w mod u = 2 mod u" using alpha_equations_def eq by auto + have 49: "2 < w" using alpha_equations_def eq by auto + have 50: "x ^ 2 + y ^ 2 = 1 + w * x * y" using alpha_equations_def eq by auto + have 51: "2 * a < u" using alpha_equations_def eq by auto + have 52: "2 * a < v" using alpha_equations_def eq by auto + have 53: "a mod v = x mod v" using alpha_equations_def eq by auto + have 54: "2 * c < u" using alpha_equations_def eq by auto + have 55: "int c mod u = x mod u" using alpha_equations_def eq by auto + + have "b > 2" using \b>3\ by auto + have "u > 0" using 51 by auto + + (* These first three equations are all proved very similarly. *) + text \Equation 3.56\ + have "\k. u = \ b k" using 42 alpha_char_eq2 by (simp add: \2 < b\ power2_eq_square) + then obtain k where 56: "u = \ b k" by auto + + text \Equation 3.57\ + have "\m. s = \ b m \ r = \ b (m-1)" using 43 44 alpha_char_eq[of r s b] diff_Suc_1 + by (metis power2_eq_square) + then obtain m where 57: "s = \ b m \ r = \ b (m-1)" by auto + + (* These are some properties we need multiple times *) + have m_pos: "m \ 0" using "44" "57" not_less_eq by fastforce + have alpha_pos: "\ b m > 0" using "44" "57" by linarith + + + text \Equation 3.58\ + have "\n. x = \ w n" using 50 alpha_char_eq2 by (simp add: "49" power2_eq_square) + then obtain n where 58: "x = \ w n" by auto + + text \Equation 3.59\ + have "\l j. (n = 2 * l * m + j \ n = 2 * l * m - j \ 2 * l * m > j \ j \ 1) \ j \ m" + proof - + define q where "q = n mod m" + obtain p where p_def: "n = p * m + q" using mod_div_decomp q_def by auto + have q1: "q \ m" using 44 57 + by (metis diff_le_self le_0_eq le_simps(1) linorder_not_le mod_less_divisor nat_int q_def) + consider (c1) "even p" | (c2) "odd p" by auto + thus ?thesis + proof(cases) + case c1 + thus ?thesis using p_def q1 by blast + next + case c2 + obtain d where "p=2*d+1" using c2 oddE by blast + define l where "l=d+1" + hence jpt: "l>0" by simp + from \p=2*d+1\ l_def have c21: "p=2*l-1" by auto + have c22: "n=2*l*m-(m-q)" + by (metis Nat.add_diff_assoc2 add.commute c21 diff_diff_cancel diff_le_self jpt mult_eq_if + mult_is_0 neq0_conv p_def q1 zero_neq_numeral) + thus ?thesis using diff_le_self + by (metis add.left_neutral diff_add_inverse2 diff_zero less_imp_diff_less mult.right_neutral + mult_eq_if mult_zero_right not_less zero_less_diff) + qed + qed + + (* here we add some conditions that are implicit in the proof but necessary for Isabelle *) + then obtain l j where 59: " (n = 2 * l * m + j \ n = 2 * l * m - j \ 2 * l * m > j \ j \ 1) \ j \ m" by auto + + text \Equation 3.60\ + have 60: "u dvd m" + using 45 56 57 divisibility_alpha2[of b m k] \b>2\ + by (metis dvd_trans dvd_triv_right int_dvd_int_iff m_pos neq0_conv of_nat_power) + + text \Equation 3.61\ + have 61: "v = \ b (m+1)- \ b (m-1)" + proof- + have "v = b*(\ b m) - 2*(\ b (m-1))" using 46 57 by (metis add_diff_cancel_right' mult_2 of_nat_add of_nat_mult) + thus ?thesis using alpha_n[of b "m-1"] m_pos by auto + qed + + text \Equation 3.62.1\ + have "a mod v = \ b n mod v" using 53 58 47 congruence[of w v b n] by (simp add: zmod_int) + hence "a mod v = \ b j mod v \ a mod v = -\ b j mod v" using 36[of b] 61 59 \2 < b\ by auto + (* more usable version *) + hence 62: "v dvd (a+ \ b j) \ v dvd (a - \ b j)" using mod_eq_dvd_iff zmod_int by auto + + text \Equation 3.63\ + (* This could be rewritten in a single proof if none of the 631-634 are reused *) + + have 631: "2*\ b j \ 2* \ b m" using 59 alpha_strictly_increasing_general[of b j m] \2 < b\ by force + + have "b - 2 \ 2" using 41 by simp + moreover have "\ b m > 0" using "44" "57" by linarith + ultimately have 632: "2 * \ b m \ (b - 2) * \ b m" by auto + + have "(b - 2) * \ b m = b * \ b m - 2* \ b m" using \2 < b\ + by (simp add: int_distrib(4) mult.commute of_nat_diff) + moreover have "b * \ b m - 2* \ b m < b * \ b m - 2 * \ b (m - 1)" using "44" "57" by linarith + ultimately have 633: "(b - 2) * \ b m < b * \ b m - 2 * \ b (m - 1)" by auto + + have 634: " b * \ b m - 2 * \ b (m - 1) = v" using 61 alpha_n[of b "m-1"] m_pos by simp + + have 63: "2*\ b j < v" using 631 632 633 634 by auto + + text \Equation 3.64\ + + hence 64: "a = \ b j" + proof(cases "0 < a + \ b j") + case True + moreover have "a + \ b j < v" using 52 63 by linarith + ultimately show ?thesis using 62 + apply auto + subgoal using zdvd_not_zless by blast + subgoal + by (smt \2 < b\ alpha_superlinear dvd_add_triv_left_iff negative_zle zdvd_not_zless) + done + next + case False + hence "j = 0" using \2 < b\ alpha_strictly_increasing_general by force + thus ?thesis using False by auto + qed + + + text \Equation 3.65\ + have 65: "c mod u = n mod u" + proof - + have "c mod u = \ w n mod u" using 55 58 zmod_int by (simp add: ) + moreover have "... = n mod u" using 48 alpha_linear congruence zmod_int by presburger + ultimately show ?thesis by linarith + qed + + text \Equation 3.66\ + have "2 * j \ 2 * \ b j \ 2 * a < u" + using 51 alpha_superlinear \b>2\ by auto + hence 66: "2*j < u" using "64" by linarith + + text \Equation 3.67\ + have 652: "u dvd (n+j) \ u dvd (n-j)" using 60 59 by auto + + hence "c = j" using 66 54 + proof- + have "c + j < u" using 66 54 by linarith + thus ?thesis using 652 + apply auto + subgoal + by (metis "65" add_cancel_right_right dvd_eq_mod_eq_0 mod_add_left_eq mod_if not_add_less2 not_gr_zero) + subgoal + by (metis "59" "60" "65" "66" Nat.add_diff_assoc2 \\c + j < u; u dvd n + j\ \ c = j\ + add_diff_cancel_right' add_lessD1 dvd_mult le_add2 le_less mod_less mod_nat_eqI mult_2) + done + qed + + show ?thesis using \b>3\ 64 \c=j\ by auto +qed + + +text \ 3.7.2 The necessity \ + +lemma add_mod: + fixes p q :: int + assumes "p mod 2 = 0" "q mod 2 = 0" + shows "(p+q) mod 2 = 0 \ (p-q) mod 2 = 0" + using assms(1) assms(2) by auto + +lemma one_odd: + fixes b n :: nat + assumes "b>2" + shows "(\ b n) mod 2 = 1 \ (\ b (n+1)) mod 2 = 1" +proof(rule ccontr) + assume asm: "\(\ b n mod 2 = 1 \ \ b (n + 1) mod 2 = 1)" + from asm have step1: "(\ b n mod 2 = 0 \ \ b (n + 1) mod 2 = 0)" by simp + from step1 have s1: "(\ b n)^2 mod 2 = 0 \ (\ b (n+1))^2 mod 2 = 0" by auto + from step1 have s2: "(int b)*(\ b n)*(\ b (n+1)) mod 2 = 0" by auto + from s1 have s3: "((\ b (n+1))^2 + (\ b n)^2) mod 2 = 0" by auto + from s2 s3 add_mod have s4: "((\ b (n+1))^2 + (\ b n)^2 - (int b)*((\ b n)*(\ b (n+1)))) mod 2 = 0" + by (simp add: Groups.mult_ac(2) Groups.mult_ac(3)) + have s5: "(\ b (n+1))^2+(\ b n)^2-(int b)*((\ b n)*(\ b (n+1)))=(\ b (n+1))^2-(int b)*(\ b (n+1)*(\ b n))+(\ b n)^2" by simp + from s4 s5 have s6: "((\ b (n+1))^2-(int b)*(\ b (n+1)*(\ b n))+(\ b n)^2) mod 2 = 0" + proof - + have f1: "(\ b (n + 1))\<^sup>2 - int b * (\ b (n + 1) * \ b n) = (\ b (n + 1))\<^sup>2 + - 1 * (int b * (\ b (n + 1) * \ b n))" + by simp + have f2: "(\ b (n + 1))\<^sup>2 + - 1 * (int b * (\ b (n + 1) * \ b n)) + (\ b n)\<^sup>2 = (\ b (n + 1))\<^sup>2 + (\ b n)\<^sup>2 + - 1 * (int b * (\ b n * \ b (n + 1)))" + by simp + have "((\ b (n + 1))\<^sup>2 + (\ b n)\<^sup>2 + - 1 * (int b * (\ b n * \ b (n + 1)))) mod 2 = 0" + using s4 by fastforce + thus ?thesis using f2 f1 by presburger + qed + from s6 alpha_det1 show False by (simp add: assms mult.assoc) +qed + +lemma oneodd: + fixes b n :: nat + assumes "b>2" + shows "odd (\ b n) = True \ odd (\ b (n+1)) = True" + using assms odd_iff_mod_2_eq_one one_odd by auto + +lemma cong_solve_nat: "a \ 0 \ \x. (a*x) mod n = (gcd a n) mod n" + for a n :: nat + apply (cases "n=0") + apply auto + apply (insert bezout_nat [of a n], auto) + by (metis mod_mult_self4) + +lemma cong_solve_coprime_nat: "coprime (a::nat) (n::nat) \ \x. (a*x) mod n = 1 mod n" + using cong_solve_nat[of a n] coprime_iff_gcd_eq_1[of a n] by fastforce + +lemma chinese_remainder_aux_nat: + fixes m1 m2 :: nat + assumes a:"coprime m1 m2" + shows "\b1 b2. b1 mod m1 = 1 mod m1 \ b1 mod m2 = 0 mod m2 \ b2 mod m1 = 0 mod m1 \ b2 mod m2 = 1 mod m2" +proof - + from cong_solve_coprime_nat [OF a] obtain x1 where 1: "(m1*x1) mod m2 = 1 mod m2" by auto + from a have b: "coprime m2 m1" + by (simp add: coprime_commute) + from cong_solve_coprime_nat [OF b] obtain x2 where 2: "(m2*x2) mod m1 = 1 mod m1" by auto + have "(m1*x1) mod m1 = 0" by simp + have "(m2*x2) mod m2 = 0" by simp + show ?thesis using 1 2 + by (metis mod_0 mod_mult_self1_is_0) +qed + +lemma cong_scalar2_nat: "a mod m = b mod m \ (k*a) mod m = (k*b) mod m" + for a b k :: nat + by (rule mod_mult_cong) simp_all + +lemma chinese_remainder_nat: + fixes m1 m2 :: nat + assumes a: "coprime m1 m2" + shows "\x. x mod m1 = u1 mod m1 \ x mod m2 = u2 mod m2" +proof - + from chinese_remainder_aux_nat [OF a] obtain b1 b2 where "b1 mod m1 = 1 mod m1" and "b1 mod m2 = 0 mod m2" and +"b2 mod m1 = 0 mod m1" and "b2 mod m2 = 1 mod m2" by force + let ?x = "u1*b1+u2*b2" + have "?x mod m1 = (u1*1+u2*0) mod m1" + apply (rule mod_add_cong) + apply(rule cong_scalar2_nat) + apply (rule \b1 mod m1 = 1 mod m1\) + apply(rule cong_scalar2_nat) + apply (rule \b2 mod m1 = 0 mod m1\) + done + hence 1:"?x mod m1 = u1 mod m1" by simp + have "?x mod m2 = (u1*0+u2*1) mod m2" + apply (rule mod_add_cong) + apply(rule cong_scalar2_nat) + apply (rule \b1 mod m2 = 0 mod m2\) + apply(rule cong_scalar2_nat) + apply (rule \b2 mod m2 = 1 mod m2\) + done + hence "?x mod m2 = u2 mod m2" by simp + with 1 show ?thesis by blast +qed + +lemma nat_int1: "\(w::nat) (u::int).u>0 \ (w mod nat u = 2 mod nat u \ int w mod u = 2 mod u)" + by blast + +lemma nat_int2: "\(w::nat) (b::nat) (v::int).u>0 \ (w mod nat v = b mod nat v \ int w mod v = int b mod v)" + by (metis mod_by_0 nat_eq_iff zmod_int) + +lemma lem: + fixes u t::int and b::nat + assumes "u^2-int b*u*t+t^2=1" "u\0" "t\0" + shows "(nat u)^2+(nat t)^2=1+b*(nat u)*(nat t)" +proof - + define U where "U=nat u" + define T where "T=nat t" + from U_def T_def assms have UT: "int U=u \ int T = t" using int_eq_iff by blast + from UT have UT1: "int (b*U*T) = b*u*t" by simp + from UT have UT2: "int (U^2+T^2)=u^2+t^2" by simp + from UT2 assms have sth: "int (U^2+T^2)\b*u*t" by auto + from sth assms have sth1: "U^2+T^2\b*U*T" using UT1 by linarith + from sth1 of_nat_diff have sth2: "int (U^2+T^2-b*U*T) = int (U^2+T^2) - int (b*U*T)" by blast + from UT1 UT2 have UT3: "int (U^2+T^2)-int (b*U*T)=u^2+t^2-b*u*t" by simp + from sth2 UT3 assms have sth4: "int (U^2+T^2-b*U*T) = 1" by auto + from sth4 have sth5: "U^2+T^2-b*U*T=1" by simp + from sth5 have sth6: "U^2+T^2=1+b*U*T" by simp + show ?thesis using sth6 U_def T_def by simp +qed + +text \The necessity\ + +lemma alpha_equiv_nec: + "b > 3 \ a = \ b c \ \r s t u v w x y. alpha_equations a b c r s t u v w x y" +proof - + assume assms: "b > 3 \ a = \ b c" + have s1: "\(k::nat) (u::int) (t::int).u=\ b k \ odd u = True \ 2*int a u u^2-(int b)*u*t+t^2=1 \ k>0 \ t = \ b (k+1)" + proof - + define j::nat where "j=2*(a)+1" + have rd: "j>0" by (simp add: j_def) + consider (c1) "odd (\ b j) = True" | (c2) "odd (\ b (j+1)) = True" + using assms oneodd by fastforce + thus ?thesis + proof cases + case c1 + define k::nat where "k=j" + define u::int where "u=\ b k" + define t::int where "t=\ b (k+1)" + have stp: "k>0" by (simp add: k_def j_def) + from alpha_strictly_increasing assms have abc: "u2*a" by (simp add: k_def j_def) + from alpha_superlinear c12 have c13: "2*a b k" + define t::int where "t=\ b (k+1)" + have stc: "k>0" by (simp add: k_def j_def) + from alpha_strictly_increasing assms have abc: "u2*a" by (simp add: k_def j_def) + from alpha_superlinear c22 have c23: "2*a b k \ odd u = True \ 2*int a u u^2-(int b)*u*t+t^2=1 \ k>0 \ t= \ b (k+1)" by force + define m where "m=(nat u)*k" + define s where "s=\ b m" + define r where "r=\ b (m-1)" + note udef = \u = \ b k \ odd u = True \ 2 * int a < u \ u < t \ u\<^sup>2 - int b * u * t + t\<^sup>2 = 1 \ 0 < k \ t = \ b (k+1)\ + from assms have s211: "int b > 3" by simp + from assms alpha_superlinear have a354: "c\a" + by (simp add: nat_int_comparison(3)) + from a354 udef have 354: "2* int c b k \ int k" by simp + from alpha_strictly_increasing s211 s1 m_def s_def udef r_def have s212: "\ b (m-1) < \ b m" + by (smt One_nat_def Suc_pred nat_0_less_mult_iff zero_less_nat_eq) + from s212 r_def s_def have 344: "r b k) dvd (int m) \ k dvd m" by simp + from xyz divisibility_alpha2 have wxyz: "(\ b k)*(\ b k) dvd (\ b m)" by (smt assms dvd_mult_div_cancel int_nat_eq less_imp_le_nat m_def mult_pos_pos neq0_conv not_less not_less_eq numeral_2_eq_2 numeral_3_eq_3 of_nat_0_less_iff power2_eq_square udef) + from wxyz udef s_def have 345: "u^2 dvd s" by (simp add: power2_eq_square) + define v where "v = b*s-2*r" + from v_def s_def r_def alpha_n have 370: "v = \ b (m+1) - \ b (m-1)" + by (smt Suc_eq_plus1 add_diff_inverse_nat diff_Suc_1 neq0_conv not_less_eq s212 zero_less_diff) + have 371: "v = b*\ b m - 2*\ b (m-1)" using v_def s_def r_def by simp + from alpha_strictly_increasing assms m_def udef have asd: "\ b m > 0" + by (smt Suc_pred nat_0_less_mult_iff s211 zero_less_nat_eq) + from assms asd 371 have 372: "v\4*\ b m -2*\ b (m-1)" by simp + from 372 assms have 373: "v>2*\ b m \ 4*\ b m -2*\ b (m-1) > 2*\ b m" using s212 by linarith + from 373 assms alpha_superlinear have 374: "2*\ b m \ 2*m \ v>2*m" + by (smt One_nat_def Suc_eq_plus1 add_lessD1 distrib_right mult.left_neutral numeral_3_eq_3 of_nat_add one_add_one) + from udef have pre1: "k\1 \ u\1" using rd by linarith + from pre1 374 m_def have pre2: "m\u" by simp + from pre2 374 have 375: "2*m\2*u \ v>2*u" by simp + from 375 udef have 376: "2*u>2*a \ v>2*a" using pre1 by linarith + have u_v_coprime: "coprime u v" + proof - + obtain d::nat where d: "d = gcd u v" + by (metis gcd_int_def) + from \d = gcd u v\ have ddef: "d dvd u \ d dvd v" by simp + from 345 ddef have stp1: "d dvd s" using dvd_mult_left dvd_trans s_def udef wxyz by blast + from v_def stp1 ddef have stp2: "d dvd 2*r" by algebra + from ddef udef have d_odd: "odd d" using dvd_trans by auto + have r2even: "even (2*r)" by simp + from stp2 d_odd r2even have stp3: "(2*d) dvd (2*r)" by fastforce + from stp3 have stp4: "d dvd r" by simp + from stp1 stp4 have stp5: "d dvd s^2 \ d dvd (-int b*s*r) \ d dvd r^2" by (simp add: power2_eq_square) + from stp5 have stp6: "d dvd (s^2-int b*s*r+r^2)" by simp + from 343 stp6 have stp7: "d dvd 1" by simp + show ?thesis using stp7 d by auto + qed + have wdef: "\w::nat. int w mod u = 2 mod u \ int w mod v = int b mod v \ w>2" + proof - + from pre1 m_def have mg: "m\1" by auto + from s_def r_def 344 have srg: "s-r\1" by simp + from assms have bg: "b\4" by simp + from bg have bsr: "((int b)*s-2*r)\(4*s-2*r)" using 372 r_def s_def v_def by blast + have t1: "v\2+2*s" using bsr srg v_def by simp + from s_def have sg: "s\1" using asd by linarith + from sg t1 have t2: "v\4" by simp + from u_v_coprime have u_v_coprime1:"coprime (nat u) (nat v)" using pre1 t2 + using coprime_int_iff by fastforce + obtain z::nat where "z mod nat u = 2 mod nat u \ z mod nat v = b mod nat v" using chinese_remainder_nat u_v_coprime1 by force + note zdef = \z mod nat u = 2 mod nat u \ z mod nat v = b mod nat v\ + from t2 pre1 have t31: "nat v\4 \ nat u\1" by auto + from t31 have t3: "nat v*nat u\4" using mult_le_mono by fastforce + define w::nat where "w=z+ nat u*nat v" + from w_def t3 have t4: "w\4" by (simp add: mult.commute) + have t51: "(nat u*nat v) mod nat u = 0 \ (nat u*nat v) mod nat v = 0" using algebra by simp + from t51 w_def have t5: "w mod nat u = z mod nat u" by presburger + from t51 w_def have t6: "w mod nat v = z mod nat v" by presburger + from t5 t6 zdef have t7: "w mod nat u = 2 mod nat u \ w mod nat v = b mod nat v" by simp + from t7 t31 have t8: "int w mod u = 2 mod u \ int w mod v = int b mod v" + using nat_int1 nat_int2 by force + from t4 t8 show ?thesis by force + qed + obtain w::nat where "int w mod u = 2 mod u \ int w mod v = int b mod v \ w>2" using wdef by force + note wd = \int w mod u = 2 mod u \ int w mod v = int b mod v \ w>2\ + define x where "x = \ w c" + define y where "y = \ w (c+1)" + from alpha_det1 wd x_def y_def have 350: "x^2-int w*x*y+y^2 =1" by (metis add_gr_0 alpha_det2 diff_add_inverse2 less_one mult.assoc) + from x_def wd congruence have 353: "a mod v = x mod v" + by (smt "374" assms int_nat_eq nat_int nat_mod_distrib) + from congruence2 wd x_def have 379: "x mod int (w-2) = int c mod (int w-2)" + using int_ops(6) zmod_int by auto + from wd have wc: "u dvd (int w-2)" using mod_diff_cong mod_eq_0_iff_dvd by fastforce + from wc have wb: "\k1. u*k1=int w-2" by (metis dvd_def) + obtain k1 where "u*k1=int w-2" using wb by force + note k1def = \u*k1=int w-2\ + define r1 where "r1=int c mod (int w-2)" + from r1_def 379 have wa: "r1 = x mod (int w-2)" + using int_ops(6) wd by auto + obtain k2 where "int c = (int w-2)*k2+r1" by (metis mult_div_mod_eq r1_def) + note k2def = \int c = (int w-2)*k2+r1\ + from k2def k1def have a355: "int c = u*k1*k2+r1" by simp + from udef k1def k2def have bh: "u*k1*k2 mod u = 0" by (metis mod_mod_trivial mod_mult_left_eq mod_mult_self1_is_0 mult_eq_0_iff) + from a355 bh have b355: "(u*k1*k2+r1) mod u = r1 mod u" by (simp add: mod_eq_dvd_iff) + from a355 b355 have c355: "int c mod u = r1 mod u" by simp + from wa have waa: "\k3. x = k3*(int w-2)+r1" by (metis div_mult_mod_eq) + obtain k3 where "x=k3*(int w-2)+r1" using waa by force + from k1def \x = k3*(int w-2)+r1\ have d355: "x=u*k1*k3+r1" by simp + from udef k1def have ch: "u*k1*k3 mod u = 0" by (metis mod_mod_trivial mod_mult_left_eq mod_mult_self1_is_0 mult_eq_0_iff) + from d355 ch have e355: "(u*k1*k3+r1) mod u = r1 mod u" by (simp add: mod_eq_dvd_iff) + from d355 e355 have f355: "x mod u = r1 mod u" by simp + from c355 f355 have 355: "int c mod u = x mod u" by simp + from assms s1 wdef udef 343 344 345 v_def wd 350 376 353 354 355 have prefinal: "u^2-b*u*t+t^2=1 \ s^2-b*s*r+r^2=1 \ r u^2 dvd s \ b*s=v+2*r \ w mod v = b mod v \ w mod u = 2 mod u \ w>2 \ x^2-w*x*y+y^2=1 \ + 2*a 2*a a mod v = x mod v \ 2*c c mod u = x mod u" by fastforce + from alpha_strictly_increasing have s_pos: "s\0" using asd s_def by linarith + define S where "S=nat s" + from alpha_strictly_increasing have r_pos: "r\0" using asd r_def by (smt One_nat_def Suc_1 alpha_superlinear assms(1) lessI less_trans numeral_3_eq_3 of_nat_0_le_iff) + define R where "R=nat r" + from udef alpha_strictly_increasing have ut_pos:"u\0 \ t\0" using pre1 by linarith + from assms have a_pos: "a\0" using a354 by linarith + from a_pos have v_pos: "v\0" using "376" by linarith + from x_def y_def have xy_pos: "x\0 \ y\0" by (smt alpha_superlinear of_nat_0_le_iff wd) + define U where "U=nat u" + define T where "T=nat t" + define V where "V=nat v" + define X where "X=nat x" + define Y where "Y=nat y" + from lem U_def T_def S_def R_def X_def Y_def prefinal have lem1: "U^2+T^2=1+b*U*T \ S^2+R^2=1+b*S*R \ X^2+Y^2=1+w*X*Y" using s_pos ut_pos r_pos xy_pos by blast + from R_def S_def have lem2: "R2*r" using v_def v_pos by simp + from aq have aq1: "nat (int b*s) \ nat (2*r)" by simp + from s_pos r_pos assms have aq2: "nat (int b*s) = b*(nat s) \ nat (2*r) = 2*(nat r)" by (simp add: nat_mult_distrib) + from aq1 aq2 have aq3: "b*S\2*R" using S_def R_def by simp + from aq3 have aq4: "int (b*S-2*R) = int (b*S)-int (2*R)" using of_nat_diff by blast + have aq5: "int (b*S) = int b*int S \ int (2*R) = 2*int R" by simp + from aq4 aq5 have aq6: "int (b*S-2*R) = int b*s-2*r" using R_def S_def r_pos s_pos by simp + from aq6 v_def v_pos V_def have lem4: "b*S-2*R = V" by simp + from prefinal v_pos V_def ut_pos U_def xy_pos X_def a_pos have lem5: "w mod V = b mod V \ w mod U = 2 mod U \ a mod V=X mod V \ c mod U = X mod U" + by (metis int_nat_eq nat_int of_nat_numeral zmod_int) + from a_pos ut_pos v_pos U_def V_def prefinal have lem6: "2*nat a 2*nat a 2*c2" by simp + have third_last: "\b s v r::nat. b * s = v + 2 * r \ int (b * s) = int (v + 2 * r)" using of_nat_eq_iff by blast + have onemore: "\u t b. u ^ 2 + t ^ 2 = 1 + b * u * t \ int u ^ 2 + int t ^ 2 = 1 + int b * int u * int t" + by (metis (no_types) nat_int of_nat_1 of_nat_add of_nat_mult of_nat_power) + from lem1 lem2 lem3 lem4 lem5 lem6 lem7 third_last onemore show ?thesis + unfolding Exp_Matrices.alpha_equations_def[of a b c] apply auto + using assms apply blast + apply (rule exI[of _ R], rule exI[of _ S], rule exI[of _ T], rule exI[of _ U], simp) + apply (rule exI[of _ V], simp) + apply (rule exI[of _ w], simp) + apply (rule exI[of _ X], simp) + using aq4 aq5 lem5 by auto +qed + +subsubsection \Exponentiation is Diophantine\ + +text \Equations 3.80-3.83\ + +lemma 86: + fixes b r and q::int + defines "m \ b * q - q * q - 1" + shows "(q * \ b (r + 1) - \ b r) mod m = (q ^ (r + 1)) mod m" +proof(induction r) + case 0 + show ?case by simp +next + case (Suc n) + from m_def have a0: "(q * q - b * q + 1) mod m = ((-(q * q - b * q + 1)) mod m + (q * q - b * q + 1) mod m) mod m" by simp + have a1: "\ = 0" by (simp add:mod_add_eq) + from a0 a1 have a2: "(q * q - b * q + 1) mod m = 0" by simp + + from a2 have b0: "(b * q - 1) mod m = ((q * q - b * q + 1) mod m + (b * q - 1) mod m) mod m" by simp + have b1: "\ = (q * q) mod m" by (simp add: mod_add_eq) + from b0 b1 have b2: "(b * q - 1) mod m = (q * q) mod m" by simp + + have "(q * (\ b (Suc n + 1)) -\ b (Suc n)) mod m = (q * (int b *\ b (Suc n) -\ b n) -\ b (Suc n)) mod m" by simp + also have "\ = ((b * q - 1) *\ b (Suc n) - q *\ b n) mod m" by algebra + also have "\ = (((b * q - 1) *\ b (Suc n)) mod m - (q *\ b n) mod m) mod m" by (simp add: mod_diff_eq) + also have "\ = ((((b * q - 1) mod m) * ((\ b (Suc n)) mod m)) mod m - (q *\ b n) mod m) mod m" by (simp add: mod_mult_eq) + also have "\ = ((((q * q) mod m) * ((\ b (Suc n)) mod m)) mod m - (q *\ b n) mod m) mod m" by (simp add: b2) + also have "\ = (((q * q) * (\ b (Suc n))) mod m - (q *\ b n) mod m) mod m" by (simp add: mod_mult_eq) + also have "\ = ((q * q) * (\ b (Suc n)) - q *\ b n) mod m" by (simp add: mod_diff_eq) + also have "\ = (q * (q * (\ b (Suc n)) -\ b n)) mod m" by algebra + also have "\ = ((q mod m) * ((q * (\ b (Suc n)) -\ b n) mod m)) mod m" by (simp add: mod_mult_eq) + finally have c0: "(q * (\ b (Suc n + 1)) -\ b (Suc n)) mod m = ((q mod m) * ((q * (\ b (Suc n)) -\ b n) mod m)) mod m" by simp + from Suc.IH have c1: "\ = ((q ^ (n + 2))) mod m" by (simp add: mod_mult_eq) + + from c0 c1 show ?case by simp +qed + +text \This is a more convenient version of (86)\ + +lemma 860: + fixes b r and q::int + defines "m \ b * q - q * q - 1" + shows "(q * \ b r - (int b * \ b r - \ b (Suc r))) mod m = (q ^ r) mod m" +proof(cases "r=0") + case True + then show ?thesis by simp +next + case False + thus ?thesis using alpha_n[of b "r-1"] 86[of q b "r-1"] m_def by auto +qed + +text \We modify the equivalence (88) in a similar manner\ + +lemma 88: + fixes b r p q:: nat + defines "m \ int b * int q - int q * int q - 1" + assumes "int q ^ r < m" and "q > 0" + shows "int p = int q ^ r \ int p < m \ (q * \ b r - (int b * \ b r - \ b (Suc r))) mod m = int p mod m" + using "Exp_Matrices.860" assms(2) m_def by auto + +lemma 89: + fixes r p q :: nat + assumes "q > 0" + defines "b \ nat (\ (q + 4) (r + 1)) + q * q + 2" + defines "m \ int b * int q - int q * int q - 1" + shows "int q ^ r < m" +proof - + have a0: "int q * int q - 2 * int q + 1 = (int q - 1) * (int q - 1)" by algebra + from assms have a1: "int q * int q * int q \ int q * int q" by simp + from assms a0 a1 have a2: "\ > (int q - 1) * (int q - 1)" by linarith + + from alpha_strictly_increasing have c0: " \ (q + 4) (r + 1) > 0" by simp + from c0 have c1: " \ (q + 4) (r + 1) = int (nat (\ (q + 4) (r + 1)))" by simp + + then have b1: "(q+3) ^ r \ \ (q + 4) (r + 1)" using alpha_exponential_1[of "q+3"] + by(auto simp add: add.commute) + have b3: "int q ^ r \ (q + 3) ^ r" by (simp add: power_mono) + also have b4: "... \ (q + 3) ^ r * int q" using assms by simp + also from assms b1 have b5: "\ \ \ (q + 4) (r + 1) * int q" by simp + also from a2 have b6: "\ < \ (q + 4) (r + 1) * int q + int q * int q * int q - (int q - 1) * (int q - 1)" by simp + also have b7: "\ = ( \ (q + 4) (r + 1) + int q * int q + 2) * q - int q * int q - 1" by algebra + also from assms m_def have b8: "\ = m" using c1 by auto + finally show ?thesis by linarith +qed +end + +text \The final equivalence\ +theorem exp_alpha: + fixes p q r :: nat + shows "p = q ^ r \ ((q = 0 \ r = 0 \ p = 1) \ + (q = 0 \ 0 < r \ p = 0) \ + (q > 0 \ (\b m. + b = Exp_Matrices.\ (q + 4) (r + 1) + q * q + 2 \ + m = b * q - q * q - 1 \ + p < m \ + p mod m = ((q * Exp_Matrices.\ b r) - (int b * Exp_Matrices.\ b r - Exp_Matrices.\ b (r + 1))) mod m)))" +proof(cases "q>0") + case True + show ?thesis (is "?P = ?Q") + proof (rule) + assume ?P + define b where "b = nat (Exp_Matrices.\ (q + 4) (r + 1)) + q * q + 2" + define m where "m = int b * int q - int q * int q - 1" + have sg1: "int b = Exp_Matrices.\ (q + 4) (Suc r) + int q * int q + 2" using b_def + proof- + have "0 \ (Exp_Matrices.\ (q + 4) (r + 1))" using Exp_Matrices.alpha_exponential_1[of "q+3" r] + apply (simp add: add.commute) using zero_le_power[of "int q+3" r] by linarith + then show ?thesis using b_def int_nat_eq[of "(Exp_Matrices.\ (q + 4) (r + 1))"] by simp + qed + have sg2: "q ^ r < b * q - Suc (q * q)" using True "Exp_Matrices.89"[of q r] + of_nat_less_of_nat_power_cancel_iff[of q r " b * q - Suc (q * q)"] + b_def int_ops(6)[of "b * q" "Suc (q * q)"] of_nat_1 of_nat_add of_nat_mult plus_1_eq_Suc by smt + have sg3: "int (q ^ r mod (b * q - Suc (q * q))) + = (int q * Exp_Matrices.\ b r - (int b * Exp_Matrices.\ b r - Exp_Matrices.\ b (Suc r))) + mod int (b * q - Suc (q * q))" + proof- + have "int b * int q - int q * int q - 1 = b * q - Suc (q * q)" + using \q ^ r < b * q - Suc (q * q)\ int_ops(6) by auto + then show ?thesis using "Exp_Matrices.860"[of q b r] by (simp add: zmod_int) + qed + from sg1 sg2 sg3 True show ?Q + by (smt (verit) Suc_eq_plus1_left \p = q ^ r\ add.commute diff_diff_eq of_nat_mult) + next + assume Q: ?Q (is "?A \ ?B \ ?C") + thus ?P + proof (elim disjE) + show "?A \ ?P" by auto + show "?B \ ?P" by auto + show "?C \ ?P" + proof- + obtain b where b_def: "int b = Exp_Matrices.\ (q + 4) (Suc r) + int q * int q + 2" using Q True by auto + have prems3: "p < b * q - Suc (q * q)" using Q True b_def apply (simp add: add.commute) by (metis of_nat_eq_iff) + have prems4: " int p = (int q * Exp_Matrices.\ b r - ((Exp_Matrices.\ (q + 4) (Suc r) + + int q * int q + 2) * Exp_Matrices.\ b r - Exp_Matrices.\ b (Suc r))) mod int (b * q - Suc (q * q))" + using Q True b_def apply (simp add: add.commute) by (metis mod_less of_nat_eq_iff) + define m where "m = int b * int q - int q * int q - 1" + have "int q ^ r < int b * int q - int q * int q - 1" using "Exp_Matrices.89"[of q r] b_def True + by (smt Exp_Matrices.alpha_strictly_increasing One_nat_def Suc_eq_plus1 int_nat_eq nat_2 + numeral_Bit0 of_nat_0_less_iff of_nat_add of_nat_mult one_add_one) + moreover have "int p < m" by (smt gr_implies_not0 int_ops(6) int_ops(7) less_imp_of_nat_less + m_def of_nat_Suc of_nat_eq_0_iff prems3) + moreover have "(int q * Exp_Matrices.\ b r - (int b * Exp_Matrices.\ b r - Exp_Matrices.\ b (Suc r))) mod m = int p mod m" + using prems4 by (smt calculation(2) int_ops(6) m_def mod_pos_pos_trivial of_nat_0_le_iff + of_nat_1 of_nat_add of_nat_mult plus_1_eq_Suc b_def) + ultimately show ?thesis using True "Exp_Matrices.88"[of q "r" b p] m_def by simp + qed + qed + qed +next + case False + then show ?thesis by auto +qed + +lemma alpha_equivalence: + fixes a b c + shows "3 < b \ int a = Exp_Matrices.\ b c \ (\r s t u v w x y. Exp_Matrices.alpha_equations a b c r s t u v w x y)" + using Exp_Matrices.alpha_equiv_suff Exp_Matrices.alpha_equiv_nec + by meson+ + +end \ No newline at end of file diff --git a/thys/DPRM_Theorem/Diophantine/Modulo_Divisibility.thy b/thys/DPRM_Theorem/Diophantine/Modulo_Divisibility.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Diophantine/Modulo_Divisibility.thy @@ -0,0 +1,74 @@ +subsection \Mod is Diophantine\ + +theory Modulo_Divisibility + imports Existential_Quantifier +begin + +text \ Divisibility is diophantine \ +definition dvd ("DVD _ _" 1000) where "DVD Q R \ (BINARY (dvd) Q R)" + +lemma dvd_repr: + fixes a b :: nat + shows "a dvd b \ (\x. x * a = b)" + using dvd_class.dvd_def by auto + +lemma dvd_dioph[dioph]: "is_dioph_rel (DVD Q R)" +proof - + define Q' R' where pushed_defs: "Q' \ push_param Q 1" "R' \ push_param R 1" + define D where "D \ [\] (Param 0 [*] Q' [=] R')" + + have "eval (DVD Q R) a = eval D a" for a + unfolding D_def pushed_defs defs using push_push1 apply (auto simp: push0) + unfolding dvd_def by (auto simp: dvd_repr binary_eval) + + moreover have "is_dioph_rel D" + unfolding D_def by (auto simp: dioph) + + ultimately show ?thesis + by (auto simp: is_dioph_rel_def) +qed + +declare dvd_def[defs] + +(* Congruence is diophantine *) +definition mod ("MOD _ _ _" 1000) + where "MOD A B C \ (TERNARY (\a b c. a mod b = c mod b) A B C)" +declare mod_def[defs] + +lemma mod_repr: + fixes a b c :: nat + shows "a mod b = c mod b \ (\x y. c + x*b = a + y*b)" + by (metis mult.commute nat_mod_eq_iff) + +lemma mod_dioph[dioph]: + fixes A B C + defines "D \ (MOD A B C)" + shows "is_dioph_rel D" +proof - + define A' B' C' where pushed_defs: "A' \ push_param A 2" "B' \ push_param B 2" "C' \ push_param C 2" + define DS where "DS \ [\2] (Param 0 [*] B' [+] C' [=] Param 1 [*] B' [+] A')" + + have "eval DS a = eval D a" for a + proof + show "eval DS a \ eval D a" + unfolding DS_def defs D_def mod_def + by auto (metis mod_mult_self3 push_push_simp pushed_defs(1) pushed_defs(2) pushed_defs(3)) + show "eval D a \ eval DS a" + unfolding DS_def defs D_def mod_def + apply (auto simp add: mod_repr) + subgoal for x y + apply (rule exI[of _ "[x, y]"]) + unfolding pushed_defs by (simp add: push_push[where ?n = 2] push_list_eval) + done + qed + + moreover have "is_dioph_rel DS" + unfolding DS_def by (simp add: dioph) + + ultimately show ?thesis + by (auto simp: is_dioph_rel_def) +qed + +declare mod_def[defs] + +end \ No newline at end of file diff --git a/thys/DPRM_Theorem/Diophantine/Parametric_Polynomials.thy b/thys/DPRM_Theorem/Diophantine/Parametric_Polynomials.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Diophantine/Parametric_Polynomials.thy @@ -0,0 +1,82 @@ +section \Diophantine Equations\ + +theory Parametric_Polynomials + imports Main + abbrevs ++ = "\<^bold>+" and + -- = "\<^bold>-" and + ** = "\<^bold>*" and + 00 = "\<^bold>0" and + 11 = "\<^bold>1" +begin + +subsection \Parametric Polynomials\ + +text \This section defines parametric polynomials and builds up the infrastructure to later prove + that a given predicate or relation is Diophantine. The formalization follows + @{cite "h10lecturenotes"}.\ + +type_synonym assignment = "nat \ nat" + +text \Definition of parametric polynomials with natural number coefficients and their evaluation + function\ + +datatype ppolynomial = + Const nat | + Param nat | + Var nat | + Sum ppolynomial ppolynomial (infixl "\<^bold>+" 65) | + NatDiff ppolynomial ppolynomial (infixl "\<^bold>-" 65) | + Prod ppolynomial ppolynomial (infixl "\<^bold>*" 70) + +fun ppeval :: "ppolynomial \ assignment \ assignment \ nat" where + "ppeval (Const c) p v = c" | + "ppeval (Param x) p v = p x" | + "ppeval (Var x) p v = v x" | + "ppeval (D1 \<^bold>+ D2) p v = (ppeval D1 p v) + (ppeval D2 p v)" | + (* The next line lifts subtraction of type "nat \ nat \ nat" *) + "ppeval (D1 \<^bold>- D2) p v = (ppeval D1 p v) - (ppeval D2 p v)" | + "ppeval (D1 \<^bold>* D2) p v = (ppeval D1 p v) * (ppeval D2 p v)" + +definition Sq_pp ("_ \<^bold>^\<^bold>2" [99] 75) where "Sq_pp P = P \<^bold>* P" + +definition is_dioph_set :: "nat set \ bool" where + "is_dioph_set A = (\P1 P2::ppolynomial. \a. (a \ A) + \ (\v. ppeval P1 (\x. a) v = ppeval P2 (\x. a) v))" + +datatype polynomial = + Const nat | + Param nat | + Sum polynomial polynomial (infixl "[+]" 65) | + NatDiff polynomial polynomial (infixl "[-]" 65) | + Prod polynomial polynomial (infixl "[*]" 70) + +fun peval :: "polynomial \ assignment \ nat" where + "peval (Const c) p = c" | + "peval (Param x) p = p x" | + "peval (Sum D1 D2) p = (peval D1 p) + (peval D2 p)" | + (* The next line lifts subtraction of type "nat \ nat \ nat" *) + "peval (NatDiff D1 D2) p = (peval D1 p) - (peval D2 p)" | + "peval (Prod D1 D2) p = (peval D1 p) * (peval D2 p)" + +definition sq_p :: "polynomial \ polynomial" ("_ [^2]" [99] 75) where "sq_p P = P [*] P" + +definition zero_p :: "polynomial" ("\<^bold>0") where "zero_p = Const 0" +definition one_p :: "polynomial" ("\<^bold>1") where "one_p = Const 1" + +lemma sq_p_eval: "peval (P[^2]) p = (peval P p)^2" + unfolding sq_p_def by (simp add: power2_eq_square) + +fun convert :: "polynomial \ ppolynomial" where + "convert (Const c) = (ppolynomial.Const c)" | + "convert (Param x) = (ppolynomial.Param x)" | + "convert (D1 [+] D2) = (convert D1) \<^bold>+ (convert D2)" | + "convert (D1 [-] D2) = (convert D1) \<^bold>- (convert D2)" | + "convert (D1 [*] D2) = (convert D1) \<^bold>* (convert D2)" + +lemma convert_eval: "peval P a = ppeval (convert P) a v" (* implicit for all v *) + by (induction P, auto) + +definition list_eval :: "polynomial list \ assignment \ (nat \ nat)" where + "list_eval PL a = nth (map (\x. peval x a) PL)" + +end \ No newline at end of file diff --git a/thys/DPRM_Theorem/Diophantine/Register_Machine_Sums.thy b/thys/DPRM_Theorem/Diophantine/Register_Machine_Sums.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Diophantine/Register_Machine_Sums.thy @@ -0,0 +1,123 @@ +subsubsection \Preliminary: Register machine sums are Diophantine\ + +theory Register_Machine_Sums imports Diophantine_Relations + "../Register_Machine/RegisterMachineSimulation" + +begin + +fun sum_polynomial :: "(nat \ polynomial) \ nat list \ polynomial" where + "sum_polynomial f [] = Const 0" | + "sum_polynomial f (i#idxs) = f i [+] sum_polynomial f idxs" + +lemma sum_polynomial_eval: + "peval (sum_polynomial f idxs) a = (\k=0.. (xs ! xa) = (xs @ [x]) ! xa" for xa + by (simp add: nth_append) + ultimately show ?case by auto +qed + + +definition sum_program :: "program \ (nat \ polynomial) \ polynomial" + ("[\_] _" [100, 100] 100) where + "[\p] f \ sum_polynomial f [0.. length l = length p \ + peval ([\p] (\k. if g k then map (\x. push_param x m) l ! k else h k)) (push_list a ns) + = peval ([\p] (\k. if g k then l ! k else h k)) a" + unfolding sum_program_def apply (induction p, auto) + oops + +definition sum_radd_polynomial :: "program \ register \ (nat \ polynomial) \ polynomial" + ("[\R+] _ _ _") where + "[\R+] p l f \ [\p] (\k. if isadd (p!k) \ l = modifies (p!k) then f k else Const 0)" + +lemma sum_radd_polynomial_eval[defs]: + assumes "length p > 0" + shows "peval ([\R+] p l f) a = (\R+ p l (\x. peval (f x) a))" +proof - + have 1: "x \ length p - Suc 0 \ x < length p" for x using assms by linarith + have 2: "x \ length p - Suc 0 \ peval (f ([0.. register \ (nat \ polynomial) \ polynomial" + ("[\R-] _ _ _") where + "[\R-] p l f \ [\p] (\k. if issub (p!k) \ l = modifies (p!k) then f k else Const 0)" + +lemma sum_rsub_polynomial_eval[defs]: + assumes "length p > 0" + shows "peval ([\R-] p l f) a = (\R- p l (\x. peval (f x) a))" +proof - + have 1: "x \ length p - Suc 0 \ x < length p" for x using assms by linarith + have 2: "x \ length p - Suc 0 \ peval (f ([0.. state \ (nat \ polynomial) \ polynomial" + ("[\S+] _ _ _") where + "[\S+] p d f \ [\p] (\k. if isadd (p!k) \ d = goes_to (p!k) then f k else Const 0)" + +lemma sum_sadd_polynomial_eval[defs]: + assumes "length p > 0" + shows "peval ([\S+] p d f) a = (\S+ p d (\x. peval (f x) a))" +proof - + have 1: "x \ length p - Suc 0 \ x < length p" for x using assms by linarith + have 2: "x \ length p - Suc 0 \ peval (f ([0.. state \ (nat \ polynomial) \ polynomial" + ("[\S-] _ _ _") where + "[\S-] p d f \ [\p] (\k. if issub (p!k) \ d = goes_to (p!k) then f k else Const 0)" + +lemma sum_ssub_nzero_polynomial_eval[defs]: + assumes "length p > 0" + shows "peval ([\S-] p d f) a = (\S- p d (\x. peval (f x) a))" +proof - + have 1: "x \ length p - Suc 0 \ x < length p" for x using assms by linarith + have 2: "x \ length p - Suc 0 \ peval (f ([0.. state \ (nat \ polynomial) \ polynomial" + ("[\S0] _ _ _") where + "[\S0] p d f \ [\p] (\k. if issub (p!k) \ d = goes_to_alt (p!k) then f k else Const 0)" + +lemma sum_ssub_zero_polynomial_eval[defs]: + assumes "length p > 0" + shows "peval ([\S0] p d f) a = (\S0 p d (\x. peval (f x) a))" +proof - + have 1: "x \ length p - Suc 0 \ x < length p" for x using assms by linarith + have 2: "x \ length p - Suc 0 \ peval (f ([0..Wrap-Up: Combining all equations\ + +theory All_Equations + imports All_Equations_Invariance + +begin + +context register_machine +begin + +definition all_equations_relation :: "polynomial \ polynomial \ polynomial \ polynomial + \ polynomial \ polynomial \ polynomial \ polynomial list \ polynomial list \ polynomial list + \ relation" ("[ALLEQ] _ _ _ _ _ _ _ _ _ _") where + "[ALLEQ] a q b c d e f r z s + \ LARY (\ll. all_equations (ll!0!0) (ll!0!1) (ll!0!2) (ll!0!3) (ll!0!4) (ll!0!5) (ll!0!6) + (nth (ll!1)) (nth (ll!2)) (nth (ll!3))) + [[a, q, b, c, d, e, f], r, z, s]" + +lemma all_equations_dioph: + fixes A f e d c b q :: polynomial + fixes r z s :: "polynomial list" + assumes "length r = n" "length z = n" "length s = Suc m" + defines "DR \ [ALLEQ] A q b c d e f r z s" + shows "is_dioph_rel DR" +proof - + define DS where "DS \ ([REG] A b q r z s) + [\] ([STATE] b e q z s) + [\] ([MASK] c d e f r z) + [\] ([CONST] b c d e f q) + [\] [MISC] A c q" + + have "eval DS a = eval DR a" for a + unfolding DR_def DS_def all_equations_relation_def all_equations_def + unfolding register_equations_relation_def state_equations_relation_def + mask_equations_relation_def rm_constant_equations_def rm_miscellaneous_equations_def + by (simp add: defs) + + moreover have "is_dioph_rel DS" + unfolding DS_def apply (rule and_dioph)+ + apply (simp_all add: rm_constant_equations_dioph rm_miscellaneous_equations_dioph) + using assms reg_dioph[of r z s A b q] state_equations_dioph[of s z b e q] + mask_equations_relation_dioph[of r z c d e f] by metis+ + + ultimately show ?thesis using is_dioph_rel_def by auto +qed + +definition rm_equations :: "nat \ bool" where + "rm_equations a \ \ q :: nat. + \ b c d e f :: nat. + \ r z :: register \ nat. + \ s :: state \ nat. + all_equations a q b c d e f r z s" + +definition rm_equations_relation :: "polynomial \ relation" ("[RM] _") where + "[RM] A \ UNARY (rm_equations) A" + +(* Correct assumptions: Need validity of p *) + +lemma rm_dioph: + fixes A + fixes ic :: configuration + defines "DR \ [RM] A" + shows "is_dioph_rel DR" +proof - + define q b c d e f where "q \ Param 0" and + "b \ Param 1" and + "c \ Param 2" and + "d \ Param 3" and + "e \ Param 4" and + "f \ Param 5" + + define r where "r \ map Param [6.. map Param [n+6..<2*n + 6]" + define s where "s \ map Param [2*n + 6..<2*n + 6 + m + 1]" + + define number_of_ex_vars where "number_of_ex_vars \ 2*n + 6 + m + 1" + + define A' where "A' \ push_param A number_of_ex_vars" + + define DS where "DS \ [\number_of_ex_vars] [ALLEQ] A' q b c d e f r z s" + + have "length r = n" and "length z = n" and "length s = Suc m" + unfolding r_def z_def s_def by auto + + have "eval DS a = eval DR a" for a + proof (rule) + assume "eval DS a" + then obtain ks where + ks_length: "number_of_ex_vars = length ks" and + ALLEQ: "eval ([ALLEQ] A' q b c d e f r z s) (push_list a ks)" + unfolding DS_def by (auto simp add: defs) + + define q' b' c' d' e' f' where "q' \ ks!0" and + "b' \ ks!1" and + "c' \ ks!2" and + "d' \ ks!3" and + "e' \ ks!4" and + "f' \ ks!5" + + define r_list where "r_list \ (take n (drop 6 ks))" + define z_list where "z_list \ (take n (drop (6+n) ks))" + define s_list where "s_list \ (drop (6 + 2*n) ks)" + + define r' where "r' \ (!) r_list" + define z' where "z' \ (!) z_list" + define s' where "s' \ (!) s_list" + + have A: "peval A' (push_list a ks) = peval A a" for a + using ks_length push_push_simp unfolding A'_def by auto + + have q: "peval q (push_list a ks) = q'" + unfolding q_def q'_def push_list_def using ks_length unfolding number_of_ex_vars_def by auto + have b: "peval b (push_list a ks) = b'" + unfolding b_def b'_def push_list_def using ks_length unfolding number_of_ex_vars_def by auto + have c: "peval c (push_list a ks) = c'" + unfolding c_def c'_def push_list_def using ks_length unfolding number_of_ex_vars_def by auto + have d: "peval d (push_list a ks) = d'" + unfolding d_def d'_def push_list_def using ks_length unfolding number_of_ex_vars_def by auto + have e: "peval e (push_list a ks) = e'" + unfolding e_def e'_def push_list_def using ks_length unfolding number_of_ex_vars_def by auto + have f: "peval f (push_list a ks) = f'" + unfolding f_def f'_def push_list_def using ks_length unfolding number_of_ex_vars_def by auto + + have r: "(!) (map (\P. peval P (push_list a ks)) r) x = (!) r_list x" if "x < n" for x + unfolding r_def r_list_def using that unfolding push_list_def + using ks_length unfolding number_of_ex_vars_def by auto + + have z: "(map (\P. peval P (push_list a ks)) z) ! x = z_list ! x" if "x < n" for x + unfolding z_def z_list_def using that unfolding push_list_def + using ks_length unfolding number_of_ex_vars_def by (auto simp add: add.commute) + + have s: "(map (\P. peval P (push_list a ks)) s) ! x = s_list ! x" if "x < Suc m" for x + unfolding s_def s_list_def using that unfolding push_list_def + using ks_length unfolding number_of_ex_vars_def by (auto simp add: add.commute) + + have "all_equations (peval A a) q' b' c' d' e' f' r' z' s'" + using ALLEQ unfolding all_equations_relation_def apply (simp add: defs) + unfolding A q b c d e f + using all_equations_invariance[of + "(!) (map (\P. peval P (push_list a ks)) r)" r' + "(!) (map (\P. peval P (push_list a ks)) z)" z' + "(!) (map (\P. peval P (push_list a ks)) s)" s' + "peval A a" q' b' c' d' e' f'] r z s + using r'_def s'_def z'_def by fastforce + + thus "eval DR a" + unfolding DR_def rm_equations_def rm_equations_relation_def by (auto simp: defs) (blast) + next + assume "eval DR a" + then obtain q' b' c' d' e' f' r' z' s' where + all_eq: "all_equations (peval A a) q' b' c' d' e' f' r' z' s'" + unfolding DR_def rm_equations_def rm_equations_relation_def by (auto simp: defs) + + define r_list where "r_list \ map r' [0.. map z' [0.. map s' [0.. [q', b', c', d', e', f'] @ r_list @ z_list @ s_list" + + have "number_of_ex_vars = length ks" + unfolding number_of_ex_vars_def ks_def r_list_def z_list_def s_list_def by auto + + have A: "peval A' (push_list a ks) = peval A a" for a + unfolding A'_def + using push_push_simp[of A ks a] unfolding \number_of_ex_vars = length ks\ by auto + + + have q: "peval q (push_list a ks) = q'" + unfolding q_def ks_def push_list_def by auto + have b: "peval b (push_list a ks) = b'" + unfolding b_def ks_def push_list_def by auto + have c: "peval c (push_list a ks) = c'" + unfolding c_def ks_def push_list_def by auto + have d: "peval d (push_list a ks) = d'" + unfolding d_def ks_def push_list_def by auto + have e: "peval e (push_list a ks) = e'" + unfolding e_def ks_def push_list_def by auto + have f: "peval f (push_list a ks) = f'" + unfolding f_def ks_def push_list_def by auto + + have r: "(map (\P. peval P (push_list a ks)) r) ! x = r' x" if "x < n" for x + using that unfolding ks_def r_list_def r_def push_list_def + using nth_append[of "map r' [0..P. peval P (push_list a ks)) z) ! x = z' x" if "x < n" for x + using that unfolding ks_def z_list_def r_list_def z_def push_list_def apply simp + using nth_append[of "map r' [0..P. peval P (push_list a ks)) s) ! x = s' x" if "x < Suc m" for x + using that unfolding ks_def r_list_def z_list_def s_list_def s_def push_list_def apply simp + using nth_append[of "map r' [0..P. peval P (push_list a ks)) r)" r' + "(!) (map (\P. peval P (push_list a ks)) z)" z' + "(!) (map (\P. peval P (push_list a ks)) s)" s' + "peval A a" q' b' c' d' e' f'] r z s + using r_list_def s_list_def z_list_def by auto + + thus "eval DS a" + unfolding DS_def using \number_of_ex_vars = length ks\ by (auto) + qed + + moreover have "is_dioph_rel DS" + unfolding DS_def + using all_equations_dioph \length r = n\ \length z = n\ \length s = Suc m\ assms + by (auto simp: dioph) + + ultimately show ?thesis + using is_dioph_rel_def by auto + +qed + +end + +end \ No newline at end of file diff --git a/thys/DPRM_Theorem/Machine_Equations/All_Equations_Invariance.thy b/thys/DPRM_Theorem/Machine_Equations/All_Equations_Invariance.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Machine_Equations/All_Equations_Invariance.thy @@ -0,0 +1,140 @@ +subsubsection \Invariance of equations\ + +theory All_Equations_Invariance + imports Register_Equations All_State_Equations Mask_Equations Constants_Equations + +begin + +context register_machine +begin + +definition all_equations where + "all_equations a q b c d e f r z s + \ rm_eq_fixes.register_equations p n a b q r z s + \ rm_eq_fixes.state_equations p b e q z s + \ rm_eq_fixes.mask_equations n c d e f r z + \ rm_eq_fixes.constants_equations b c d e f q + \ rm_eq_fixes.miscellaneous_equations a c q" + +lemma all_equations_invariance: + fixes r z s :: "nat \ nat" + and r' z' s' :: "nat \ nat" + assumes "\iii r i = r' i" for i + using assms by auto + have z: "i z i = z' i" for i + using assms by auto + have s: "i s i = s' i" for i + using assms by auto + + have "length p > 0" using p_nonempty by auto + have "n > 0" using n_gt_0 by auto + + have z_at_modifies: "z (modifies (p ! k)) = z' (modifies (p ! k))" if "k < length p" for k + using z[of "modifies (p!k)"] m_def modifies_yields_valid_register that by auto + + have "rm_eq_fixes.register_equations p n a b q r z s + = rm_eq_fixes.register_equations p n a b q r' z' s'" + proof - + + have sum_radd: "\R+ p d s = \R+ p d s'" for d + by (rule sum_radd_cong, auto simp: s m_def) + + have sum_rsub: "\R- p d (\k. s k && z d) = \R- p d (\k. s' k && z' d)" for d + apply (rule sum_rsub_cong) using s z m_def z_at_modifies \length p > 0\ + by (auto, metis Suc_pred \0 < length p\ le_imp_less_Suc) + + have "rm_eq_fixes.register_0 p a b r z s = rm_eq_fixes.register_0 p a b r' z' s'" + using rm_eq_fixes_def local.register_machine_axioms rm_eq_fixes.register_0_def sum_radd[of 0] + sum_rsub[of 0] using r \n > 0\ by auto + + moreover have "rm_eq_fixes.register_l p n b r z s = rm_eq_fixes.register_l p n b r' z' s'" + using rm_eq_fixes.register_l_def sum_radd sum_rsub rm_eq_fixes_def + local.register_machine_axioms using r \n > 0\ by auto + + moreover have "rm_eq_fixes.register_bound n b q r = rm_eq_fixes.register_bound n b q r'" + using rm_eq_fixes_def local.register_machine_axioms rm_eq_fixes.register_bound_def + using r by auto + + ultimately show ?thesis + using rm_eq_fixes_def local.register_machine_axioms rm_eq_fixes.register_equations_def + by auto + qed + + moreover have "rm_eq_fixes.state_equations p b e q z s + = rm_eq_fixes.state_equations p b e q z' s'" + proof - + have "rm_eq_fixes.state_relations_from_recursion p b e z s + = rm_eq_fixes.state_relations_from_recursion p b e z' s'" + proof - + + have sum_sadd: "\S+ p d s = \S+ p d s'" for d + by (rule sum_sadd_cong, auto simp: s m_def) + + have sum_ssub_nzero: "\S- p d (\k. s k && z (modifies (p ! k))) + = \S- p d (\k. s' k && z' (modifies (p ! k)))" for d + apply (rule sum_ssub_nzero_cong) using z_at_modifies z s + by (metis One_nat_def Suc_pred \0 < length p\ le_imp_less_Suc m_def) + + have sum_ssub_zero: "\S0 p d (\k. s k && e - z (modifies (p ! k))) + = \S0 p d (\k. s' k && e - z' (modifies (p ! k)))" for d + apply (rule sum_ssub_zero_cong) using z_at_modifies z s + by (metis One_nat_def Suc_pred \0 < length p\ le_imp_less_Suc m_def) + + have "rm_eq_fixes.state_0 p b e z s = rm_eq_fixes.state_0 p b e z' s'" + using rm_eq_fixes.state_0_def sum_sadd sum_ssub_nzero sum_ssub_zero + rm_eq_fixes_def local.register_machine_axioms + using s by auto + + moreover have "rm_eq_fixes.state_d p b e z s = rm_eq_fixes.state_d p b e z' s'" + using rm_eq_fixes.state_d_def sum_sadd sum_ssub_nzero sum_ssub_zero + rm_eq_fixes_def local.register_machine_axioms + using s by auto + + ultimately show ?thesis + using rm_eq_fixes_def local.register_machine_axioms + rm_eq_fixes.state_relations_from_recursion_def by auto + qed + + moreover have "rm_eq_fixes.state_unique_equations p b e q s + = rm_eq_fixes.state_unique_equations p b e q s'" + using rm_eq_fixes.state_unique_equations_def + rm_eq_fixes_def local.register_machine_axioms rm_eq_fixes.state_mask_def + rm_eq_fixes.state_bound_def + using s by force + + ultimately show ?thesis + using rm_eq_fixes_def local.register_machine_axioms rm_eq_fixes.state_equations_def + rm_eq_fixes.state_mask_def rm_eq_fixes.state_bound_def rm_eq_fixes.state_m_def + rm_eq_fixes.state_partial_sum_mask_def using s z by auto + qed + + moreover have "rm_eq_fixes.mask_equations n c d e f r z = + rm_eq_fixes.mask_equations n c d e f r' z'" + proof - + have "rm_eq_fixes.register_mask n d r = rm_eq_fixes.register_mask n d r'" + using rm_eq_fixes_def local.register_machine_axioms rm_eq_fixes.register_mask_def r by auto + + moreover have "rm_eq_fixes.zero_indicator_mask n e z = rm_eq_fixes.zero_indicator_mask n e z'" + using rm_eq_fixes.zero_indicator_mask_def rm_eq_fixes_def local.register_machine_axioms z + by auto + + moreover have "rm_eq_fixes.zero_indicator_0_or_1 n c d f r z + = rm_eq_fixes.zero_indicator_0_or_1 n c d f r' z'" + using rm_eq_fixes_def local.register_machine_axioms rm_eq_fixes.zero_indicator_0_or_1_def + using r z by auto + + ultimately show ?thesis + using rm_eq_fixes_def local.register_machine_axioms rm_eq_fixes.mask_equations_def by auto + qed + + ultimately show ?thesis + unfolding all_equations_def by auto +qed + + +end + +end \ No newline at end of file diff --git a/thys/DPRM_Theorem/Machine_Equations/All_State_Equations.thy b/thys/DPRM_Theorem/Machine_Equations/All_State_Equations.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Machine_Equations/All_State_Equations.thy @@ -0,0 +1,142 @@ +subsubsection \Wrap-up: Combining all state equations\ + +theory All_State_Equations imports State_Unique_Equations State_d_Equation + +begin + +text \The remaining equations:\ + +context rm_eq_fixes +begin + + text \Equation 4.27\ + definition state_m :: "bool" where + "state_m \ s m = b ^ q" + + text \Equation not in the book\ + definition state_partial_sum_mask :: "bool" where + "state_partial_sum_mask \ \M\m. (\k\M. s k) \ e" + + text \Wrapping it all up\ + + definition state_equations :: "bool" where + "state_equations \ state_relations_from_recursion \ state_unique_equations + \ state_partial_sum_mask \ state_m" + +end + +context register_machine +begin + +lemma state_m_dioph: + fixes b q :: polynomial + fixes s :: "polynomial list" + assumes "length s = Suc m" + defines "DR \ LARY (\ll. rm_eq_fixes.state_m p (ll!0!0) (ll!0!1) (nth (ll!1))) [[b, q], s]" + shows "is_dioph_rel DR" +proof - + define DS where "DS \ [(s!m) = b ^ q]" + + have "eval DS a = eval DR a" for a + using DS_def DR_def rm_eq_fixes.state_m_def rm_eq_fixes_def local.register_machine_axioms + using assms by (simp add: defs) + + moreover have "is_dioph_rel DS" + unfolding DS_def by (auto simp: dioph) + + ultimately show ?thesis using is_dioph_rel_def by auto +qed + +lemma state_partial_sum_mask_dioph: + fixes e :: polynomial + fixes s :: "polynomial list" + assumes "length s = Suc m" + defines "DR \ LARY (\ll. rm_eq_fixes.state_partial_sum_mask p (ll!0!0) (nth (ll!1))) [[e], s]" + shows "is_dioph_rel DR" +proof - + + define partial_sum_mask where "partial_sum_mask \ (\m. (sum_polynomial (nth s) [0..] e))" + define DS where "DS \ [\j = 0.. peval e a) + = ((\j = 0.. peval e a)" for k + proof - + have "[0..j = 0..j = 0..j = 0..P. peval P a) s)) {..k})" if "k\m" for k + apply (rule sum.cong, auto) + by (metis assms(1) dual_order.strict_trans le_imp_less_Suc nth_map + order.not_eq_order_implies_strict that) + + have "eval DS a = (\kj = 0.. peval e a)" + unfolding DS_def partial_sum_mask_def using aux + by (simp add: defs \length s = Suc m\ sum_polynomial_eval) + + also have "... = (\k\m. + (\j = 0.. peval e a)" + by (simp add: less_Suc_eq_le) + + finally show ?thesis using rm_eq_fixes_def local.register_machine_axioms DR_def + rm_eq_fixes.state_partial_sum_mask_def aux2 by (simp add: defs) + qed + + moreover have "is_dioph_rel DS" + unfolding DS_def partial_sum_mask_def by (auto simp: dioph) + + ultimately show ?thesis using is_dioph_rel_def by auto +qed + +definition state_equations_relation :: "polynomial \ polynomial \ polynomial \ polynomial list + \ polynomial list \ relation" ("[STATE] _ _ _ _ _")where + "[STATE] b e q z s \ LARY (\ll. rm_eq_fixes.state_equations p (ll!0!0) (ll!0!1) (ll!0!2) + (nth (ll!1)) (nth (ll!2))) + [[b, e, q], z, s]" + +lemma state_equations_dioph: + fixes b e q :: polynomial + fixes s z :: "polynomial list" + assumes "length s = Suc m" "length z = n" + defines "DR \ [STATE] b e q z s" + shows "is_dioph_rel DR" +proof - + + define DS where + "DS \ (LARY (\ll. rm_eq_fixes.state_relations_from_recursion p (ll!0!0) (ll!0!1) + (nth (ll!1)) (nth (ll!2))) [[b, e], z, s]) + [\] (LARY (\ll. rm_eq_fixes.state_unique_equations p (ll!0!0) (ll!0!1) (ll!0!2) (nth (ll!1))) + [[b, e, q], s]) + [\] (LARY (\ll. rm_eq_fixes.state_partial_sum_mask p (ll!0!0) (nth (ll!1))) [[e], s]) + [\] (LARY (\ll. rm_eq_fixes.state_m p (ll!0!0) (ll!0!1) (nth (ll!1))) [[b, q], s])" + + have "eval DS a = eval DR a" for a + using DS_def DR_def rm_eq_fixes.state_equations_def + state_equations_relation_def rm_eq_fixes_def local.register_machine_axioms by (auto simp: defs) + + moreover have "is_dioph_rel DS" + unfolding DS_def using assms state_relations_from_recursion_dioph[of z s] state_m_dioph[of s] + state_partial_sum_mask_dioph state_unique_equations_dioph and_dioph + by (auto simp: dioph) + + ultimately show ?thesis using is_dioph_rel_def by auto +qed + +end + +end + diff --git a/thys/DPRM_Theorem/Machine_Equations/Constants_Equations.thy b/thys/DPRM_Theorem/Machine_Equations/Constants_Equations.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Machine_Equations/Constants_Equations.thy @@ -0,0 +1,137 @@ +subsubsection \Equations for arithmetization constants\ + +theory Constants_Equations imports Equation_Setup "../Register_Machine/MachineMasking" + "../Diophantine/Binary_And" + +begin + +context rm_eq_fixes +begin + + text \Equation 4.14\ + definition constant_b :: "bool" where + "constant_b \ b = B c" + + text \Equation 4.16\ + definition constant_d :: "bool" where + "constant_d \ d = D q c b" + + text \Equation 4.18\ + definition constant_e :: "bool" where + "constant_e \ e = E q b" + + text \Equation 4.21\ + definition constant_f :: "bool" where + "constant_f \ f = F q c b" + + text \Equation not in the book\ + definition c_gt_0 :: "bool" where + "c_gt_0 \ c > 0" + + text \Equation 4.26\ + definition a_bound :: "bool" where + "a_bound \ a < 2 ^ c" + + text \Equation not in the book\ + definition q_gt_0 :: "bool" where + "q_gt_0 \ q > 0" + + + definition constants_equations :: "bool" where + "constants_equations \ constant_b \ constant_d \ constant_e \ constant_f" + + definition miscellaneous_equations :: "bool" where + "miscellaneous_equations \ c_gt_0 \ a_bound \ q_gt_0 " + +end + +context register_machine +begin + +definition rm_constant_equations :: + "polynomial \ polynomial \ polynomial \ polynomial \ polynomial \ polynomial \ relation" + ("[CONST] _ _ _ _ _ _") where + "[CONST] b c d e f q \ NARY (\l. rm_eq_fixes.constants_equations + (l!0) (l!1) (l!2) (l!3) (l!4) (l!5)) [b, c, d, e, f, q]" + +definition rm_miscellaneous_equations :: + "polynomial \ polynomial \ polynomial \ relation" + ("[MISC] _ _ _") where + "[MISC] c a q \ NARY (\l. rm_eq_fixes.miscellaneous_equations + (l!0) (l!1) (l!2)) [c, a, q]" + +lemma rm_constant_equations_dioph: + fixes b c d e f q + defines "DR \ [CONST] b c d e f q" + shows "is_dioph_rel DR" +proof- + have fx: "rm_eq_fixes p n" + using rm_eq_fixes_def local.register_machine_axioms by auto + + define b' c' d' e' f' q' where pushed_defs: + "b' = (push_param b 2)" "c' = (push_param c 2)" "d' = (push_param d 2)" + "e' = (push_param e 2)" "f' = (push_param f 2)" "q' = (push_param q 2)" + + define s t where params_def: "s = Param 0" "t = Param 1" + + (* using equations (4.31) - (4.33) *) + define DS1 where "DS1 \ [b' = Const 2 ^ (c' [+] \<^bold>1)] [\] + [s = Const 2 ^ c'] [\] [t = b' ^ (q' [+] \<^bold>1)] [\] + (b' [-] \<^bold>1) [*] d' [=] (s [-] \<^bold>1) [*] (t [-] \<^bold>1)" + + define DS2 where "DS2 \ (b' [-] \<^bold>1) [*] e' [=] t [-] \<^bold>1 [\] + (b' [-] \<^bold>1) [*] f' [=] s [*] (t [-] \<^bold>1)" + + define DS where "DS \ [\2] DS1 [\] DS2" + + have "eval DS a = eval DR a" for a + unfolding DR_def DS_def DS1_def DS2_def rm_constant_equations_def defs + apply (auto simp add: fx rm_eq_fixes.constants_equations_def[of p n]) + unfolding pushed_defs params_def push_push apply (auto simp add: push_list_eval) + apply (auto simp add: fx rm_eq_fixes.constant_b_def[of p n] B_def + rm_eq_fixes.constant_d_def[of p n] rm_eq_fixes.constant_e_def[of p n] + rm_eq_fixes.constant_f_def[of p n]) + using d_geom_series[of "2 * 2 ^ peval c a" "peval c a" "(peval q a)" " peval d a"] + using e_geom_series[of "(2 * 2 ^ peval c a)" "peval q a" "peval e a"] + using f_geom_series[of "2 * 2 ^ peval c a" "peval c a" "(peval q a)" " peval f a"] + apply (auto) + apply (rule exI[of _ "[2 ^ peval c a, peval b a * peval b a ^ peval q a]"]) + using push_list_def push_push by auto + + + moreover have "is_dioph_rel DS" unfolding DS_def DS1_def DS2_def by (simp add: dioph) + + ultimately show ?thesis + by (simp add: is_dioph_rel_def) +qed + +lemma rm_miscellaneous_equations_dioph: + fixes c a q + defines "DR \ [MISC] a c q" + shows "is_dioph_rel DR" +proof- + define c' a' q' where pushed_defs: + "c' == (push_param c 1)" "a' == (push_param a 1)" "q' = (push_param q 1)" + + define DS where "DS \ [\] c' [>] \<^bold>0 + [\] [(Param 0) = (Const 2) ^ c'] [\] a'[<] Param 0 + [\] q' [>] \<^bold>0" + + have "eval DS a = eval DR a" for a unfolding DS_def defs DR_def + using rm_miscellaneous_equations_def + rm_eq_fixes.miscellaneous_equations_def rm_eq_fixes.c_gt_0_def rm_eq_fixes.a_bound_def + rm_eq_fixes.q_gt_0_def rm_eq_fixes_def local.register_machine_axioms apply auto + unfolding pushed_defs push_push1 + apply (auto, rule exI[of _ "2 ^ peval c a"]) unfolding push0 by auto + + + moreover have "is_dioph_rel DS" unfolding DS_def by (simp add: dioph) + + ultimately show ?thesis + by (simp add: is_dioph_rel_def) +qed + + +end + +end \ No newline at end of file diff --git a/thys/DPRM_Theorem/Machine_Equations/Equation_Setup.thy b/thys/DPRM_Theorem/Machine_Equations/Equation_Setup.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Machine_Equations/Equation_Setup.thy @@ -0,0 +1,38 @@ +subsection \Arithmetizing equations are Diophantine\ + +theory Equation_Setup imports "../Register_Machine/RegisterMachineSpecification" + "../Diophantine/Diophantine_Relations" + +begin + +locale register_machine = + fixes p :: program + and n :: nat + assumes p_nonempty: "length p > 0" + and valid_program: "program_register_check p n" + assumes n_gt_0: "n > 0" + +begin + + definition m :: "nat" where + "m \ length p - 1" + + lemma modifies_yields_valid_register: + assumes "k < length p" + shows "modifies (p!k) < n" + proof - + have "instruction_register_check n (p!k)" + using valid_program assms list_all_length program_register_check.simps by auto + + thus ?thesis by (cases "p!k", auto simp: n_gt_0) + qed + +end + +locale rm_eq_fixes = register_machine + + fixes a b c d e f :: "nat" + and q :: nat + and r z :: "register \ nat" + and s :: "state \ nat" + +end \ No newline at end of file diff --git a/thys/DPRM_Theorem/Machine_Equations/Machine_Equation_Equivalence.thy b/thys/DPRM_Theorem/Machine_Equations/Machine_Equation_Equivalence.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Machine_Equations/Machine_Equation_Equivalence.thy @@ -0,0 +1,257 @@ +subsection \Equivalence of register machine and arithmetizing equations\ + +theory Machine_Equation_Equivalence imports All_Equations + "../Register_Machine/MachineEquations" + "../Register_Machine/MultipleToSingleSteps" + +begin + +context register_machine +begin + +lemma conclusion_4_5: + assumes is_val: "is_valid_initial ic p a" + and n_def: "n \ length (snd ic)" + shows "(\q. terminates ic p q) = rm_equations a" +proof (rule) + assume "\q. terminates ic p q" + then obtain q::nat where terminates: "terminates ic p q" by auto + hence "q>0" using terminates_def by auto + + have "\c>1. cells_bounded ic p c" + using terminate_c_exists terminates is_val is_valid_initial_def by blast + then obtain c where c: "cells_bounded ic p c \ c > 1" by auto + + define b where "b \ B c" + define d where "d \ D q c b" + define e where "e \ E q b" + define f where "f \ F q c b" + + have "c>1" using c by auto + + have "b>1" using c b_def B_def + using nat_neq_iff by fastforce + + define r where "r \ RLe ic p b q" + define s where "s \ SKe ic p b q" + define z where "z \ ZLe ic p b q" + + interpret equations: rm_eq_fixes p n a b c d e f q r z s by unfold_locales + + have "equations.mask_equations" + proof - + have "\l d" + using lm04_15_register_masking[of "ic" "p" "c" _ "q"] r_def n_def d_def b_def c by auto + moreover have "\l e" + using lm04_15_zero_masking z_def n_def e_def b_def c by auto + moreover have "\lR+ p 0 s - b * \R- p 0 (\k. s k && z 0)" + using lm04_23_multiple_register1[of "ic" "p" "a" "c" "0" "q"] is_val c terminates `q>0` r_def + s_def z_def b_def bitAND_commutes by auto + moreover have "\l>0. l < n \ r l = b * r l + b * \R+ p l s - b * \R- p l (\k. s k && z l)" + using lm04_22_multiple_register[of "ic" "p" "a" "c" _ "q"] + b_def c terminates r_def s_def z_def is_val bitAND_commutes n_def `q>0` by auto + moreover have "l r l < b^q" for l + proof - + assume "l 2 ^ Suc c - Suc 0" using `c>1` by auto + have "\t. R ic p l t < 2 ^ c" using c `lt. R ic p l t < 2 ^ Suc c - Suc 0" using c_ineq + by (metis dual_order.strict_trans linorder_neqE_nat not_less) + have "(\t = 0..q. b ^ t * R ic p l t) = (\t = 0..(Suc (q-1)). b ^ t * R ic p l t)" + using `q>0` by auto + also have "... = (\t = 0..q-1. b ^ t * R ic p l t) + b^q * R ic p l q" + using Set_Interval.comm_monoid_add_class.sum.atLeast0_atMost_Suc[of _ "q-1"] `q>0` by auto + also have "... = (\t = 0..q-1. b ^ t * R ic p l t)" using Rlq by auto + also have "... < b ^ q" using b_def R_bound + base_summation_bound[of "R ic p l" "c" "q-1"] `q>0` by (auto simp: mult.commute) + finally show ?thesis using r_def RLe_def by auto + qed + ultimately show ?thesis unfolding equations.register_equations_def equations.register_0_def + equations.register_l_def equations.register_bound_def by auto + qed + + moreover have "equations.state_equations" + proof - + have "equations.state_relations_from_recursion" + proof - + have "\d>0. d\m \ s d = b*\S+ p d (\k. s k) + b*\S- p d (\k. s k && z (modifies (p!k))) + + b*\S0 p d (\k. s k && (e - z (modifies (p!k))))" + apply (auto simp: s_def z_def) + using lm04_24_multiple_step_states[of "ic" "p" "a" "c" _ "q"] + b_def c terminates s_def z_def is_val bitAND_commutes m_def `q>0` e_def E_def by auto + moreover have "s 0 = 1 + b*\S+ p 0 (\k. s k) + b*\S- p 0 (\k. s k && z (modifies (p!k))) + + b*\S0 p 0 (\k. s k && (e - z (modifies (p!k))))" + using lm04_25_multiple_step_state1[of "ic" "p" "a" "c" _ "q"] + b_def c terminates s_def z_def is_val bitAND_commutes m_def `q>0` e_def E_def by auto + ultimately show ?thesis unfolding equations.state_relations_from_recursion_def + equations.state_0_def equations.state_d_def equations.state_m_def by auto + qed + + moreover have "equations.state_unique_equations" + proof - + have "k s k < b ^ q" for k + using state_q_bound is_val terminates \q>0\ b_def s_def m_def c by auto + moreover have "k\m \ s k \ e" for k + using state_mask is_val terminates \q>0\ b_def e_def s_def c by auto + ultimately show ?thesis unfolding equations.state_unique_equations_def + equations.state_mask_def equations.state_bound_def by auto + qed + + moreover have "\M\m. sum s {..M} \ e" + using state_sum_mask is_val terminates \q>0\ b_def e_def s_def c `b>1` m_def by auto + + moreover have "s m = b^q" + using halting_condition_04_27[of "ic" "p" "a" "q" "c"] m_def b_def is_val `q>0` terminates + s_def by auto + + ultimately show ?thesis unfolding equations.state_equations_def + equations.state_partial_sum_mask_def equations.state_m_def by auto + qed + + moreover have "equations.constants_equations" + unfolding equations.constants_equations_def equations.constant_b_def + equations.constant_d_def equations.constant_e_def equations.constant_f_def + using b_def d_def e_def f_def by auto + + moreover have "equations.miscellaneous_equations" + proof - + have tapelength: "length (snd ic) > 0" + using is_val is_valid_initial_def[of "ic" "p" "a"] by auto + have "R ic p 0 0 = a" using is_val is_valid_initial_def[of "ic" "p" "a"] + R_def List.hd_conv_nth[of "snd ic"] by auto + moreover have "R ic p 0 0 < 2^c" using c tapelength by auto + ultimately have "a < 2^c" by auto + thus ?thesis unfolding equations.miscellaneous_equations_def equations.c_gt_0_def + equations.a_bound_def equations.q_gt_0_def + using \q > 0\ \c > 1\ by auto + qed + + ultimately show "rm_equations a" unfolding rm_equations_def all_equations_def by blast +next + assume "rm_equations a" + + then obtain q b c d e f r z s where + reg: "rm_eq_fixes.register_equations p n a b q r z s" and + state: "rm_eq_fixes.state_equations p b e q z s" and + mask: "rm_eq_fixes.mask_equations n c d e f r z" and + const: "rm_eq_fixes.constants_equations b c d e f q" and + misc: "rm_eq_fixes.miscellaneous_equations a c q" + unfolding rm_equations_def all_equations_def by auto + + have fx: "rm_eq_fixes p n" + unfolding rm_eq_fixes_def using local.register_machine_axioms by auto + + have "q>0" using misc fx rm_eq_fixes.miscellaneous_equations_def + rm_eq_fixes.q_gt_0_def by auto + have "b>1" using B_def const rm_eq_fixes.constants_equations_def + rm_eq_fixes.constant_b_def fx + by (metis One_nat_def Zero_not_Suc less_one n_not_Suc_n nat_neq_iff nat_power_eq_Suc_0_iff + numeral_2_eq_2 of_nat_0 of_nat_power_eq_of_nat_cancel_iff of_nat_zero_less_power_iff pos2) + have "n>0" using is_val is_valid_initial_def[of "ic" "p" "a"] n_def by auto + have "m>0" using m_def is_val is_valid_initial_def[of "ic" "p"] is_valid_def[of "ic" "p"] by auto + + define Seq where "Seq \ (\k t. nth_digit (s k) t b)" + define Req where "Req \ (\l t. nth_digit (r l) t b)" + define Zeq where "Zeq \ (\l t. nth_digit (z l) t b)" + + (* Quick and dirty: :\| *) + have mask_old: "mask_equations n r z c d e f" and + reg_old: "reg_equations p r z s b a (length (snd ic)) q" and + state_old: "state_equations p s z b e q (length p - 1)" and + const_old: "rm_constants q c b d e f a" + subgoal + using mask rm_eq_fixes.mask_equations_def rm_eq_fixes.register_mask_def fx + mask_equations_def rm_eq_fixes.zero_indicator_0_or_1_def rm_eq_fixes.zero_indicator_mask_def + by simp + subgoal + using reg state mask const misc using rm_eq_fixes.register_equations_def + rm_eq_fixes.register_0_def rm_eq_fixes.register_l_def rm_eq_fixes.register_bound_def + reg_equations_def n_def fx by simp + subgoal + using state fx state_equations_def rm_eq_fixes.state_equations_def + rm_eq_fixes.state_relations_from_recursion_def rm_eq_fixes.state_0_def rm_eq_fixes.state_m_def + rm_eq_fixes.state_d_def rm_eq_fixes.state_unique_equations_def rm_eq_fixes.state_mask_def + rm_eq_fixes.state_bound_def rm_eq_fixes.state_partial_sum_mask_def m_def by simp + subgoal unfolding rm_constants_def + using const misc fx rm_eq_fixes.constants_equations_def + rm_eq_fixes.miscellaneous_equations_def rm_eq_fixes.constant_b_def rm_eq_fixes.constant_d_def + rm_eq_fixes.constant_e_def rm_eq_fixes.constant_f_def rm_eq_fixes.c_gt_0_def + rm_eq_fixes.q_gt_0_def rm_eq_fixes.a_bound_def by simp + done + + hence RZS_eq: "l j\m \ t\q \ + R ic p l t = Req l t \ Z ic p l t = Zeq l t \ S ic p j t = Seq j t" for l j t + using rzs_eq[of "m" "p" "n" "ic" "a" "r" "z"] mask_old reg_old state_old const_old + m_def n_def is_val `q>0` Seq_def Req_def Zeq_def by auto + + have R_eq: "l t\q \ R ic p l t = Req l t" for l t using RZS_eq by auto + have Z_eq: "l t\q \ Z ic p l t = Zeq l t" for l t using RZS_eq by auto + have S_eq: "j\m \ t\q \ S ic p j t = Seq j t" for j t using RZS_eq[of "0"] `n>0` by auto + + have "ishalt (p!m)" using m_def is_val + is_valid_initial_def[of "ic" "p" "a"] is_valid_def[of "ic" "p"] by auto + have "Seq m q = 1" using state nth_digit_def Seq_def `b>1` + using fx rm_eq_fixes.state_equations_def + rm_eq_fixes.state_relations_from_recursion_def + rm_eq_fixes.state_m_def by auto + hence "S ic p m q = 1" using S_eq by auto + hence "fst (steps ic p q) = m" using S_def by(cases "fst (steps ic p q) = m"; auto) + hence qhalt: "ishalt (p ! (fst (steps ic p q)))" using S_def `ishalt (p!m)` by auto + + hence rempty: "snd (steps ic p q) ! l = 0" if "l < n" for l + unfolding R_def[symmetric] + using R_eq[of l q] \l < n\ apply auto + using reg Req_def nth_digit_def + using rm_eq_fixes.register_equations_def + rm_eq_fixes.register_l_def + rm_eq_fixes.register_0_def + rm_eq_fixes.register_bound_def + by (smt Euclidean_Division.div_eq_0_iff mod_if mult_0_right mult_mod_right nat_mult_1_right + zero_less_one fx) + + have state_m_0: "t S ic p m t = 0" for t + proof - + assume "t1 < b\ \t < q\ less_imp_le not_one_le_zero power_diff) + also have "... mod b = 0" using \1 < b\ \t < q\ by simp + finally have mod: "b^q div b^t mod b = 0" by auto + have "s m = b^q" using state fx rm_eq_fixes.state_equations_def + rm_eq_fixes.state_m_def + rm_eq_fixes.state_relations_from_recursion_def by auto + hence "Seq m t = 0" using Seq_def nth_digit_def mod by auto + with S_eq `t < q` show ?thesis by auto + qed + have "\k ishalt (p!k)" + using is_val is_valid_initial_def[of "ic" "p" "a"] is_valid_def[of "ic" "p"] m_def by auto + moreover have "t fst (steps ic p t) < length p - 1" for t + proof (rule ccontr) + assume asm: "\ (t < q \ fst (steps ic p t) < length p - 1)" + hence "t length p - 1" by auto + moreover have "fst (steps ic p t) \ length p - 1" + using p_contains[of "ic" "p" "a" "t"] is_val by auto + ultimately have "fst (steps ic p t) = m" using m_def by auto + hence "S ic p m t = 1" using S_def by auto + thus "False" using state_m_0[of "t"] `t \ ishalt (p ! (fst (steps ic p t)))" for t using m_def by auto + hence no_early_halt: "t \ ishalt (p ! (fst (steps ic p t)))" for t using state_m_0 by auto + + have "correct_halt ic p q" using qhalt rempty correct_halt_def n_def by auto + thus "(\q. terminates ic p q)" using no_early_halt terminates_def `q>0` by auto +qed + +end + +end \ No newline at end of file diff --git a/thys/DPRM_Theorem/Machine_Equations/Mask_Equations.thy b/thys/DPRM_Theorem/Machine_Equations/Mask_Equations.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Machine_Equations/Mask_Equations.thy @@ -0,0 +1,159 @@ +subsubsection \Equations for masking relations\ + +theory Mask_Equations + imports "../Register_Machine/MachineMasking" Equation_Setup "../Diophantine/Binary_And" + +abbrevs mb = "\" + +begin + +context rm_eq_fixes +begin + + text \Equation 4.15\ + definition register_mask :: "bool" where + "register_mask \ \l < n. r l \ d" + + text \Equation 4.17\ + definition zero_indicator_mask :: "bool" where + "zero_indicator_mask \ \l < n. z l \ e" + + text \Equation 4.20\ + definition zero_indicator_0_or_1 :: "bool" where + "zero_indicator_0_or_1 \ \l register_mask \ zero_indicator_mask \ zero_indicator_0_or_1" + +end + +context register_machine +begin + +lemma register_mask_dioph: + fixes d r + assumes "n = length r" + defines "DR \ (NARY (\l. rm_eq_fixes.register_mask n (l!0) (shift l 1)) ([d] @ r))" + shows "is_dioph_rel DR" +proof - + define DS where "DS \ [\i. ((r!i) [\] d))" + + have "eval DS a = eval DR a" for a + proof - + have "eval DR a = rm_eq_fixes.register_mask n (peval d a) (list_eval r a)" + unfolding DR_def by (auto simp add: shift_def list_eval_def) + also have "... = (\l < n. (peval (r!l) a) \ peval d a)" + using rm_eq_fixes.register_mask_def \n = length r\ rm_eq_fixes_def + local.register_machine_axioms by (auto simp: list_eval_def) + finally show ?thesis + unfolding DS_def defs by simp + qed + + moreover have "is_dioph_rel DS" + unfolding DS_def by (auto simp add: dioph) + + ultimately show ?thesis + by (simp add: is_dioph_rel_def) +qed + +lemma zero_indicator_mask_dioph: + fixes e z + assumes "n = length z" + defines "DR \ (NARY (\l. rm_eq_fixes.zero_indicator_mask n (l!0) (shift l 1)) ([e] @ z))" + shows "is_dioph_rel DR" +proof - + define DS where "DS \ [\i. ((z!i) [\] e))" + + have "eval DS a = eval DR a" for a + proof - + have "eval DR a = rm_eq_fixes.zero_indicator_mask n (peval e a) (list_eval z a)" + unfolding DR_def by (auto simp add: shift_def list_eval_def) + also have "... = (\l < n. (peval (z!l) a) \ peval e a)" + using rm_eq_fixes.zero_indicator_mask_def \n = length z\ + rm_eq_fixes_def local.register_machine_axioms by (auto simp: list_eval_def) + finally show ?thesis + unfolding DS_def defs by simp + qed + + moreover have "is_dioph_rel DS" + unfolding DS_def by (auto simp add: dioph) + + ultimately show ?thesis + by (simp add: is_dioph_rel_def) +qed + +lemma zero_indicator_0_or_1_dioph: + fixes c d f r z + assumes "n = length r" and "n = length z" + defines "DR \ LARY (\ll. rm_eq_fixes.zero_indicator_0_or_1 n (ll!0!0) (ll!0!1) (ll!0!2) + (nth (ll!1)) (nth (ll!2))) [[c, d, f], r, z]" + shows "is_dioph_rel DR" +proof - + let ?N = 2 + define c' d' f' r' z' where pushed_def: "c' = push_param c ?N" "d' = push_param d ?N" + "f' = push_param f ?N" "r' = map (\x. push_param x ?N) r" + "z' = map (\x. push_param x ?N) z" + define DS where "DS \ [\i. ([\2] [Param 0 = (Const 2) ^ c'] + [\] [Param 1 = (r'!i) [+] d' && f'] + [\] Param 0 [*] (z'!i) [=] Param 1))" + + have "eval DS a = eval DR a" for a + proof - + have "eval DR a = rm_eq_fixes.zero_indicator_0_or_1 n (peval c a) (peval d a) (peval f a) + (list_eval r a) (list_eval z a)" + unfolding DR_def defs by (auto simp add: assms shift_def list_eval_def) + also have "... = (\l < n. 2^(peval c a) * (peval (z!l) a) + = (peval (r!l) a + peval d a) && peval f a)" + using rm_eq_fixes.zero_indicator_0_or_1_def \n = length r\ using assms + rm_eq_fixes_def local.register_machine_axioms by (auto simp: list_eval_def) + finally show ?thesis + unfolding DS_def defs pushed_def using push_push apply (auto) + subgoal for k + apply (rule exI[of _ "[2^peval c a, peval (r!k) a + peval d a && peval f a]"]) + apply (auto simp: push_list_def assms(1-2)) + by (metis assms(1) assms(2) length_Cons list.size(3) nth_map numeral_2_eq_2) + subgoal + using assms by auto + done + qed + + moreover have "is_dioph_rel DS" + unfolding DS_def by (auto simp add: dioph) + + ultimately show ?thesis + by (simp add: is_dioph_rel_def) +qed + + +definition mask_equations_relation ("[MASK] _ _ _ _ _ _") where + "[MASK] c d e f r z \ LARY (\ll. rm_eq_fixes.mask_equations n + (ll!0!0) (ll!0!1) (ll!0!2) (ll!0!3) (nth (ll!1)) (nth (ll!2))) + [[c, d, e, f], r, z]" + +lemma mask_equations_relation_dioph: + fixes c d e f r z + assumes "n = length r" and "n = length z" + defines "DR \ [MASK] c d e f r z" + shows "is_dioph_rel DR" +proof - + define DS where "DS \ NARY (\l. rm_eq_fixes.register_mask n (l!0) (shift l 1)) ([d] @ r) + [\] NARY (\l. rm_eq_fixes.zero_indicator_mask n (l!0) (shift l 1)) ([e] @ z) + [\] LARY (\ll. rm_eq_fixes.zero_indicator_0_or_1 n (ll!0!0) (ll!0!1) (ll!0!2) + (nth (ll!1)) (nth (ll!2))) [[c, d, f], r, z]" + + have "eval DS a = eval DR a" for a + using DS_def DR_def mask_equations_relation_def rm_eq_fixes.mask_equations_def + rm_eq_fixes_def local.register_machine_axioms by (simp add: defs shift_def) + + moreover have "is_dioph_rel DS" + unfolding DS_def using assms dioph + using register_mask_dioph zero_indicator_mask_dioph zero_indicator_0_or_1_dioph + by (metis (no_types, lifting)) + + ultimately show ?thesis + by (simp add: is_dioph_rel_def) +qed + +end + +end \ No newline at end of file diff --git a/thys/DPRM_Theorem/Machine_Equations/RM_Sums_Diophantine.thy b/thys/DPRM_Theorem/Machine_Equations/RM_Sums_Diophantine.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Machine_Equations/RM_Sums_Diophantine.thy @@ -0,0 +1,110 @@ +theory RM_Sums_Diophantine imports Equation_Setup "../Diophantine/Register_Machine_Sums" + "../Diophantine/Binary_And" + +begin + +context register_machine +begin + +definition sum_ssub_nzero_of_bit_and :: "polynomial \ nat \ polynomial list \ polynomial list + \ relation" + ("[_ = \S- _ '(_ && _')]") where + "[x = \S- d (s && z)] \ let x' = push_param x (length p); + s' = push_param_list s (length p); + z' = push_param_list z (length p) + in [\length p] [\i. [Param i = s'!i && z'!i]) + [\] x' [=] ([\S-] p d Param)" + +lemma sum_ssub_nzero_of_bit_and_dioph[dioph]: + fixes s z :: "polynomial list" and d :: nat and x + shows "is_dioph_rel [x = \S- d (s && z)]" + unfolding sum_ssub_nzero_of_bit_and_def by (auto simp add: dioph) + +lemma sum_rsub_nzero_of_bit_and_eval: + fixes z s :: "polynomial list" and d :: nat and x :: polynomial + assumes "length s = Suc m" "length z = Suc m" "length p > 0" + shows "eval [x = \S- d (s && z)] a + \ peval x a = \S- p d (\k. peval (s!k) a && peval (z!k) a)" (is "?P \ ?Q") +proof - + have invariance: "\k \S- p d y1 = \S- p d y2" for y1 y2 + unfolding sum_ssub_nzero.simps apply (intro sum.cong, simp) + using \length p > 0\ by auto (metis Suc_pred le_imp_less_Suc length_greater_0_conv) + + have len_ps: "length s = length p" + using m_def \length s = Suc m\ \length p > 0\ by auto + have len_pz: "length z = length p" + using m_def \length z = Suc m\ \length p > 0\ by auto + + show ?thesis + proof (rule) + assume ?P + thus ?Q + using sum_ssub_nzero_of_bit_and_def \length p > 0\ apply (auto simp add: defs push_push) + using push_push_map_i apply (simp add: push_param_list_def len_ps len_pz) + unfolding list_eval_def apply (auto simp: assms len_ps len_pz invariance) + apply (rule sum_ssub_nzero_cong) apply auto + by (metis (no_types, lifting) One_nat_def assms(1) assms(2) + le_imp_less_Suc len_ps m_def nth_map) + + next + assume ?Q + thus ?P + using sum_ssub_nzero_of_bit_and_def \length p > 0\ apply (auto simp add: defs push_push) + apply (rule exI[of _ "map (\k. peval (s ! k) a && peval (z ! k) a) [0.. nat \ polynomial list \ polynomial list + \ relation" + ("[_ = \S0 _ '(_ && _')]") where + "[x = \S0 d (s && z)] \ let x' = push_param x (length p); + s' = push_param_list s (length p); + z' = push_param_list z (length p) + in [\length p] [\i. [Param i = s'!i && z'!i]) + [\] x' [=] [\S0] p d Param" + +lemma sum_ssub_zero_of_bit_and_dioph[dioph]: + fixes s z :: "polynomial list" and d :: nat and x + shows "is_dioph_rel [x = \S0 d (s && z)]" + unfolding sum_ssub_zero_of_bit_and_def by (auto simp add: dioph) + +lemma sum_rsub_zero_of_bit_and_eval: + fixes z s :: "polynomial list" and d :: nat and x :: polynomial + assumes "length s = Suc m" "length z = Suc m" "length p > 0" + shows "eval [x = \S0 d (s && z)] a + \ peval x a = \S0 p d (\k. peval (s!k) a && peval (z!k) a)" (is "?P \ ?Q") +proof - + have invariance: "\k \S0 p d y1 = \S0 p d y2" for y1 y2 + unfolding sum_ssub_zero.simps apply (intro sum.cong, simp) + using \length p > 0\ by auto (metis Suc_pred le_imp_less_Suc length_greater_0_conv) + + have len_ps: "length s = length p" + using m_def \length s = Suc m\ \length p > 0\ by auto + have len_pz: "length z = length p" + using m_def \length z = Suc m\ \length p > 0\ by auto + + show ?thesis + proof (rule) + assume ?P + thus ?Q + using sum_ssub_zero_of_bit_and_def \length p > 0\ apply (auto simp add: defs push_push) + using push_push_map_i apply (simp add: push_param_list_def len_ps len_pz) + unfolding list_eval_def apply (auto simp: assms len_ps len_pz invariance) + apply (rule sum_ssub_zero_cong) apply auto + by (metis (no_types, lifting) One_nat_def assms(1) assms(2) + le_imp_less_Suc len_ps m_def nth_map) + next + assume ?Q + thus ?P + using sum_ssub_zero_of_bit_and_def \length p > 0\ apply (auto simp add: defs push_push) + apply (rule exI[of _ "map (\k. peval (s ! k) a && peval (z!k) a) [0..Register Equations\ + +theory Register_Equations imports "../Register_Machine/MultipleStepRegister" + Equation_Setup "../Diophantine/Register_Machine_Sums" + "../Diophantine/Binary_And" "HOL-Library.Rewrite" + +begin + +context rm_eq_fixes +begin + + text \Equation 4.22\ + definition register_0 :: "bool" where + "register_0 \ r 0 = a + b*r 0 + b*\R+ p 0 s - b*\R- p 0 (\k. s k && z 0)" + + text \Equation 4.23\ + definition register_l :: "bool" where + "register_l \ \l>0. l < n \ r l = b*r l + b*\R+ p l s - b*\R- p l (\k. s k && z l)" + + text \Extra equation not in Matiyasevich's book\ + definition register_bound :: "bool" where + "register_bound \ \l < n. r l < b ^ q" + + definition register_equations :: "bool" where + "register_equations \ register_0 \ register_l \ register_bound" + +end + +context register_machine +begin + +definition sum_rsub_of_bit_and :: "polynomial \ nat \ polynomial list \ polynomial + \ relation" + ("[_ = \R- _ '(_ && _')]") where + "[x = \R- d (s && zl)] \ let x' = push_param x (length p); + s' = push_param_list s (length p); + zl' = push_param zl (length p) + in [\length p] [\i. [Param i = s'!i && zl']) + [\] x' [=] [\R-] p d Param" + +lemma sum_rsub_of_bit_and_dioph[dioph]: + fixes s :: "polynomial list" and d :: nat and x zl :: polynomial + shows "is_dioph_rel [x = \R- d (s && zl)]" + unfolding sum_rsub_of_bit_and_def by (auto simp add: dioph) + +lemma sum_rsub_of_bit_and_eval: + fixes z s :: "polynomial list" and d :: nat and x :: polynomial + assumes "length s = Suc m" "length p > 0" + shows "eval [x = \R- d (s && zl)] a + \ peval x a = \R- p d (\k. peval (s!k) a && peval zl a)" (is "?P \ ?Q") +proof - + have invariance: "\k \R- p d y1 = \R- p d y2" for y1 y2 + unfolding sum_rsub.simps apply (intro sum.cong, simp) + using \length p > 0\ by auto (metis Suc_pred le_imp_less_Suc length_greater_0_conv) + + have len_ps: "length s = length p" + using m_def \length s = Suc m\ \length p > 0\ by auto + + have aux1: "peval ([\R-] p l f) a = \R- p l (\x. peval (f x) a) " for l f + using defs \length p > 0\ by auto + + show ?thesis + proof (rule) + assume ?P + thus ?Q + unfolding sum_rsub_of_bit_and_def + using aux1 apply simp + apply (auto simp add: aux1 push_push defs) + using push_push_map_i apply (simp add: push_param_list_def len_ps) + unfolding list_eval_def apply (simp add: assms len_ps invariance) + using assms(2) invariance len_ps sum_rsub_polynomial_eval by force + next + assume ?Q + thus ?P + unfolding sum_rsub_of_bit_and_def apply (auto simp add: aux1 defs push_push) + apply (rule exI[of _ "map (\k. peval (s ! k) a && peval zl a) [0..length p > 0\ defs by simp + qed +qed + + +lemma register_0_dioph[dioph]: + fixes A b :: polynomial + fixes r z s :: "polynomial list" + assumes "length r = n" "length z = n" "length s = Suc m" + defines "DR \ LARY (\ll. rm_eq_fixes.register_0 p (ll!0!0) (ll!0!1) + (nth (ll!1)) (nth (ll!2)) (nth (ll!3))) [[A, b], r, z, s]" + shows "is_dioph_rel DR" +proof - + let ?N = "1" + define A' b' r' z' s' where pushed_def: "A' = push_param A ?N" "b' = push_param b ?N" + "r' = map (\x. push_param x ?N) r" "z' = map (\x. push_param x ?N) z" + "s' = map (\x. push_param x ?N) s" + + define DS where "DS \ [\] ([Param 0 = \R- 0 (s' && (z'!0))] [\] + r'!0 [=] A' [+] b' [*] r'!0 [+] b' [*] ([\R+] p 0 (nth s')) + [-] b' [*] (Param 0))" + + have "length p > 0" using p_nonempty by auto + have "n > 0" using n_gt_0 by auto + + have "length p = length s" + using \length s = Suc m\ m_def \length p > 0\ by auto + have "length s' = length s" + unfolding pushed_def by auto + have "length z > 0" + using \length z = n\ \n > 0\ by simp + have "length r > 0" + using \length r = n\ \n > 0\ by simp + + have "eval DS a = eval DR a" for a + proof - + (* the key to this proof is to write these intermediate steps with list_eval on the RHS + because that is needed in the final proof; otherwise showing the equivalence again + re-requires unfolding the sum definitions *) + have sum_radd_push: "\R+ p 0 (\x. peval (s' ! x) (push a k)) = \R+ p 0 (list_eval s a)" for k + unfolding sum_radd.simps pushed_def apply (intro sum.cong, simp) + using push_push_map1 \length p = length s\ \length s = Suc m\ by simp + + have sum_rsub_push: "\R- p 0 (\x. peval (s' ! x) (push a k) && peval (z' ! 0) (push a k)) + = \R- p 0 (\x. list_eval s a x && peval (z ! 0) a)" for k + unfolding sum_rsub.simps pushed_def apply (intro sum.cong, simp) + using push_push_map1 \length p = length s\ \length s = Suc m\ \length z > 0\ + by (simp add: list_eval_def) + + have 1: "peval ([\R-] p l f) a = \R- p l (\x. peval (f x) a) " for f l + using defs \length p > 0\ by auto + + show ?thesis + unfolding DS_def rm_eq_fixes.register_0_def + register_machine_axioms rm_eq_fixes_def apply (simp add: defs) + using \length p > 0\ apply (simp add: sum_rsub_of_bit_and_eval \length s' = length s\ + \length s = Suc m\) + apply (simp add: sum_radd_push sum_rsub_push) + unfolding pushed_def using push_push1 push_push_map1 \length r > 0\ apply simp + unfolding DR_def assms defs \length p > 0\ + using rm_eq_fixes_def rm_eq_fixes.register_0_def register_machine_axioms apply (simp) + using \length z > 0\ push_def list_eval_def 1 apply (simp add: 1 defs \length p > 0\) + using One_nat_def sum_radd_push unfolding pushed_def(5) list_eval_def by presburger + qed + + moreover have "is_dioph_rel DS" + unfolding DS_def by (simp add: dioph) + + ultimately show ?thesis + by (auto simp: is_dioph_rel_def) +qed + +lemma register_l_dioph[dioph]: + fixes b :: polynomial + fixes r z s :: "polynomial list" + assumes "length r = n" "length z = n" "length s = Suc m" + defines "DR \ LARY (\ll. rm_eq_fixes.register_l p n (ll!0!0) + (nth (ll!1)) (nth (ll!2)) (nth (ll!3))) [[b], r, z, s]" + shows "is_dioph_rel DR" +proof - + define indices where "indices \ [Suc 0..x. push_param x ?N) r" + "z' = map (\x. push_param x ?N) z" + "s' = map (\x. push_param x ?N) s" + + define param_l_is_sum_rsub_of_bitand where + "param_l_is_sum_rsub_of_bitand \ \l. [Param l = \R- l (s' && (z'!l))]" + define params_are_sum_rsub_of_bitand where + "params_are_sum_rsub_of_bitand \ [\ in indices] param_l_is_sum_rsub_of_bitand" + define single_register where + "single_register \ \l. r'!l [=] b' [*] r'!l [+] b' [*] ([\R+] p l (nth s')) [-] b' [*] (Param l)" + + define DS where "DS \ [\n] params_are_sum_rsub_of_bitand [\] [\ in indices] single_register" + + have "length p > 0" using p_nonempty by auto + have "n > 0" using n_gt_0 by auto + have "length p = length s" + using \length s = Suc m\ m_def \length p > 0\ by auto + have "length s' = length s" + unfolding pushed_def by auto + have "length z > 0" + using \length z = n\ \n > 0\ by simp + have "length r > 0" + using \length r = n\ \n > 0\ by simp + have "length indices + 1 = n" + unfolding indices_def \n>0\ + using Suc_pred' \n > 0\ length_upt by presburger + have "length s' = Suc m" + using \length s' = length s\ \length s = Suc m\ by auto + + have "eval DS a = eval DR a" for a + proof - + + have eval_to_peval: + "eval [polynomial.Param (indices ! k) + = \R- indices ! k (s' && z' ! (indices ! k))] y + \(peval (polynomial.Param (indices ! k)) y + = \R- p (indices ! k) (\ka. peval (s' ! ka) y && peval (z' ! (indices ! k)) y) )" for k y + using sum_rsub_of_bit_and_eval \length p > 0\ \length s' = Suc m\ by auto + + have b'_unfold: "peval b' (push_list a ks) = peval b a" if "length ks = n" for ks + unfolding pushed_def using indices_def push_push that \length indices + 1 = n\ by auto + + have r'_unfold: "peval (r' ! (indices ! k)) (push_list a ks) = peval (r!(indices!k)) a" + if "k < length indices" and "length ks = n" for k ks + using indices_def push_push pushed_def that(1) that(2) \length r = n\ by auto + + have Param_unfold: "peval (Param (indices ! k)) (push_list a ks) = ks!(indices!k)" + if "k < length indices" and "length ks = n" for k ks + using One_nat_def Suc_pred indices_def length_upt nat_add_left_cancel_less + nth_upt peval.simps(2) plus_1_eq_Suc push_list_eval that(1) that(2) by (metis \0 < n\) + + have unfold_4: "push_list a ks (indices ! k) = ks!(indices!k)" + if "k < length indices" and "length ks = n" for k ks + using Param_unfold that(1) that(2) by force + + have unfold_sum_radd: "\R+ p (indices ! k) (\x. peval (s' ! x) (push_list a ks)) + = \R+ p (indices ! k) (list_eval s a)" + if "length ks = n" for k ks + apply (rule sum_radd_cong) unfolding pushed_def + using push_push_map_i[of ks n _ s a] \length indices + 1 = n\ that + using \length p = length s\ + by (metis \0 < length p\ add.left_neutral add_lessD1 le_neq_implies_less less_add_one + less_diff_conv less_diff_conv2 nat_le_linear not_add_less1) + + have unfold_sum_rsub: "\R- p (indices ! k) (\ka. peval (s' ! ka) (push_list a ks) + && peval (z' ! (indices ! k)) (push_list a ks)) + = \R- p (indices ! k) (\ka. list_eval s a ka + && peval (z ! (indices ! k)) a)" + if "length ks = n" for k ks + apply (rule sum_rsub_cong) unfolding pushed_def + using push_push_map_i[of ks n _ s a] unfolding \length indices + 1 = n\ + using \length p = length s\ assms apply simp + using nth_map[of _ z "\x. push_param x (Suc (length indices))"] + using modifies_yields_valid_register \length z = n\ + by (smt assms le_imp_less_Suc nth_map push_push_simp that) + + have indices_unfold: "(\k < length indices. P (indices!k)) \ (\l>0. l P l)" for P + unfolding indices_def apply auto + using \n>0\ by (metis Suc_diff_Suc diff_zero not_less_eq) + + have alternative_sum_rsub: + "(\R- p l (\ka. list_eval s a ka && peval (z ! l) a)) + =(\R- p l (\k. map (\P. peval P a) s ! k && map (\P. peval P a) z ! l))" for l + apply (rule sum_rsub_cong) unfolding list_eval_def apply simp + using modifies_yields_valid_register + One_nat_def assms(3) nth_map \length z = n\ \length s = Suc m\ + by (metis \length p = length s\ le_imp_less_Suc m_def) + + (* Start of chain of equalities *) + have "(eval DS a) = (\ks. n = length ks \ + (\kR- (indices ! k) (s' && z' ! (indices ! k))] (push_list a ks)) \ + (\kks. n = length ks \ + (\kR- p (indices ! k) (\ka. peval (s' ! ka) (push_list a ks) + && peval (z' ! (indices ! k)) (push_list a ks)) \ + peval (r' ! (indices ! k)) (push_list a ks) + = peval b' (push_list a ks) * peval (r' ! (indices ! k)) (push_list a ks) + + peval b' (push_list a ks) * \R+ p (indices ! k) + (\x. peval (s' ! x) (push_list a ks)) + - peval b' (push_list a ks) * (push_list a ks (indices ! k))))" + using eval_to_peval unfolding single_register_def + using sum_radd_polynomial_eval \length p > 0\ by (simp add: defs) (blast) + + also have "... = (\ks. n = length ks \ + (\kR- p (indices ! k) (\ka. peval (s' ! ka) (push_list a ks) + && peval (z' ! (indices ! k)) (push_list a ks)) \ + peval (r!(indices!k)) a + = peval b a * peval (r!(indices!k)) a + + peval b a * \R+ p (indices ! k) (\x. peval (s' ! x) (push_list a ks)) + - peval b a * (ks!(indices!k))))" + using b'_unfold r'_unfold Param_unfold unfold_4 by (smt (z3)) + + also have "... = (\ks. n = length ks \ + (\kR- p (indices ! k) (\ka. peval (s' ! ka) (push_list a ks) + && peval (z' ! (indices ! k)) (push_list a ks))) \ + peval (r!(indices!k)) a + = peval b a * peval (r!(indices!k)) a + + peval b a * (\R+ p (indices ! k) (list_eval s a)) + - peval b a * (ks!(indices!k))))" + using unfold_sum_radd by (smt (z3)) + + also have "... = (\ks. n = length ks \ + (\kR- p (indices ! k) (\ka. list_eval s a ka && peval (z ! (indices ! k)) a) + \ peval (r!(indices!k)) a + = peval b a * peval (r!(indices!k)) a + + peval b a * (\R+ p (indices ! k) (list_eval s a)) + - peval b a * (ks!(indices!k))))" + using unfold_sum_rsub by auto + + also have "... = (\ks. n = length ks \ + (\kR- p (indices ! k) (\ka. list_eval s a ka && peval (z ! (indices ! k)) a) + \ peval (r!(indices!k)) a + = peval b a * peval (r!(indices!k)) a + + peval b a * (\R+ p (indices ! k) (list_eval s a)) + - peval b a * + (\R- p (indices ! k) (\ka. list_eval s a ka && peval (z ! (indices ! k)) a))))" + by smt + + also have "... = (\kR+ p (indices ! k) (list_eval s a)) + - peval b a * + (\R- p (indices ! k) (\ka. list_eval s a ka && peval (z ! (indices ! k)) a)))" + unfolding indices_def apply auto + apply (rule exI[of _ + "map (\k. \R- p k (\ka. list_eval s a ka && peval (z ! k) a)) [0..l>0. l < n \ + peval (r!l) a + = peval b a * peval (r!l) a + + peval b a * (\R+ p l (list_eval s a)) + - peval b a * + (\R- p l (\ka. list_eval s a ka && peval (z ! l) a)))" + using indices_unfold[of "\x. peval (r ! x) a = + peval b a * peval (r ! x) a + peval b a * (\R+ p x (list_eval s a)) - + peval b a * (\R- p x (\ka. (list_eval s a ka) && peval (z ! x) a))"] + by auto + + also have "... = (\l>0. l < n \ + peval (r!l) a = + peval b a * map (\P. peval P a) r ! l + + peval b a * (\R+ p l ((!) (map (\P. peval P a) s))) + - peval b a * (\R- p l (\k. map (\P. peval P a) s ! k && map (\P. peval P a) z ! l)))" + using nth_map[of _ r "(\P. peval P a)"] unfolding \length r = n\ + using alternative_sum_rsub list_eval_def by auto + + also have "... = (eval DR a)" + apply (simp add: DR_def defs) using rm_eq_fixes_def rm_eq_fixes.register_l_def + local.register_machine_axioms + using nth_map[of _ r "\P. peval P a"] unfolding \length r = n\ by auto + + finally show "eval DS a = eval DR a" by auto + qed + + moreover have "is_dioph_rel DS" + proof - + have "list_all (is_dioph_rel \ param_l_is_sum_rsub_of_bitand) indices" + unfolding param_l_is_sum_rsub_of_bitand_def indices_def list_all_def by (auto simp:dioph) + hence "is_dioph_rel params_are_sum_rsub_of_bitand" + unfolding params_are_sum_rsub_of_bitand_def by (auto simp: dioph) + + have "list_all (is_dioph_rel \ single_register) indices" + unfolding single_register_def list_all_def indices_def by (auto simp: dioph) + thus ?thesis + unfolding DS_def using \is_dioph_rel params_are_sum_rsub_of_bitand\ by (auto simp: dioph) + qed + + ultimately show ?thesis + by (auto simp: is_dioph_rel_def) +qed + +lemma register_bound_dioph: + fixes b q :: polynomial + fixes r :: "polynomial list" + assumes "length r = n" + defines "DR \ LARY (\ll. rm_eq_fixes.register_bound n (ll!0!0) (ll!0!1) (nth (ll!1))) + [[b, q], r]" + shows "is_dioph_rel DR" +proof - + + define indices where "indices \ [0..x. push_param x ?N) r" + + define bound where + "bound \ \l. (r'!l [<] (Param l) [\] [Param l = b' ^ q'])" + + define DS where "DS \ [\n] [\ in indices] bound" + + have "eval DS a = eval DR a" for a + proof - + + have r'_unfold: "peval (r' ! k) (push_list a ks) = peval (r ! k) a" + if "length ks = n" and "k < length ks" for k ks + unfolding pushed_def \length indices = n\ + using push_push_map_i[of ks n k r] that \length r = n\ list_eval_def by auto + + have b'_unfold: "peval b' (push_list a ks) = peval b a" + and q'_unfold: "peval q' (push_list a ks) = peval q a" + if "length ks = n" and "k < length ks" for k ks + unfolding pushed_def \length indices = n\ + using push_push_simp that \length r = n\ list_eval_def by auto + + have "eval DS a = (\ks. n = length ks \ + (\k + push_list a ks k = peval b' (push_list a ks) ^ peval q' (push_list a ks)))" + unfolding DS_def indices_def bound_def by (simp add: defs) + + also have "... = (\ks. n = length ks \ + (\k + push_list a ks k = peval b a ^ peval q a))" + using r'_unfold b'_unfold q'_unfold by (metis (full_types)) + + also have "... = (\kk. peval b a ^ peval q a) [0..lP. peval P a) r ! l < peval b a ^ peval q a)" + using nth_map[of _ r "\P. peval P a"] \length r = n\ by force + + finally show ?thesis unfolding DR_def + using rm_eq_fixes.register_bound_def rm_eq_fixes_def register_machine_def + p_nonempty n_gt_0 valid_program by (auto simp add: defs) + + qed + + moreover have "is_dioph_rel DS" + proof - + have "list_all (is_dioph_rel \ bound) indices" + unfolding bound_def indices_def list_all_def by (auto simp:dioph) + thus ?thesis unfolding DS_def indices_def bound_def by (auto simp: dioph) + qed + + ultimately show ?thesis + by (auto simp: is_dioph_rel_def) +qed + + + +definition register_equations_relation :: "polynomial \ polynomial \ polynomial + \ polynomial list \ polynomial list \ polynomial list \ relation" ("[REG] _ _ _ _ _ _") where + "[REG] a b q r z s \ LARY (\ll. rm_eq_fixes.register_equations p n (ll!0!0) (ll!0!1) (ll!0!2) + (nth (ll!1)) (nth (ll!2)) (nth (ll!3))) [[a, b, q], r, z, s]" + +lemma reg_dioph: + fixes A b q r z s + assumes "length r = n" "length z = n" "length s = Suc m" + defines "DR \ [REG] A b q r z s" + shows "is_dioph_rel DR" +proof - + + define DS where "DS \ (LARY (\ll. rm_eq_fixes.register_0 p (ll!0!0) (ll!0!1) + (nth (ll!1)) (nth (ll!2)) (nth (ll!3))) [[A, b], r, z, s]) + [\] (LARY (\ll. rm_eq_fixes.register_l p n (ll!0!0) + (nth (ll!1)) (nth (ll!2)) (nth (ll!3))) [[b], r, z, s]) + [\] (LARY (\ll. rm_eq_fixes.register_bound n (ll!0!0) (ll!0!1) (nth (ll!1))) + [[b, q], r])" + + have "eval DS a = eval DR a" for a + unfolding DS_def DR_def register_equations_relation_def rm_eq_fixes.register_equations_def + apply (simp add: defs) + by (simp add: register_machine_axioms rm_eq_fixes.intro rm_eq_fixes.register_equations_def) + + moreover have "is_dioph_rel DS" + unfolding DS_def using assms register_0_dioph[of r z s] register_l_dioph[of r z s] + register_bound_dioph by (auto simp: dioph) + + ultimately show ?thesis by (auto simp: is_dioph_rel_def) +qed + +end + +end \ No newline at end of file diff --git a/thys/DPRM_Theorem/Machine_Equations/State_0_Equation.thy b/thys/DPRM_Theorem/Machine_Equations/State_0_Equation.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Machine_Equations/State_0_Equation.thy @@ -0,0 +1,313 @@ +subsubsection \State 0 equation\ + +theory State_0_Equation imports "../Register_Machine/MultipleStepState" + RM_Sums_Diophantine "../Diophantine/Binary_And" + +begin + +context rm_eq_fixes +begin + + text \Equation 4.24\ + definition state_0 :: "bool" where + "state_0 \ s 0 = 1 + b*\S+ p 0 s + b*\S- p 0 (\k. s k && z (modifies (p!k))) + + b*\S0 p 0 (\k. s k && (e - z (modifies (p!k))))" + +end + +context register_machine +begin + +no_notation ppolynomial.Sum (infixl "\<^bold>+" 65) +no_notation ppolynomial.NatDiff (infixl "\<^bold>-" 65) +no_notation ppolynomial.Prod (infixl "\<^bold>*" 70) + + +lemma state_0_dioph: + fixes b e :: polynomial + fixes z s :: "polynomial list" + assumes "length z = n" "length s = Suc m" + defines "DR \ LARY (\ll. rm_eq_fixes.state_0 p (ll!0!0) (ll!0!1) + (nth (ll!1)) (nth (ll!2))) [[b, e], z, s]" + shows "is_dioph_rel DR" +proof - + let ?N = "2" + define b' e' z' s' where pushed_def: "b' = push_param b ?N" + "e' = push_param e ?N" + "z' = map (\x. push_param x ?N) z" + "s' = map (\x. push_param x ?N) s" + + define z0 z1 where z_def: "z0 \ map (\i. z' ! modifies (p!i)) [0.. map (\i. e' [-] z' ! modifies (p!i)) [0.. [Param 0 = \S- 0 (s' && z0)]" + + define param_1_is_sum_sub_zero_term where + "param_1_is_sum_sub_zero_term \ [Param 1 = \S0 0 (s' && z1)]" + + define step_relation where + "step_relation \ (s'!0 [=] \<^bold>1 [+] b' [*] ([\S+] p 0 (nth s')) + [+] b' [*] Param 0 [+] b' [*] Param 1)" + + define DS where "DS \ [\?N] step_relation + [\] param_0_is_sum_sub_nzero_term + [\] param_1_is_sum_sub_zero_term" + + have "p \ []" using p_nonempty by auto + have ps_lengths: "length p = length s" + using \length s = Suc m\ m_def \p \ []\ by auto + have s_len: "length s > 0" + using ps_lengths \p \ []\ by auto + have p_len: "length p > 0" + using ps_lengths s_len by auto + have p_len2: "length p = Suc m" + using ps_lengths \length s = Suc m\ by auto + have len_s': "length s' = Suc m" + unfolding pushed_def using \length s = Suc m\ by auto + have "length z0 = Suc m" + unfolding z_def ps_lengths \length s = Suc m\ by simp + have "length z1 = Suc m" + unfolding z_def ps_lengths \length s = Suc m\ by simp + + have modifies_le_n: "k < length p \ modifies (p!k) < n" for k + using modifies_yields_valid_register \length z = n\ by auto + + have "eval DS a = eval DR a" for a + proof - + + have b'_unfold: "peval b' (push_list a ks) = peval b a" if "length ks = 2" for ks + using push_push_simp unfolding pushed_def using that by metis + + have s'_0_unfold: "peval (s' ! 0) (push_list a ks) = peval (s ! 0) a" if "length ks = 2" for ks + unfolding pushed_def using push_push_map_i[of ks 2 0 s a] that unfolding list_eval_def + \length s > 0\ using s_len by auto + + have sum_nzero_unfold: + "eval [polynomial.Param 0 = \S- 0 (s' && z0)] (push_list a ks) + = (peval (polynomial.Param 0) (push_list a ks) + = \S- p 0 (\k. peval (s' ! k) (push_list a ks) && peval (z0 ! k) (push_list a ks)))" for ks + using sum_rsub_nzero_of_bit_and_eval[of s' z0 "Param 0" 0 "push_list a ks"] + \length p > 0\ \length s' = Suc m\ \length z0 = Suc m\ by auto + + have sum_zero_unfold: + "eval [polynomial.Param 1 = \S0 0 (s' && z1)] (push_list a ks) + = (peval (polynomial.Param 1) (push_list a ks) + = \S0 p 0 (\k. peval (s' ! k) (push_list a ks) && peval (z1 ! k) (push_list a ks)))" for ks + using sum_rsub_zero_of_bit_and_eval[of s' z1 "Param 1" 0 "push_list a ks"] + \length p > 0\ \length s' = Suc m\ \length z1 = Suc m\ by auto + + have param_0_unfold: "peval (Param 0) (push_list a ks) = ks ! 0" if "length ks = 2" for ks + unfolding push_list_def using that by auto + + have param_1_unfold: "peval (Param 1) (push_list a ks) = ks ! 1" if "length ks = 2" for ks + unfolding push_list_def using that by auto + + have sum_sadd_unfold: + "peval ([\S+] p 0 ((!) s')) (push_list a ks) = \S+ p 0 (\x. peval (s ! x) a)" + if "length ks = 2" for ks + using sum_sadd_polynomial_eval \length p > 0\ apply auto + apply (rule sum_sadd_cong, auto) + unfolding pushed_def using push_push_map_i[of ks 2 _ s a] that + unfolding \length p = length s\ list_eval_def + by (smt One_nat_def assms le_imp_less_Suc m_def nth_map p_len2) + + have z0_unfold: + "peval (s' ! k) (push_list a ks) && peval (z0 ! k) (push_list a ks) + = peval (s ! k) a && peval (z ! modifies (p ! k)) a" + if "length ks = 2" and "k < length p" for k ks + proof - + have map: "map (\i. z' ! modifies (p ! i)) [0..i. z' ! modifies (p ! i)"] + using \k < length p\ by auto + + have s: "peval (map (\x. push_param x 2) s ! k) (push_list a ks) = peval (s ! k) a" + using push_push_map_i[of ks 2 k s] that nth_map[of k s] + unfolding \length s = Suc m\ \length p = Suc m\ list_eval_def by auto + + have z: "peval (map (\x. push_param x 2) z ! modifies (p ! k)) (push_list a ks) + = peval (z ! modifies (p ! k)) a" + using push_push_map_i[of ks 2 "modifies (p!k)" z a] modifies_le_n[of k] that nth_map[of _ z] + unfolding \length z = n\ list_eval_def by auto + + show ?thesis + unfolding z_def map unfolding pushed_def s z by auto + qed + + have z1_unfold: + "peval (s' ! k) (push_list a ks) && peval (z1 ! k) (push_list a ks) + = peval (s ! k) a && (peval e a - peval (z ! modifies (p ! k)) a)" + if "length ks = 2" and "k < length p" for k ks + proof - + have map: + "map (\i. e' [-] (z' ! (modifies (p ! i)))) [0..i. z' ! modifies (p ! i)"] + using \k < length p\ by auto + + have s: "peval (map (\x. push_param x 2) s ! k) (push_list a ks) = peval (s ! k) a" + using push_push_map_i[of ks 2 k s] that nth_map[of k s] + unfolding \length s = Suc m\ \length p = Suc m\ list_eval_def by auto + + have z: "peval (push_param e 2) (push_list a ks) + - peval (map (\x. push_param x 2) z ! modifies (p ! k)) (push_list a ks) + = peval e a - peval (z ! (modifies (p!k))) a" + using push_push_simp[of e ks a] unfolding \length ks = 2\ apply simp + using push_push_map_i[of ks 2 "modifies (p!k)" z a] modifies_le_n[of k] that + nth_map[of "modifies (p!k)" z "(\x. peval x a)"] + unfolding \length z = n\ list_eval_def by auto + + show ?thesis + unfolding z_def map unfolding pushed_def s using z by auto + qed + + have z0sum_unfold: + "(\S- p 0 (\k. peval (s' ! k) (push_list a ks) && peval (z0 ! k) (push_list a ks))) + =(\S- p 0 (\k. peval (s ! k) a && peval (z ! modifies (p ! k)) a))" + if "length ks = 2" for ks + apply (rule sum_ssub_nzero_cong) using z0_unfold[of ks] that + by (metis \length s = Suc m\ le_imp_less_Suc m_def ps_lengths) + + have z1sum_unfold: + "(\S0 p 0 (\k. peval (s' ! k) (push_list a ks) && peval (z1 ! k) (push_list a ks))) + =(\S0 p 0 (\k. peval (s ! k) a && peval e a - peval (z ! modifies (p ! k)) a))" + if "length ks = 2" for ks + apply (rule sum_ssub_zero_cong) using z1_unfold[of ks] that + by (metis \length s = Suc m\ le_imp_less_Suc m_def ps_lengths) + + have sum_sadd_map: "\S+ p 0 ((!) (map (\P. peval P a) s)) = \S+ p 0 (\x. peval (s ! x) a)" + apply (rule sum_sadd_cong, auto) + using nth_map[of _ s "(\P. peval P a)"] m_def \length s = Suc m\ by auto + + have sum_ssub_nzero_map: + "(\S- p 0 (\k. peval (s ! k) a && peval (z ! modifies (p ! k)) a)) + = (\S- p 0 (\k. map (\P. peval P a) s ! k && map (\P. peval P a) z ! modifies (p ! k)))" + proof - + have 1: "peval (s ! k) a && peval (z ! modifies (p ! k)) a = + map (\P. peval P a) s ! k && map (\P. peval P a) z ! modifies (p ! k) " + if "k < length p" for k + proof - + have "peval (s ! k) a = map (\P. peval P a) s ! k" + using nth_map that ps_lengths by auto + moreover have "peval (z ! modifies (p ! k)) a + = map (\P. peval P a) z ! modifies (p ! k) " + using nth_map[of "modifies (p!k)" z "(\P. peval P a)"] modifies_le_n[of k] that + using \length z = n\ by auto + ultimately show ?thesis by auto + qed + show ?thesis apply (rule sum_ssub_nzero_cong, auto) + using 1 by (metis Suc_le_mono Suc_pred less_eq_Suc_le p_len) + qed + + have sum_ssub_zero_map: + "(\S0 p 0 (\k. peval (s ! k) a && peval e a - peval (z ! modifies (p ! k)) a)) + = (\S0 p 0 (\k. map (\P. peval P a) s ! k && peval e a + - map (\P. peval P a) z ! modifies (p ! k)))" + proof - + have 1: "peval (s ! k) a && peval e a - peval (z ! modifies (p ! k)) a = + map (\P. peval P a) s ! k && peval e a - map (\P. peval P a) z ! modifies (p ! k) " + if "k < length p" for k + proof - + have "peval (s ! k) a = map (\P. peval P a) s ! k" + using nth_map that ps_lengths by auto + moreover have "peval (z ! modifies (p ! k)) a + = map (\P. peval P a) z ! modifies (p ! k) " + using nth_map[of "modifies (p!k)" z "(\P. peval P a)"] modifies_le_n[of k] that + using \length z = n\ by auto + ultimately show ?thesis by auto + qed + show ?thesis apply (rule sum_ssub_zero_cong, auto) + using 1 by (metis Suc_le_mono Suc_pred less_eq_Suc_le p_len) + qed + + + have "eval DS a = + (\ks. length ks = 2 \ + eval (s' ! 0 [=] \<^bold>1 [+] b' [*] ([\S+] p 0 (!) s') [+] b' [*] Param 0 + [+] b' [*] Param (Suc 0)) (push_list a ks) + \ eval [polynomial.Param 0 = \S- 0 (s' && z0)] (push_list a ks) + \ eval [polynomial.Param 1 = \S0 0 (s' && z1)] (push_list a ks))" + unfolding DS_def step_relation_def param_0_is_sum_sub_nzero_term_def + param_1_is_sum_sub_zero_term_def by (simp add: defs) + + also have "... = (\ks. length ks = 2 \ + peval (s' ! 0) (push_list a ks) = + Suc (peval b' (push_list a ks) * peval ([\S+] p 0 ((!) s')) (push_list a ks) + + peval b' (push_list a ks) * push_list a ks 0 + + peval b' (push_list a ks) * push_list a ks (Suc 0)) + \ (peval (Param 0) (push_list a ks) + = \S- p 0 (\k. peval (s' ! k) (push_list a ks) && peval (z0 ! k) (push_list a ks))) + \ (peval (Param 1) (push_list a ks) + = \S0 p 0 (\k. peval (s' ! k) (push_list a ks) && peval (z1 ! k) (push_list a ks))))" + unfolding sum_nzero_unfold sum_zero_unfold by (simp add: defs ) + + also have "... = (\ks. length ks = 2 \ + peval (s ! 0) a = + Suc (peval b a * peval ([\S+] p 0 ((!) s')) (push_list a ks) + + peval b a * push_list a ks 0 + + peval b a * push_list a ks (Suc 0)) + \ (ks!0 + = \S- p 0 (\k. peval (s' ! k) (push_list a ks) && peval (z0 ! k) (push_list a ks))) + \ (ks!1 + = \S0 p 0 (\k. peval (s' ! k) (push_list a ks) && peval (z1 ! k) (push_list a ks))))" + using b'_unfold s'_0_unfold param_0_unfold param_1_unfold by auto + + also have "... = (\ks. length ks = 2 \ + peval (s ! 0) a = + Suc (peval b a * \S+ p 0 (\x. peval (s ! x) a) + + peval b a * (ks!0) + peval b a * (ks!1)) + \ (ks!0 = \S- p 0 (\k. peval (s' ! k) (push_list a ks) && peval (z0 ! k) (push_list a ks))) + \ (ks!1 = \S0 p 0 (\k. peval (s' ! k) (push_list a ks) && peval (z1 ! k) (push_list a ks))))" + using push_list_def sum_sadd_unfold by auto + + also have "... = (\ks. length ks = 2 \ + peval (s ! 0) a = Suc (peval b a * \S+ p 0 (\x. peval (s ! x) a) + + peval b a * (ks!0) + peval b a * (ks!1)) + \ (ks!0 = \S- p 0 (\k. peval (s ! k) a && peval (z ! modifies (p ! k)) a)) + \ (ks!1 = \S0 p 0 (\k. peval (s ! k) a && peval e a - peval (z ! modifies (p ! k)) a)))" + using z0sum_unfold z1sum_unfold by auto + + also have "... = (\ks. length ks = 2 \ + peval (s ! 0) a + = Suc (peval b a * \S+ p 0 (\x. peval (s ! x) a) + + peval b a * \S- p 0 (\k. peval (s ! k) a && peval (z ! modifies (p ! k)) a) + + peval b a * \S0 p 0 (\k. peval (s ! k) a && peval e a - peval (z ! modifies (p ! k)) a)) + \ (ks!0 = \S- p 0 (\k. peval (s ! k) a && peval (z ! modifies (p ! k)) a)) + \ (ks!1 = \S0 p 0 (\k. peval (s ! k) a && peval e a - peval (z ! modifies (p ! k)) a)))" + by auto + + also have "... = (peval (s ! 0) a + = Suc (peval b a * \S+ p 0 (\x. peval (s ! x) a) + + peval b a * \S- p 0 (\k. peval (s ! k) a && peval (z ! modifies (p ! k)) a) + + peval b a * \S0 p 0 (\k. peval (s ! k) a && peval e a - peval (z ! modifies (p ! k)) a)))" + apply auto + apply (rule exI[of _ "[(\S- p 0 (\k. peval (s ! k) a && peval (z ! modifies (p ! k)) a)), + \S0 p 0 (\k. peval (s ! k) a && peval e a - peval (z ! modifies (p ! k)) a) ]"]) + by auto + + also have "... = (map (\P. peval P a) s ! 0 = + Suc (peval b a * \S+ p 0 ((!) (map (\P. peval P a) s)) + + peval b a * \S- p 0 (\k. map (\P. peval P a) s ! k + && map (\P. peval P a) z ! modifies (p ! k)) + + peval b a * + \S0 p 0 (\k. map (\P. peval P a) s ! k && peval e a + - map (\P. peval P a) z ! modifies (p ! k)) ))" + using nth_map[of _ _ "(\P. peval P a)"] \length s > 0\ + using sum_ssub_zero_map sum_sadd_map sum_ssub_nzero_map by auto + + finally show ?thesis unfolding DR_def using rm_eq_fixes_def local.register_machine_axioms + rm_eq_fixes.state_0_def by (simp add: defs) + qed + + moreover have "is_dioph_rel DS" + unfolding DS_def param_1_is_sum_sub_zero_term_def param_0_is_sum_sub_nzero_term_def + step_relation_def by (auto simp add: dioph) + + ultimately show ?thesis + by (simp add: is_dioph_rel_def) +qed + +end + +end \ No newline at end of file diff --git a/thys/DPRM_Theorem/Machine_Equations/State_Unique_Equations.thy b/thys/DPRM_Theorem/Machine_Equations/State_Unique_Equations.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Machine_Equations/State_Unique_Equations.thy @@ -0,0 +1,156 @@ +subsubsection \State unique equations\ + +theory State_Unique_Equations imports "../Register_Machine/MultipleStepState" + Equation_Setup "../Diophantine/Register_Machine_Sums" + "../Diophantine/Binary_And" + +begin + +context rm_eq_fixes +begin + + text \Equations not in the book: \ + definition state_mask :: "bool" where + "state_mask \ \k\m. s k \ e" + + definition state_bound :: "bool" where + "state_bound \ \k— s m,t = 1 at t = q and nowhere else*) + + definition state_unique_equations :: "bool" where + "state_unique_equations \ state_mask \ state_bound" + +end + +context register_machine +begin + +lemma state_mask_dioph: + fixes e :: polynomial + fixes s :: "polynomial list" + assumes "length s = Suc m" + defines "DR \ LARY (\ll. rm_eq_fixes.state_mask p (ll!0!0) (nth (ll!1))) [[e], s]" + shows "is_dioph_rel DR" +proof - + define mask where "mask \ (\l. (s!l [\] e))" + define DS where "DS \ [\k\m. peval (s ! k) a \ peval e a)" + unfolding DS_def mask_def by (simp add: less_Suc_eq_le defs) + + also have "... = (\k\m. map (\P. peval P a) s ! k \ peval e a)" + using nth_map[of _ s "(\P. peval P a)"] \length s = Suc m\ by auto + + finally show ?thesis + unfolding DR_def using rm_eq_fixes_def local.register_machine_axioms + rm_eq_fixes.state_mask_def by (simp add: defs) + qed + + moreover have "is_dioph_rel DS" + proof - + have "list_all (is_dioph_rel \ mask) [0.. LARY (\ll. rm_eq_fixes.state_bound p (ll!0!0) (ll!0!1) (nth (ll!1))) [[b, q], s]" + shows "is_dioph_rel DR" +proof - + let ?N = "m" + define b' q' s' where pushed_def: "b' = push_param b ?N" + "q' = push_param q ?N" + "s' = map (\x. push_param x ?N) s" + + define bound where + "bound \ \l. s'!l [<] (Param l) [\] [Param l = b' ^ q']" + + define DS where "DS \ [\m] [\length s = Suc m\ list_eval_def + by (metis less_SucI nth_map push_push) + + have b'_unfold: "peval b' (push_list a ks) = peval b a" + and q'_unfold: "peval q' (push_list a ks) = peval q a" + if "length ks = m" and "k < length ks" for k ks + unfolding pushed_def + using push_push_simp that \length s = Suc m\ list_eval_def by metis+ + + have "eval DS a = (\ks. m = length ks \ + (\k + push_list a ks k = peval b' (push_list a ks) ^ peval q' (push_list a ks)))" + unfolding DS_def bound_def by (simp add: defs) + + also have "... = (\ks. m = length ks \ + (\k + push_list a ks k = peval b a ^ peval q a))" + using s'_unfold b'_unfold q'_unfold by metis + + also have "... = (\kk. peval b a ^ peval q a) [0..lP. peval P a) s ! l < peval b a ^ peval q a)" + using nth_map[of _ s "\P. peval P a"] \length s = Suc m\ by force + + finally show ?thesis unfolding DR_def + using rm_eq_fixes_def local.register_machine_axioms rm_eq_fixes.state_bound_def + by (simp add: defs) + + qed + + moreover have "is_dioph_rel DS" + proof - + have "list_all (is_dioph_rel \ bound) [0.. LARY + (\ll. rm_eq_fixes.state_unique_equations p (ll!0!0) (ll!0!1) (ll!0!2) (nth (ll!1))) + [[b, e, q], s]" + shows "is_dioph_rel DR" +proof - + + define DS where "DS \ LARY (\ll. rm_eq_fixes.state_mask p (ll!0!0) (nth (ll!1))) [[e], s] + [\] LARY (\ll. rm_eq_fixes.state_bound p (ll!0!0) (ll!0!1) (nth (ll!1))) + [[b, q], s]" + + have "eval DS a = eval DR a" for a + unfolding DR_def DS_def using rm_eq_fixes.state_unique_equations_def rm_eq_fixes_def + local.register_machine_axioms + by (auto simp: defs) + + moreover have "is_dioph_rel DS" + unfolding DS_def using state_bound_dioph state_mask_dioph assms dioph by auto + + ultimately show ?thesis using is_dioph_rel_def by auto +qed + +end + +end \ No newline at end of file diff --git a/thys/DPRM_Theorem/Machine_Equations/State_d_Equation.thy b/thys/DPRM_Theorem/Machine_Equations/State_d_Equation.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Machine_Equations/State_d_Equation.thy @@ -0,0 +1,433 @@ +subsubsection \State d equation\ + +theory State_d_Equation imports State_0_Equation + +begin + +context rm_eq_fixes +begin + + text \Equation 4.25\ + definition state_d :: "bool" where + "state_d \ \d>0. d\m \ s d = b*\S+ p d s + b*\S- p d (\k. s k && z (modifies (p!k))) + + b*\S0 p d (\k. s k && (e - z (modifies (p!k))))" + + text \Combining the two\ + definition state_relations_from_recursion :: "bool" where + "state_relations_from_recursion \ state_0 \ state_d" + +end + +context register_machine +begin + +lemma state_d_dioph: + fixes b e :: polynomial + fixes z s :: "polynomial list" + assumes "length z = n" "length s = Suc m" + defines "DR \ LARY (\ll. rm_eq_fixes.state_d p (ll!0!0) (ll!0!1) + (nth (ll!1)) (nth (ll!2))) + [[b, e], z, s]" + shows "is_dioph_rel DR" +proof - + + define d_domain where "d_domain \ [1..x. push_param x number_of_ex_vars) z" + "s' = map (\x. push_param x number_of_ex_vars) s" + + note e'_def = \e' = push_param e number_of_ex_vars\ + + define z0 z1 where z_def: "z0 \ map (\i. z' ! modifies (p!i)) [0.. map (\i. e' [-] z' ! modifies (p!i)) [0.. (\d. Param (d - Suc 0))" + write sum_ssub_nzero_param_of_state ("\S-'_Param _") + + define sum_ssub_zero_param_of_state where + "sum_ssub_zero_param_of_state \ (\d. Param (m + d - Suc 0))" + write sum_ssub_zero_param_of_state ("\S0'_Param _") + + define param_is_sum_ssub_nzero_term where + "param_is_sum_ssub_nzero_term \ (\d::nat. [(\S-_Param d) = \S- d (s' && z0)])" + + define param_is_sum_ssub_zero_term where + "param_is_sum_ssub_zero_term \ (\d. [(\S0_Param d) = \S0 d (s' && z1)])" + + define params_are_sum_terms where + "params_are_sum_terms \ [\ in d_domain] (\d. param_is_sum_ssub_nzero_term d + [\] param_is_sum_ssub_zero_term d)" + + define step_relation where + "step_relation \ (\d. (s'!d) [=] b' [*] ([\S+] p d (nth s')) + [+] b' [*] (\S-_Param d) + [+] b' [*] (\S0_Param d))" + + define DS where "DS \ [\number_of_ex_vars] (([\ in d_domain] (\d. step_relation d)) + [\] params_are_sum_terms)" + + have "length p > 0" + using p_nonempty by auto + hence "m \ 0" + unfolding m_def by auto + have "length s' = Suc m" and "length z0 = Suc m" and "length z1 = Suc m" + unfolding pushed_def z_def using \length s = Suc m\ m_def \length p > 0\ by auto + + have "eval DS a = eval DR a" for a + proof - + + have b'_unfold: "peval b' (push_list a ks) = peval b a" + if "length ks = number_of_ex_vars" for ks + unfolding pushed_def using push_push_simp \length d_domain = m\ by (metis that) + + have h0: "k < m \ d_domain ! k < Suc m" for k + unfolding d_domain_def apply simp + using One_nat_def Suc_pred \0 < length p\ add.commute + assms(3) d_domain_def less_diff_conv m_def nth_upt upt_Suc_append + by (smt \length d_domain = m\ less_nat_zero_code list.size(3) upt_Suc) + + have s'_unfold: "peval (s' ! (d_domain ! k)) (push_list a ks) + = peval (s ! (d_domain ! k)) a" + if "length ks = number_of_ex_vars" and "k < m" for k ks + proof - + from \k < m\ have "d_domain ! k < length s" unfolding \length s = Suc m\ + using h0 by blast + + have suc_k: "([Suc 0..k < m\) + + have "peval (map (\x. push_param x number_of_ex_vars) s ! (d_domain ! k)) (push_list a ks) + = list_eval s a (d_domain ! k)" + using push_push_map_i[of "ks" "number_of_ex_vars" "d_domain!k" s a] + using \length ks = number_of_ex_vars\ \k < m\ h0 \length s = Suc m\ by auto + also have "... = peval (s ! (d_domain ! k)) a" + unfolding list_eval_def + using nth_map [of "d_domain ! k" s "(\x. peval x a)"] \d_domain ! k < length s\ + unfolding d_domain_def using \m \ 0\ \k < m\ suc_k by auto + + finally show ?thesis unfolding pushed_def by auto + qed + + have sum_sadd_unfold: "(\S+ p (d_domain ! k) (\x. peval (s' ! x) (push_list a ks))) + = (\S+ p (d_domain ! k) ((!) (map (\P. peval P a) s)))" + if "length ks = number_of_ex_vars" for k ks + apply (rule sum_sadd_cong, auto) unfolding pushed_def + using push_push_map_i[of ks number_of_ex_vars _ s a] \length ks = number_of_ex_vars\ + unfolding list_eval_def by (simp add: \length s = Suc m\ m_def) + + have s: "peval (s' ! ka) (push_list a ks) = map (\P. peval P a) s ! ka" + if "ka < Suc m" and "length ks = number_of_ex_vars" for ka ks + unfolding pushed_def + using push_push_map_i[of ks number_of_ex_vars ka s a] \length ks = number_of_ex_vars\ + using list_eval_def \length s = Suc m\ \ka < Suc m\ by auto + + have modifies_valid: "modifies (p ! ka) < length z" if "ka < Suc m" for ka + using modifies_yields_valid_register that unfolding \length z = n\ m_def + using p_nonempty by auto + + have sum_ssub_nzero_unfold: + "(\S- p (d_domain ! k) (\k. peval (s' ! k) (push_list a ks) + && peval (z0 ! k) (push_list a ks))) + = (\S- p (d_domain ! k) (\k. map (\P. peval P a) s ! k + && map (\P. peval P a) z ! modifies (p ! k)))" + if "length ks = number_of_ex_vars" for k ks + proof- + have z0: "peval (z0 ! ka) (push_list a ks) = map (\P. peval P a) z ! modifies (p ! ka)" + if "ka < Suc m" for ka + unfolding z_def pushed_def + using push_push_map_i[of ks number_of_ex_vars "modifies (p!ka)" z a] + \length ks = number_of_ex_vars\ unfolding list_eval_def + using \length z0 = Suc m\ \ka < Suc m\ modifies_valid \0 < length p\ m_def map_nth by force + + show ?thesis apply (rule sum_ssub_nzero_cong) using s z0 le_imp_less_Suc m_def that + by presburger + qed + + have sum_ssub_zero_unfold: + "(\S0 p (d_domain ! k) (\k. peval (s' ! k) (push_list a ks) + && peval (z1 ! k) (push_list a ks))) + = (\S0 p (d_domain ! k) (\k. map (\P. peval P a) s ! k + && peval e a - map (\P. peval P a) z ! modifies (p ! k)))" + if "length ks = number_of_ex_vars" and "k < Suc m" for k ks + proof- + + have map: + "map (\i. e' [-] (z' ! (modifies (p ! i)))) [0..i. e' [-] z' ! modifies (p ! i)"] \ka < Suc m\ + by (smt (z3) One_nat_def Suc_pred \0 < length p\ \m \ 0\ le_trans length_map m_def map_nth + nth_map upt_Suc_append zero_le_one) + + have "peval (e' [-] (z' ! modifies (p ! ka))) (push_list a ks) + = peval e a - map (\P. peval P a) z ! modifies (p ! ka)" + if "ka < Suc m" for ka + unfolding z_def pushed_def apply (simp add: defs) + using push_push_simp \length ks = number_of_ex_vars\ apply auto + using push_push_map_i[of ks number_of_ex_vars "modifies (p!ka)" z a] + \length ks = number_of_ex_vars\ modifies_valid \ka < Suc m\ + unfolding list_eval_def using \length z0 = Suc m\ \0 < length p\ m_def map_nth by auto + + hence z1: "peval (z1 ! ka) (push_list a ks) + = peval e a - map (\P. peval P a) z ! modifies (p ! ka)" if "ka < Suc m" for ka + unfolding z_def using map that by auto + + show ?thesis apply (rule sum_ssub_zero_cong) using s z1 le_imp_less_Suc m_def that + by presburger + + qed + + define sum_ssub_nzero_map where + "sum_ssub_nzero_map \ \j. \S- p j (\k. map (\P. peval P a) s ! k + && map (\P. peval P a) z ! modifies (p ! k))" + define sum_ssub_zero_map where + "sum_ssub_zero_map \ \j. \S0 p j (\k. map (\P. peval P a) s ! k + && peval e a - map (\P. peval P a) z ! modifies (p ! k)) " + + define ks_ex where + "ks_ex \ map sum_ssub_nzero_map d_domain @ map sum_ssub_zero_map d_domain" + + have "length ks_ex = number_of_ex_vars" + unfolding ks_ex_def number_of_ex_vars_def using \length d_domain = m\ by auto + + have ks_ex1: + "peval (\S-_Param (d_domain ! k)) (push_list a ks_ex) + = \S- p (d_domain ! k) (\k. map (\P. peval P a) s ! k + && map (\P. peval P a) z ! modifies (p ! k))" + if "k < m" for k + proof - + have domain_at_k_bound: + "d_domain ! k - Suc 0 < length ks_ex" using that \length ks_ex = number_of_ex_vars\ + unfolding number_of_ex_vars_def using h0 by fastforce + + have "peval (\S-_Param (d_domain ! k)) (push_list a ks_ex) = ks_ex ! k" + unfolding push_list_def sum_ssub_nzero_param_of_state_def using that domain_at_k_bound + apply auto + using One_nat_def Suc_mono d_domain_def diff_Suc_1 nth_upt plus_1_eq_Suc by presburger + + also have "... = \S- p (d_domain ! k) (\k. map (\P. peval P a) s ! k + && map (\P. peval P a) z ! modifies (p ! k))" + unfolding ks_ex_def + unfolding nth_append[of "map sum_ssub_nzero_map d_domain" "map sum_ssub_zero_map d_domain" k] + using \length d_domain = m\ that unfolding sum_ssub_nzero_map_def by auto + finally show ?thesis by auto + qed + + have ks_ex2: + "peval (\S0_Param (d_domain ! k)) (push_list a ks_ex) + = \S0 p (d_domain ! k) (\k. map (\P. peval P a) s ! k + && peval e a - map (\P. peval P a) z ! modifies (p ! k))" + if "k < m" for k + proof - + have domain_at_k_bound: + "m + d_domain ! k - Suc 0 < length ks_ex" using that \length ks_ex = number_of_ex_vars\ + unfolding number_of_ex_vars_def using h0 by fastforce + + have "d_domain ! k \ 1" + unfolding d_domain_def \k < m\ + using m_def p_nonempty that by auto + + hence index_calculation: "(m + d_domain ! k - Suc 0) = k + m" + unfolding d_domain_def + by (metis (no_types, lifting) Nat.add_diff_assoc One_nat_def Suc_pred add.commute + less_diff_conv m_def nth_upt ordered_cancel_comm_monoid_diff_class.le_imp_diff_is_add + p_nonempty that) + + have "peval (\S0_Param (d_domain ! k)) (push_list a ks_ex) = ks_ex ! (k + m)" + unfolding push_list_def sum_ssub_zero_param_of_state_def using that domain_at_k_bound + by (auto simp: index_calculation) + + also have "... = \S0 p (d_domain ! k) (\k. map (\P. peval P a) s ! k + && peval e a - map (\P. peval P a) z ! modifies (p ! k))" + unfolding ks_ex_def + unfolding nth_append[of "map sum_ssub_nzero_map d_domain" "map sum_ssub_zero_map d_domain"] + using \length d_domain = m\ that unfolding sum_ssub_zero_map_def by auto + finally show ?thesis by auto + qed + + have all_quantifier_switch: "(\kd>0. d \ m \ Property d)" for Property + proof (rule) + assume asm: "\kd>0. d \ m \ Property d" + proof (auto) + fix d + assume "d > 0" "d \ m" + hence "d - Suc 0 < length d_domain" + by (metis Suc_le_eq Suc_pred \length d_domain = m\) + hence "Property (d_domain ! (d - Suc 0))" + using asm by auto + thus "Property d" + unfolding d_domain_def + by (metis One_nat_def Suc_diff_1 \0 < d\ \d \ m\ le_imp_less_Suc nth_upt plus_1_eq_Suc) + qed + next + assume asm: "\d>0. d \ m \ Property d" + show "\k 0" + unfolding d_domain_def + by (smt (z3) One_nat_def Suc_leI Suc_pred \0 < length p\ \length d_domain = m\ + add_less_cancel_left d_domain_def diff_is_0_eq' gr_zeroI le_add_diff_inverse + less_nat_zero_code less_numeral_extra(1) m_def nth_upt) + moreover have "d_domain ! k \ m" + unfolding d_domain_def using \k < length d_domain\ unfolding \length d_domain = m\ + using d_domain_def h0 less_Suc_eq_le by auto + ultimately show "Property (d_domain ! k)" + using asm by auto + qed + qed + + have "peval (s!d) a = map (\P. peval P a) s ! d" if "d > 0" and "d \ m" for d + using nth_map[of d s "\P. peval P a"] that \length s = Suc m\ by simp + + (* Start chain of equivalences *) + have "eval DS a = (\ks. number_of_ex_vars = length ks + \ (\k eval params_are_sum_terms (push_list a ks))" + unfolding DS_def by (simp add: defs) + + also have "... = (\ks. number_of_ex_vars = length ks \ + (\kS+] p (d_domain ! k) ((!) s')) (push_list a ks) + + peval b a * peval (\S-_Param (d_domain ! k)) (push_list a ks) + + peval b a * peval (\S0_Param (d_domain ! k)) (push_list a ks)) \ + eval params_are_sum_terms (push_list a ks))" + unfolding step_relation_def \length d_domain = m\ + using b'_unfold s'_unfold by (auto simp: defs) + + also have "... = (\ks. number_of_ex_vars = length ks \ + (\kS+ p (d_domain ! k) (\x. peval (s' ! x) (push_list a ks))) + + peval b a * (peval (\S-_Param (d_domain ! k)) (push_list a ks)) + + peval b a * (peval (\S0_Param (d_domain ! k)) (push_list a ks))) + \ (\kS-_Param (d_domain ! k)) (push_list a ks) + = \S- p (d_domain ! k) (\k. peval (s' ! k) (push_list a ks) + && peval (z0 ! k) (push_list a ks)) + \ peval (\S0_Param (d_domain ! k)) (push_list a ks) + = \S0 p (d_domain ! k) (\k. peval (s' ! k) (push_list a ks) + && peval (z1 ! k) (push_list a ks))))" + unfolding params_are_sum_terms_def param_is_sum_ssub_nzero_term_def + param_is_sum_ssub_zero_term_def apply (simp add: defs) + using sum_rsub_nzero_of_bit_and_eval[of s' z0] sum_rsub_zero_of_bit_and_eval[of s' z1] + \length p > 0\ \length s' = Suc m\ \length z0 = Suc m\ \length z1 = Suc m\ + unfolding \length d_domain = m\ by (simp add: defs) + + also have "... = (\ks. number_of_ex_vars = length ks \ + (\kS+ p (d_domain ! k) ((!) (map (\P. peval P a) s)) ) + + peval b a * (\S- p (d_domain ! k) (\k. map (\P. peval P a) s ! k + && map (\P. peval P a) z ! modifies (p ! k))) + + peval b a * (\S0 p (d_domain ! k) (\k. map (\P. peval P a) s ! k + && peval e a - map (\P. peval P a) z ! modifies (p ! k)))) + \ (\kS-_Param (d_domain ! k)) (push_list a ks) + = \S- p (d_domain ! k) (\k. map (\P. peval P a) s ! k + && map (\P. peval P a) z ! modifies (p ! k)) + \ peval (\S0_Param (d_domain ! k)) (push_list a ks) + = \S0 p (d_domain ! k) (\k. map (\P. peval P a) s ! k + && peval e a - map (\P. peval P a) z ! modifies (p ! k))))" + using sum_sadd_unfold sum_ssub_nzero_unfold sum_ssub_zero_unfold by auto + + also have "... = (\kS+ p (d_domain ! k) ((!) (map (\P. peval P a) s)) ) + + peval b a * (\S- p (d_domain ! k) + (\k. map (\P. peval P a) s ! k + && map (\P. peval P a) z ! modifies (p ! k))) + + peval b a * (\S0 p (d_domain ! k) + (\k. map (\P. peval P a) s ! k + && peval e a - map (\P. peval P a) z ! modifies (p ! k))))" + apply auto + apply (rule exI[of _ ks_ex]) + using \length ks_ex = number_of_ex_vars\ ks_ex1 ks_ex2 by auto + + also have "... = (\d>0. d \ m \ + peval (s ! d) a + = peval b a * \S+ p d ((!) (map (\P. peval P a) s)) + + peval b a * \S- p d (\k. map (\P. peval P a) s ! k + && map (\P. peval P a) z ! modifies (p ! k)) + + peval b a * \S0 p d (\k. map (\P. peval P a) s ! k + && peval e a - map (\P. peval P a) z ! modifies (p ! k)) )" + using all_quantifier_switch[of "\d. peval (s ! d) a = + peval b a * \S+ p d ((!) (map (\P. peval P a) s)) + + peval b a * \S- p d (\k. map (\P. peval P a) s ! k + && map (\P. peval P a) z ! modifies (p ! k)) + + peval b a * \S0 p d (\k. map (\P. peval P a) s ! k + && peval e a - map (\P. peval P a) z ! modifies (p ! k))"] + unfolding \length d_domain = m\ by auto + + finally show ?thesis + unfolding DR_def + using local.register_machine_axioms rm_eq_fixes_def[of p n] rm_eq_fixes.state_d_def[of p n] + apply (simp add: defs) + using nth_map[of _ s "\P. peval P a"] \length s = Suc m\ + by auto + qed + + moreover have "is_dioph_rel DS" + proof - + have "is_dioph_rel (param_is_sum_ssub_nzero_term d [\] param_is_sum_ssub_zero_term d)" for d + unfolding param_is_sum_ssub_nzero_term_def param_is_sum_ssub_zero_term_def + by (auto simp: dioph) + hence 1: "list_all (is_dioph_rel \ (\d. param_is_sum_ssub_nzero_term d + [\] param_is_sum_ssub_zero_term d)) d_domain" + by (simp add: list.inducts) + + have "is_dioph_rel (step_relation d)" for d + unfolding step_relation_def by (auto simp: dioph) + hence 2: "list_all (is_dioph_rel \ step_relation) d_domain" + by (simp add: list.inducts) + + show ?thesis + unfolding DS_def params_are_sum_terms_def by (auto simp: dioph 1 2) + qed + + ultimately show ?thesis using is_dioph_rel_def by auto +qed + + +lemma state_relations_from_recursion_dioph: + fixes b e :: polynomial + fixes z s :: "polynomial list" + assumes "length z = n" "length s = Suc m" + defines "DR \ LARY (\ll. rm_eq_fixes.state_relations_from_recursion p (ll!0!0) (ll!0!1) + (nth (ll!1)) (nth (ll!2))) + [[b, e], z, s]" + shows "is_dioph_rel DR" +proof - + + define DS where "DS \ (LARY (\ll. rm_eq_fixes.state_0 p (ll!0!0) (ll!0!1) + (nth (ll!1)) (nth (ll!2))) [[b, e], z, s]) + [\](LARY (\ll. rm_eq_fixes.state_d p (ll!0!0) (ll!0!1) (nth (ll!1)) + (nth (ll!2))) [[b, e], z, s])" + + have "eval DS a = eval DR a" for a + unfolding DS_def DR_def + using local.register_machine_axioms rm_eq_fixes_def + rm_eq_fixes.state_relations_from_recursion_def + using assms by (simp add: defs) + + moreover have "is_dioph_rel DS" + unfolding DS_def apply (rule and_dioph) using assms state_0_dioph state_d_dioph by blast+ + + ultimately show ?thesis using is_dioph_rel_def by auto +qed + +end + +end diff --git a/thys/DPRM_Theorem/ROOT b/thys/DPRM_Theorem/ROOT new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/ROOT @@ -0,0 +1,69 @@ +chapter AFP + +session DPRM_Theorem (AFP) = HOL + + description \The DPRM Theorem\ + options [timeout = 600] + + sessions + "HOL-Library" + "Lucas_Theorem" + "Digit_Expansions" + + directories + "Diophantine" + "Register_Machine" + "Machine_Equations" + + theories + (* Diophantine Equations *) + "Diophantine/Parametric_Polynomials" + "Diophantine/Assignments" + "Diophantine/Diophantine_Relations" + "Diophantine/Existential_Quantifier" + "Diophantine/Modulo_Divisibility" + + (* Exponentiation is Diophantine *) + "Diophantine/Exponentiation" + "Diophantine/Alpha_Sequence" + "Diophantine/Exponential_Relation" + + (* Diophantization of Digitwise Operations *) + "Diophantine/Digit_Function" + "Diophantine/Binomial_Coefficient" + "Diophantine/Binary_Masking" + "Diophantine/Binary_Orthogonal" + "Diophantine/Binary_And" + + (* Register Machines *) + "Register_Machine/RegisterMachineSpecification" + "Register_Machine/RegisterMachineProperties" + "Register_Machine/RegisterMachineSimulation" + "Register_Machine/SingleStepRegister" + "Register_Machine/SingleStepState" + "Register_Machine/MultipleStepRegister" + "Register_Machine/MultipleStepState" + "Register_Machine/MachineMasking" + + (* Arithmetization of Register Machines *) + "Register_Machine/MachineEquations" + "Register_Machine/CommutationRelations" + "Register_Machine/MultipleToSingleSteps" + "Machine_Equations/Equation_Setup" + "Machine_Equations/RM_Sums_Diophantine" + "Diophantine/Register_Machine_Sums" + "Machine_Equations/Register_Equations" + "Machine_Equations/State_0_Equation" + "Machine_Equations/State_d_Equation" + "Machine_Equations/All_State_Equations" + "Machine_Equations/Mask_Equations" + "Machine_Equations/Constants_Equations" + "Machine_Equations/All_Equations_Invariance" + "Machine_Equations/All_Equations" + "Machine_Equations/Machine_Equation_Equivalence" + + (* The DPRM Theorem *) + DPRM + + document_files + "root.tex" + "root.bib" diff --git a/thys/DPRM_Theorem/Register_Machine/CommutationRelations.thy b/thys/DPRM_Theorem/Register_Machine/CommutationRelations.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Register_Machine/CommutationRelations.thy @@ -0,0 +1,682 @@ +subsection \Preliminary commutation relations\ + +theory CommutationRelations + imports RegisterMachineSimulation MachineEquations +begin + +lemma aux_commute_bitAND_sum: + fixes N C :: nat + and fxt :: "nat \ nat" + shows "\i\N. \j\N. i \ j \ (\k. (fct i) \ k * (fct j) \ k = 0) + \ (\k \ N. fct k && C) = (\k \ N. fct k) && C" +proof (induct N) + case 0 + then show ?case by auto +next + case (Suc N) + assume Suc_assms: "\i\Suc N. \j\Suc N. i \ j \ (\k. fct i \ k * fct j \ k = 0)" + + have "(\k\Suc N. fct k && C) = (\k\N. fct k && C) + (fct (Suc N) && C)" + by (auto cong: sum.cong) + also have "... = (sum fct {..N} && C) + (fct (Suc N) && C)" + using Suc by auto + also have "... = (sum fct {..N} + fct (Suc N)) && C" + proof - + let ?a = "sum fct {..N} && C" + let ?b = "fct (Suc N) && C" + + have formula: "\d. ( ?a + ?b ) \ d = ( ?a \ d + ?b \ d + bin_carry ?a ?b d ) mod 2" + using sum_digit_formula by auto + + + (* mutual proof of both statements, they are interdependent in the inductive step *) + have nocarry4: "\n\Suc N. \d. (sum fct {..n} \ d > 0 \ (\i\n. (fct i) \ d > 0)) + \ bin_carry (sum fct {.. Suc N \ + \d. ((\i\n. (fct i) \ d = 0) + \ sum fct {..n} \ d = 0) \ bin_carry (sum fct {..d. sum fct {.. d > 0 \ (\i d = 1)" + using nth_bit_def + by (metis One_nat_def Suc_less_eq lessThan_Suc_atMost less_Suc_eq nat_less_le + not_mod2_eq_Suc_0_eq_0) + + (* then show another helper result ... *) + have h1: "\d. sum fct {.. d + fct (Suc m) \ d \ 1" + proof - + { + fix d + have "sum fct {.. d + fct (Suc m) \ d \ 1" + proof (cases "sum fct {.. d = 0") + case True + have "fct (Suc m) \ d \ 1" + using nth_bit_def by auto + then show ?thesis using True by auto + next + case False + then have "\i d > 0" + using ex by (metis neq0_conv zero_less_one) + then obtain i where i: "i fct i \ d > 0" by auto + hence "i \ Suc N" using Suc.prems by auto + hence "\j\Suc N. i \ j \ (\k. fct i \ k * fct j \ k = 0)" + using Suc_assms by auto + then have "fct (Suc m) \ d = 0" + using Suc.prems i nat_neq_iff + by (auto) (blast) + moreover from False have "sum fct {.. d = 1" + by (simp add: nth_bit_def) + ultimately show ?thesis by auto + qed + } + thus ?thesis by auto + qed + + (* ... in order to show the inductive step of the second statement *) + from h1 have h2: "\d. bin_carry (sum fct {..d. bin_carry (sum fct {..m}) (fct (Suc m)) d = 0" + by (simp add: lessThan_Suc_atMost) + + (* finally use the just proven inductive step for the 2nd statement to show the + inductive step for the first statement *) + { + fix d + assume a: "\i\Suc m. (fct i) \ d = 0" + have "sum fct {..Suc m} \ d = (sum fct {..m} + fct (Suc m)) \ d" + by auto + also have "... = + (sum fct {..m} \ d + fct (Suc m) \ d + bin_carry (sum fct {..m}) (fct (Suc m)) d) mod 2" + using sum_digit_formula[of "sum fct {..m}" "fct (Suc m)" "d"] by auto + finally have "sum fct {..Suc m} \ d = 0" + using nocarry3 Suc a by auto + } + with h2 show ?case by auto + qed + + then have "n \ Suc N \ \d. (sum fct {..n} \ d > 0 \ (\i\n. (fct i) \ d > 0)) + \ bin_carry (sum fct {..d. ?a \ d + ?b \ d \ 1" + proof - + have "\d. ?a \ d + ?b \ d = (sum fct {..N} \ d + fct (Suc N) \ d) * C \ d" + using bitAND_digit_mult add_mult_distrib by auto + then have "\d. ?a \ d + ?b \ d \ (sum fct {..N} \ d + fct (Suc N) \ d)" + using nth_bit_def by auto + thus ?thesis + using sum_carry_formula nocarry4 no_carry_mult_equiv nth_bit_bounded bitAND_digit_mult + by (metis One_nat_def add.commute add_decreasing le_Suc_eq lessThan_Suc_atMost + nat_1_eq_mult_iff) + qed + from h3 have h4: "\d. bin_carry ?a ?b d = 0" + by (metis Suc_1 Suc_n_not_le_n carry_digit_impl) + + (* Helper for proof chain below *) + have h5: "\d. bin_carry (sum fct {..N}) (fct (Suc N)) d = 0" + using nocarry4 lessThan_Suc_atMost by auto + + from formula h3 h4 have "\d. ( ?a + ?b ) \ d = ?a \ d + ?b \ d" + by (metis (no_types, lifting) add_cancel_right_left add_le_same_cancel1 add_self_mod_2 + le_zero_eq not_mod2_eq_Suc_0_eq_0 nth_bit_def one_mod_two_eq_one plus_1_eq_Suc) + + then have "\d. ( ?a + ?b ) \ d = sum fct {..N} \ d * C \ d + fct (Suc N) \ d * C \ d" + using bitAND_digit_mult by auto + + then have "\d. ( ?a + ?b ) \ d = (sum fct {..N} \ d + fct (Suc N) \ d) * C \ d" + by (simp add: add_mult_distrib) + moreover have "\d. sum fct {..N} \ d + fct (Suc N) \ d + = ( sum fct {..N} \ d + fct (Suc N) \ d + bin_carry (sum fct {..N}) (fct (Suc N)) d ) mod 2" + using h5 sum_carry_formula + by (metis add_diff_cancel_left' add_diff_cancel_right' mult_div_mod_eq mult_is_0) + ultimately have "\d. ( ?a + ?b ) \ d = (sum fct {..N} + fct (Suc N)) \ d * C \ d" + using sum_digit_formula by auto + + then have "\d. ( ?a + ?b ) \ d = ( (sum fct {..N} + fct (Suc N)) && C ) \ d" + using bitAND_digit_mult by auto + thus ?thesis using digit_wise_equiv by blast + qed + ultimately show ?case by auto +qed + + +lemma aux_commute_bitAND_sum_if: + fixes N const :: nat + assumes nocarry: "\i\N. \j\N. i \ j \ (\k. (fct i) \ k * (fct j) \ k = 0)" + shows "(\k \ N. if cond k then fct k && const else 0) + = (\k \ N. if cond k then fct k else 0) && const" +proof - + from nocarry have nocarry_if: + "\i\N. \j\N. i \ j \ (\k. (if cond i then fct i else 0) \ k * (if cond j then fct j else 0) \ k = 0)" + by (metis (full_types) aux1_digit_wise_equiv mult.commute mult_zero_left) + + have "(if cond k then fct k && const else 0) = (if cond k then fct k else 0) && const" for k + by auto + hence "(\k \ N. if cond k then fct k && const else 0) + = (\k \ N. (if cond k then fct k else 0) && const)" + by auto + also have "... = (\k \ N. if cond k then fct k else 0) && const" + using nocarry_if aux_commute_bitAND_sum[where ?fct = "\k. (if cond k then fct k else 0)"] + by blast + ultimately show ?thesis by auto +qed + +lemma mod_mod: + fixes x a b :: nat + shows "x mod 2^a mod 2^b = x mod 2^(min a b)" + by (metis min.commute take_bit_eq_mod take_bit_take_bit) + +lemma carry_gen_pow2_reduct: + assumes "c>0" + defines b: "b \ 2 ^ (Suc c)" + assumes "nth_digit x (t-1) (2^Suc c) \ c = 0" + and "nth_digit y (t-1) (2^Suc c) \ c = 0" + shows "k\c \ bin_carry (nth_digit x t b) (nth_digit y t b) k + = bin_carry x y (Suc c * t + k)" +proof (induction k) + case 0 + then show ?case + proof (cases "t=0") + case True + then show ?thesis using bin_carry_def by auto + next + case False + hence "t>0" by auto + from assms(3) have "x \ (Suc c * (t - 1) + c) = 0" + using digit_gen_pow2_reduct[of "c" "Suc c" "x" "t-1"] by auto + moreover have "y \ (Suc c * (t - 1) + c) = 0" + using assms(4) digit_gen_pow2_reduct[of "c" "Suc c" "y" "t-1"] by auto + moreover have "Suc c * (t - 1) + c = t + c * t - Suc 0" + using add.left_commute gr0_conv_Suc \t>0\ by auto + ultimately have "(x \ (t + c * t - Suc 0) + y \ (t + c * t - Suc 0) + + bin_carry x y (t + c * t - Suc 0)) \ 1" using carry_bounded by auto + hence "bin_carry x y (Suc c * t) = 0" + using sum_carry_formula[of "x" "y" "Suc c * t - 1"] \c>0\ \t>0\ by auto + + moreover have "bin_carry (nth_digit x t b) (nth_digit y t b) 0 = 0" + using 0 bin_carry_def by auto + ultimately show ?thesis by auto + qed +next + case (Suc k) + have "k x \ (Suc c * t + k) = nth_digit x t b \ k" + using digit_gen_pow2_reduct[of "k" "Suc c" "x" "t"] b by auto + moreover have "k y \ (Suc c * t + k) = nth_digit y t b \ k" + using digit_gen_pow2_reduct[of "k" "Suc c" "y" "t"] b by auto + ultimately show ?case using Suc + sum_carry_formula[of "nth_digit x t b" "nth_digit y t b" "k"] + sum_carry_formula[of "x" "y" "Suc c * t + k"] + by auto +qed + +lemma nth_digit_bound: + fixes c defines "b \ 2 ^ (Suc c)" + shows "nth_digit x t b < 2 ^ (Suc c)" + using nth_digit_def b_def by auto + +lemma digit_wise_block_additivity: + fixes c + defines "b \ 2 ^ Suc c" + assumes "nth_digit x (t-1) (2^Suc c) \ c = 0" + and "nth_digit y (t-1) (2^Suc c) \ c = 0" + and "k\c" + and "c>0" + shows "nth_digit (x+y) t b \ k = (nth_digit x t b + nth_digit y t b) \ k" +proof - + have "k < Suc c" using `k\c` by simp + have x: "nth_digit x t b \ k = x \ (Suc c * t + k)" + using digit_gen_pow2_reduct[of "k" "Suc c" "x" "t"] b_def `k k = y \ (Suc c * t + k)" + using digit_gen_pow2_reduct[of "k" "Suc c" "y" "t"] b_def `k k + = ((nth_digit x t b) \ k + (nth_digit y t b) \ k + + bin_carry (nth_digit x t b) (nth_digit y t b) k) mod 2" + using sum_digit_formula[of "nth_digit x t b" "nth_digit y t b" "k"] by auto + also have "... = (x \ (Suc c * t + k) + y \ (Suc c * t + k) + + bin_carry (nth_digit x t b) (nth_digit y t b) k) mod 2" + using x y by auto + also have "... = (x \ (Suc c * t + k) + y \ (Suc c * t + k) + + bin_carry x y (Suc c * t + k)) mod 2" + using carry_gen_pow2_reduct[of "c" "x" "t" "y" "k"] assms by auto + also have "... = (x + y) \ (Suc c * t + k)" + using sum_digit_formula by auto + also have "... = nth_digit (x+y) t b \ k" + using digit_gen_pow2_reduct[of "k" "Suc c" "x+y" "t"] b_def `k 0" + defines "b \ 2 ^ Suc c" + assumes "nth_digit x (t-1) b \ c = 0" + and "nth_digit y (t-1) b \ c = 0" + and "nth_digit x t b \ c = 0" + and "nth_digit y t b \ c = 0" + (* needs stronger assumptions than digit_wise_block_additivity *) + shows "nth_digit (x+y) t b = nth_digit x t b + nth_digit y t b" +proof - + { + have "nth_digit x t b < b" using nth_digit_bound b_def by auto + hence x_digit_bound: "\k. k\Suc c \ nth_digit x t b \ k = 0" + using nth_bit_def b_def aux_lt_implies_mask b_def by metis + + have "nth_digit y t b < b" using nth_digit_bound b_def by auto + hence y_digit_bound: "\k. k\Suc c \ nth_digit y t b \ k = 0" + using nth_bit_def b_def aux_lt_implies_mask b_def by metis + + fix k + assume k: "k\Suc c" + have carry0: "bin_carry (nth_digit x t b) (nth_digit y t b) k = 0" + proof - (* induction proof using rule nat_induct_at_least to accommodate fact k *) + (* base case *) + have base: "bin_carry (nth_digit x t b) (nth_digit y t b) (Suc c) = 0" + using sum_carry_formula[where ?k = "c"] bin_carry_bounded[where ?k = "c"] + using assms(5-6) by (metis Suc_eq_plus1 add_cancel_left_left mod_div_trivial) + + (* inductive step *) + { + fix n + assume n: "n \ Suc c" + assume IH: "bin_carry (nth_digit x t b) (nth_digit y t b) n = 0" + have "bin_carry (nth_digit x t b) (nth_digit y t b) (Suc n) + = (nth_digit x t b \ n + nth_digit y t b \ n + + bin_carry (nth_digit x t b) (nth_digit y t b) n) div 2" + using sum_carry_formula[of "nth_digit x t b" "nth_digit y t b"] by auto + also have "... = bin_carry (nth_digit x t b) (nth_digit y t b) n div 2" + using x_digit_bound y_digit_bound n by auto + also have "... = 0" using IH by auto + + finally have "bin_carry (nth_digit x t b) (nth_digit y t b) (Suc n) = 0" + by auto + } + + then show ?thesis + using k base + using nat_induct_at_least[where ?P = "\k. bin_carry (nth_digit x t b) + (nth_digit y t b) k = 0"] + by auto + qed + + have "(nth_digit x t b + nth_digit y t b) \ k + = (nth_digit x t b \ k + nth_digit y t b \ k + + bin_carry (nth_digit x t b) (nth_digit y t b) k) mod 2" + using sum_digit_formula[of "nth_digit x t b" "nth_digit y t b" "k"] by auto + hence separate_sum: "(nth_digit x t b + nth_digit y t b) \ k = 0" + using x_digit_bound y_digit_bound carry0 k by auto + + have "nth_digit (x+y) t b < b" + using nth_digit_bound b_def by auto + hence xy_sum: "nth_digit (x+y) t b \ k = 0" + using nth_bit_def b_def aux_lt_implies_mask b_def k by metis + from xy_sum separate_sum have k_ge: "nth_digit (x+y) t b \ k + = (nth_digit x t b + nth_digit y t b) \ k" + by auto + } + hence k_ge: "k\Suc c \ nth_digit (x+y) t b \ k + = (nth_digit x t b + nth_digit y t b) \ k" for k + by auto + + moreover have k_lt:"k nth_digit (x+y) t b \ k + = (nth_digit x t b + nth_digit y t b) \ k" for k + using digit_wise_block_additivity assms by auto + + ultimately have "nth_digit (x+y) t b \ k + = (nth_digit x t b + nth_digit y t b) \ k" for k + by(cases "k0" + defines b: "b \ 2 ^ (Suc c)" + assumes yltx_digits: "\t'. nth_digit y t' b \ nth_digit x t' b" + shows "y mod b^t \ x mod b^t" +proof(cases "t=0") + case True + then show ?thesis by auto +next + case False + show ?thesis using yltx_digits apply(induct t, auto) using yltx_digits + by (smt add.commute add_left_cancel add_mono_thms_linordered_semiring(1) mod_mult2_eq + mult_le_cancel2 nth_digit_def semiring_normalization_rules(7)) +qed + +lemma narry_gen_pow2_reduct: + assumes "c>0" + defines b: "b \ 2 ^ (Suc c)" + assumes yltx_digits: "\t'. nth_digit y t' b \ nth_digit x t' b" + shows "k\c \ bin_narry (nth_digit x t b) (nth_digit y t b) k + = bin_narry x y (Suc c * t + k)" +proof (induction k) + case 0 + then show ?case + proof (cases "t=0") + case True + then show ?thesis by (simp add: bin_narry_def) + next + case False + have "bin_narry x y (Suc c * t) = 0" using yltx_digits block_to_sum bin_narry_def assms + by (metis not_less power_mult) + then show ?thesis by (simp add: bin_narry_def) + qed +next + case (Suc k) + have ylex: "y\x" using yltx_digits digitwise_leq b Suc_1 lessI power_gt1 by metis + have "k x \ (Suc c * t + k) = nth_digit x t b \ k" + using digit_gen_pow2_reduct[of "k" "Suc c" "x" "t"] b by auto + moreover have "k y \ (Suc c * t + k) = nth_digit y t b \ k" + using digit_gen_pow2_reduct[of "k" "Suc c" "y" "t"] b by auto + ultimately show ?case using Suc yltx_digits + dif_narry_formula[of "(nth_digit y t b)" "(nth_digit x t b)" k] + dif_narry_formula[of y x "Suc c * t + k"] ylex by auto +qed + +lemma digit_wise_block_subtractivity: + fixes c + defines "b \ 2 ^ Suc c" + assumes yltx_digits: "\t'. nth_digit y t' b \ nth_digit x t' b" + and "k\c" + and "c>0" + shows "nth_digit (x-y) t b \ k = (nth_digit x t b - nth_digit y t b) \ k" +proof - + have x: "nth_digit x t b \ k = x \ (Suc c * t + k)" + using digit_gen_pow2_reduct[of "k" "Suc c" "x" "t"] b_def `k\c` by auto + have y: "nth_digit y t b \ k = y \ (Suc c * t + k)" + using digit_gen_pow2_reduct[of "k" "Suc c" "y" "t"] b_def `k\c` by auto + + have "b > 1" using `c>0` b_def + by (metis Suc_1 lessI power_gt1) + then have yltx: "y \ x" using digitwise_leq yltx_digits by auto + + have "(nth_digit x t b - nth_digit y t b) \ k + = ((nth_digit x t b) \ k + (nth_digit y t b) \ k + + bin_narry (nth_digit x t b) (nth_digit y t b) k) mod 2" + using dif_digit_formula yltx_digits by auto + also have "... = (x \ (Suc c * t + k) + y \ (Suc c * t + k) + + bin_narry (nth_digit x t b) (nth_digit y t b) k) mod 2" + using x y by auto + also have "... = (x \ (Suc c * t + k) + y \ (Suc c * t + k) + + bin_narry x y (Suc c * t + k)) mod 2" + using narry_gen_pow2_reduct using assms(3) assms(4) b_def yltx_digits by auto + also have "... = nth_digit (x-y) t b \ k" + using digit_gen_pow2_reduct[of "k" "Suc c" "x-y" "t"] b_def `k\c` dif_digit_formula yltx + by auto + finally show ?thesis by auto +qed + +lemma block_subtractivity: + assumes "c > 0" + defines "b \ 2 ^ Suc c" + assumes block_wise_lt: "\t'. nth_digit y t' b \ nth_digit x t' b" + shows "nth_digit (x-y) t b = nth_digit x t b - nth_digit y t b" +proof - + have "k\c \ nth_digit (x-y) t b \ k = (x - y) \ (Suc c * t + k)" for k + using digit_gen_pow2_reduct[of "k" "Suc c" "x-y" "t"] b_def by auto + have "k\c \ nth_digit x t b \ k = x \ (Suc c * t + k)" for k + using digit_gen_pow2_reduct[of "k" "Suc c" "x" "t"] b_def by auto + have "k\c \ nth_digit y t b \ k = y \ (Suc c * t + k)" for k + using digit_gen_pow2_reduct[of "k" "Suc c" "y" "t"] b_def by auto + + have k_le: "k \ c \ nth_digit (x-y) t b \ k + = (nth_digit x t b - nth_digit y t b) \ k" for k + using assms digit_wise_block_subtractivity by auto + + have "nth_digit x t b - nth_digit y t b < b" using + nth_digit_bound b_def by (simp add: less_imp_diff_less) + hence diff: "k\Suc c \ (nth_digit x t b - nth_digit y t b) \ k = 0" for k + using nth_bit_def b_def aux_lt_implies_mask b_def by metis + + have "nth_digit (x-y) t b < b" using nth_digit_bound b_def by auto + hence "k\Suc c \ nth_digit (x-y) t b \ k = 0" for k + using nth_bit_def b_def aux_lt_implies_mask b_def by metis + with diff have k_gt: "k > c \ nth_digit (x-y) t b \ k + = (nth_digit x t b - nth_digit y t b) \ k" for k + by auto + from k_le k_gt have "nth_digit (x-y) t b \ k + = (nth_digit x t b - nth_digit y t b) \ k" for k by(cases "k>c"; auto) + thus ?thesis using digit_wise_equiv[of "nth_digit x t b - nth_digit y t b" + "nth_digit (x-y) t b"] by auto +qed + +lemma bitAND_nth_digit_commute: + assumes b_def: "b = 2^(Suc c)" + shows "nth_digit (x && y) t b = nth_digit x t b && nth_digit y t b" +proof - + { + fix k + assume k: "k < Suc c" + have prod: "nth_digit (x && y) t b \ k = (x && y) \ (Suc c * t + k)" + using digit_gen_pow2_reduct[of _ "Suc c" "x && y" "t"] b_def k by auto + moreover have x: "nth_digit x t b \ k = x \ (Suc c * t + k)" + using digit_gen_pow2_reduct[of _ "Suc c" "x"] b_def k by auto + moreover have y: "nth_digit y t b \ k = y \ (Suc c * t + k)" + using digit_gen_pow2_reduct[of _ "Suc c" "y"] b_def k by auto + moreover have "(x && y) \ (Suc c * t + k) = (x \ (Suc c * t + k)) * (y \ (Suc c * t + k))" + using bitAND_digit_mult by auto + + ultimately have "nth_digit (x && y) t b \ k + = nth_digit x t b \ k * nth_digit y t b \ k" + by auto + + also have "... = (nth_digit x t b && nth_digit y t b) \ k" + using bitAND_digit_mult by auto + + finally have "nth_digit (x && y) t b \ k + = (nth_digit x t b && nth_digit y t b) \ k" + by auto + } + + (* now also consider k \ Suc c *) + then have "nth_digit (x && y) t b \ k + = (nth_digit x t b && nth_digit y t b) \ k" for k + by (metis aux_lt_implies_mask b_def bitAND_digit_mult leI mult_eq_0_iff nth_digit_bound) + + then show ?thesis using b_def digit_wise_equiv[of "nth_digit (x && y) t b"] by auto +qed + +lemma bx_aux: + shows "b>1 \ nth_digit (b^x) t' b = (if x=t' then 1 else 0)" + by (cases "t' > x", auto simp: nth_digit_def) + (metis dvd_imp_mod_0 dvd_power leI less_SucI nat_neq_iff power_diff zero_less_diff) + + +context + fixes c b :: nat + assumes b_def: "b \ 2^(Suc c)" + assumes c_gt0: "c>0" +begin + +lemma b_gt1: "b>1" using c_gt0 b_def + using one_less_numeral_iff one_less_power semiring_norm(76) by blast + +text \Commutation relations with sums\ + +(* Commute outside, need assumption for nth_digit inside sum *) + +lemma finite_sum_nth_digit_commute: + fixes M :: nat + shows "\t. \k\M. nth_digit (fct k) t b < 2^c \ + \t. (\i=0..M. nth_digit (fct i) t b) < 2^c \ + nth_digit (\i=0..M. fct i) t b = (\i=0..M. (nth_digit (fct i) t b))" +proof (induct M arbitrary: t) + case 0 thus ?case by auto +next + case (Suc M) + + have assm1: "\t. \k\Suc M. nth_digit (fct k) t b < 2^c" + using Suc.prems by auto + have assm1_reduced: "\t. \k\M. nth_digit (fct k) t b < 2^c" + using assm1 by auto + have nocarry2: "\t. \k\Suc M. nth_digit (fct k) t b \ c = 0" + using assm1 nth_bit_def by auto + + have assm2: + "\t. nth_digit (fct (Suc M)) t b + (\i=0..M. nth_digit (fct i) t b) < 2^c" + using Suc.prems by (simp add: add.commute) + hence assm2_reduced: "\t. (\i=0..M. nth_digit (fct i) t b) < 2^c" + using Suc.prems(2) add_lessD1 by fastforce + + have IH: "\t. nth_digit (\i=0..M. fct i) t b + = (\i=0..M. nth_digit (fct i) t b)" + using assm1_reduced assm2_reduced Suc.hyps by blast + then have assm2_IH_commuted: "\t. nth_digit (\i=0..M. fct i) t b < 2^c" + using assm2_reduced by auto + hence nocarry3: "\t. nth_digit (\i=0..M. fct i) t b \ c = 0" + using aux_lt_implies_mask by blast + + have 1: "nth_digit (sum fct {0..M}) (t - 1) b \ c = 0" using nocarry3 by auto + have 2: "nth_digit (fct (Suc M)) (t - 1) b \ c = 0" using nocarry2 by auto + have 3: "nth_digit (sum fct {0..M}) t b \ c = 0" using nocarry3 by auto + have 4: "nth_digit (fct (Suc M)) t b \ c = 0" using nocarry2 by auto + from block_additivity show ?case using 1 2 3 4 c_gt0 Suc b_def + using IH by auto +qed + +lemma sum_nth_digit_commute_aux: + fixes g + defines SX_def: "SX \ \l m (fct :: nat \ nat). (\k = 0..m. if g l k then fct k else 0)" + assumes nocarry: "\t. \k\M. nth_digit (fct k) t b < 2^c" + and nocarry_sum: "\t. (SX l M (\k. nth_digit (fct k) t b)) < 2^c" + shows "nth_digit (SX l M fct) t b = SX l M (\k. nth_digit (fct k) t b)" +proof - + have aux: "nth_digit (if g l i then fct i else 0) t b + = (if g l i then nth_digit (fct i) t b else 0)" for i t + using aux1_digit_wise_gen_equiv b_gt1 by auto + + from nocarry have "\t. \k\M. nth_digit (if g l k then fct k else 0) t b < 2^c" + using aux by auto + + moreover from nocarry_sum have + "\t. (\i = 0..M. nth_digit (if g l i then fct i else 0) t b) < 2 ^ c" + unfolding SX_def by (auto simp: aux) + + ultimately have "nth_digit (\k = 0..M. if g l k then fct k else 0) t b + = (\k = 0..M. nth_digit (if g l k then fct k else 0) t b)" + using finite_sum_nth_digit_commute[where ?fct = "\k. if g l k then fct k else 0"] + by (simp add: SX_def) + moreover have "\k. nth_digit (if g l k then fct k else 0) t b + = (if g l k then nth_digit (fct k) t b else 0)" + by (auto simp: nth_digit_def) + ultimately show ?thesis by (auto simp: SX_def) +qed + +lemma sum_nth_digit_commute: + fixes g + defines SX_def: "SX \ \p l (fct :: nat \ nat). (\k = 0..length p - 1. if g l k then fct k else 0)" + assumes nocarry: "\t. \k\length p - 1. nth_digit (fct k) t b < 2^c" + and nocarry_sum: "\t. (SX p l (\k. nth_digit (fct k) t b)) < 2^c" + shows "nth_digit (SX p l fct) t b = SX p l (\k. nth_digit (fct k) t b)" +proof - + let ?m = "length p - 1" + + have "\t. (\k = 0..?m. if g l k then nth_digit (fct k) t b else 0) < 2^c" + using nocarry_sum unfolding SX_def by blast + + then have "nth_digit (\k = 0..length p - 1. if g l k then fct k else 0) t b + = (\k = 0..length p - 1. if g l k then nth_digit (fct k) t b else 0)" + using nocarry + using sum_nth_digit_commute_aux[where ?M = "length p - 1"] + by auto + + then show ?thesis using SX_def by auto +qed + +text \Commute inside, need assumption for all partial sums\ +lemma finite_sum_nth_digit_commute2: + fixes M :: nat + shows "\t. \k\M. nth_digit (fct k) t b < 2^c \ + \t. \m\M. nth_digit (\i=0..m. fct i) t b < 2^c \ + nth_digit (\i=0..M. fct i) t b = (\i=0..M. (nth_digit (fct i) t b))" +proof (induct M arbitrary: t) + case 0 thus ?case by auto +next + case (Suc M) + + have assm1: "\t. \k\Suc M. nth_digit (fct k) t b < 2^c" + using Suc.prems by auto + have assm1_reduced: "\t. \k\M. nth_digit (fct k) t b < 2^c" + using assm1 by auto + have nocarry2: "\t. \k\Suc M. nth_digit (fct k) t b \ c = 0" + using assm1 nth_bit_def by auto + + have assm2: + "\t. nth_digit (\i=0..M. (fct i)) t b < 2^c" + using Suc.prems by (simp add: add.commute) + hence nocarry3: "\t. nth_digit (\i=0..M. fct i) t b \ c = 0" + using aux_lt_implies_mask by blast + + have 1: "nth_digit (sum fct {0..M}) (t - 1) b \ c = 0" using nocarry3 by auto + have 2: "nth_digit (fct (Suc M)) (t - 1) b \ c = 0" using nocarry2 by auto + have 3: "nth_digit (sum fct {0..M}) t b \ c = 0" using nocarry3 by auto + have 4: "nth_digit (fct (Suc M)) t b \ c = 0" using nocarry2 by auto + from block_additivity show ?case using 1 2 3 4 c_gt0 Suc b_def by auto +qed + +lemma sum_nth_digit_commute_aux2: + fixes g + defines SX_def: "SX \ \l m (fct :: nat \ nat). (\k = 0..m. if g l k then fct k else 0)" + assumes nocarry: "\t. \k\M. nth_digit (fct k) t b < 2^c" + and nocarry_sum: "\t. \m\M. nth_digit (SX l m fct) t b < 2^c" + shows "nth_digit (SX l M fct) t b = SX l M (\k. nth_digit (fct k) t b)" +proof - + have aux: "nth_digit (if g l i then fct i else 0) t b + = (if g l i then nth_digit (fct i) t b else 0)" for i t + using aux1_digit_wise_gen_equiv b_gt1 by auto + + from nocarry have "\t. \k\M. nth_digit (if g l k then fct k else 0) t b < 2^c" + using aux by auto + + moreover from nocarry_sum have + "\t. \m\M. nth_digit (\i = 0..m. (if g l i then fct i else 0)) t b < 2 ^ c" + unfolding SX_def by (auto simp: aux) + + ultimately have "nth_digit (\k = 0..M. if g l k then fct k else 0) t b + = (\k = 0..M. nth_digit (if g l k then fct k else 0) t b)" + using finite_sum_nth_digit_commute2[where ?fct = "\k. if g l k then fct k else 0"] + by (simp add: SX_def) + moreover have "\k. nth_digit (if g l k then fct k else 0) t b + = (if g l k then nth_digit (fct k) t b else 0)" + by (auto simp: nth_digit_def) + ultimately show ?thesis by (auto simp: SX_def) +qed + +lemma sum_nth_digit_commute2: + fixes g p + defines SX_def: "SX \ \p l (fct :: nat \ nat). (\k = 0..length p - 1. if g l k then fct k else 0)" + assumes nocarry: "\t. \k\length p - 1. nth_digit (fct k) t b < 2^c" + and nocarry_sum: "\t. \m\length p - 1. nth_digit (SX (take (Suc m) p) l fct) t b < 2^c" + shows "nth_digit (SX p l fct) t b = SX p l (\k. nth_digit (fct k) t b)" +proof - + have "\m \ length p - 1. (SX (take (Suc m) p) l fct) = (\k = 0..m. if g l k then fct k else 0)" + unfolding SX_def + by (auto) (metis (no_types, lifting) One_nat_def diff_Suc_1 min_absorb2 min_diff) + hence "\t m. m \ length p - 1 \ + nth_digit (\k = 0..m. if g l k then fct k else 0) t b < 2 ^ c" + using nocarry_sum by auto + + then have "nth_digit (\k = 0..length p - 1. if g l k then fct k else 0) t b + = (\k = 0..length p - 1. if g l k then nth_digit (fct k) t b else 0)" + using nocarry + using sum_nth_digit_commute_aux2[where ?M = "length p - 1" and ?fct = "fct" and ?g = g] + by blast + + then show ?thesis using SX_def by auto +qed + +end + +end \ No newline at end of file diff --git a/thys/DPRM_Theorem/Register_Machine/MachineEquations.thy b/thys/DPRM_Theorem/Register_Machine/MachineEquations.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Register_Machine/MachineEquations.thy @@ -0,0 +1,62 @@ +section \Arithmetization of Register Machines\ + +subsection \A first definition of the arithmetizing equations\ + +theory MachineEquations + imports MultipleStepRegister MultipleStepState MachineMasking +begin + +definition mask_equations :: "nat \ (register \ nat) \ (register \ nat) + \ nat \ nat \ nat \ nat \ bool" (* 4.15, 4.17 and 4.20 *) + where "(mask_equations n r z c d e f) = ((\l d) + \ (\l e) + \ (\l (register \ nat) \ (register \ nat) \ (state \ nat) + \ nat \ nat \ nat \ nat \ bool" where + "(reg_equations p r z s b a n q) = ( + \ \4.22\ (\l>0. l < n \ r l = b*r l + b*\R+ p l (\k. s k) - b*\R- p l (\k. s k && z l)) + \ \ \4.23\ ( r 0 = a + b*r 0 + b*\R+ p 0 (\k. s k) - b*\R- p 0 (\k. s k && z 0)) + \ (\l \Extra equation not in Matiyasevich's book. + Needed to show that all registers are empty at time q\" + +(* STATE EQUATIONS -- todo from here on *) +definition state_equations :: "program \ (state \ nat) \ (register \ nat) \ + nat \ nat \ nat \ nat \ bool" where + "state_equations p s z b e q m = ( +\ \4.24\ (\d>0. d\m \ s d = b*\S+ p d (\k. s k) + b*\S- p d (\k. s k && z (modifies (p!k))) + + b*\S0 p d (\k. s k && (e - z (modifies (p!k))))) + \ \ \4.25\ ( s 0 = 1 + b*\S+ p 0 (\k. s k) + b*\S- p 0 (\k. s k && z (modifies (p!k))) + + b*\S0 p 0 (\k. s k && (e - z (modifies (p!k))))) + \ \ \4.27\ (s m = b^q) + \ (\k\m. s k \ e) \ (\k \these equations are not from the book\ + \ (\M\m. (\k\M. s k) \ e) \ \this equation is added, too\ )" + +(* The following two equations do not appear in Matiyasevich's book, this duplicated definition + (note that they are also included just above) is, for now, only a reminder. *) +definition state_unique_equations :: "program \ (state\nat) \ nat \ nat \bool" where + "state_unique_equations p s m e = ((\k=0..m. s k) \ e \ (\k\m. s k \ e))" + + +(* RM CONSTANTS FOR DEFINITION AND CLARIFY OF EQUATIONS *) +definition rm_constants :: "nat \ nat \ nat \ nat \ nat \ nat \ nat \ bool" where + "rm_constants q c b d e f a = ( + \ \4.14\ (b = B c) + \ \ \4.16\ (d = D q c b) + \ \ \4.18\ (e = E q b) \ \4.19 left out (compare book)\ + \ \ \4.21\ (f = F q c b) + \ \ \extra equation not in the book\ c > 0 + \ \ \4.26\ (a < 2^c) \ (q>0))" + +definition rm_equations_old :: "program \ nat \ nat \ nat \ bool" where + "rm_equations_old p q a n = ( + \ b c d e f :: nat. + \ r z :: register \ nat. + \ s :: state \ nat. + mask_equations n r z c d e f + \ reg_equations p r z s b a n q + \ state_equations p s z b e q (length p - 1) + \ rm_constants q c b d e f a)" + +end diff --git a/thys/DPRM_Theorem/Register_Machine/MachineMasking.thy b/thys/DPRM_Theorem/Register_Machine/MachineMasking.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Register_Machine/MachineMasking.thy @@ -0,0 +1,659 @@ +subsection \Masking properties\ + +theory MachineMasking + imports RegisterMachineSimulation "../Diophantine/Binary_And" +begin + +(* [D] 4.18 *) +definition E :: "nat \ nat \ nat" where + "(E q b) = (\t = 0..q. b^t)" + +lemma e_geom_series: + assumes "b \ 2" + shows "(E q b = e) \ ((b-1) * e = b^(Suc q) - 1 )" (is "?P \ ?Q") +proof- + have "sum ((^) (int b)) {.. nat \ nat \ nat" where + "(D q c b) = (\t = 0..q. (2^c - 1) * b^t)" + +lemma d_geom_series: + assumes "b = 2^(Suc c)" + shows "(D q c b = d) \ ((b-1) * d = (2^c - 1) * (b^(Suc q) - 1))" (is "?P \ ?Q") +proof- + have "D q c b = (2^c - 1) * E q b" by (auto simp: E_def D_def sum_distrib_left sum_distrib_right) + moreover have "b \ 2" using assms by fastforce + ultimately show ?thesis by (smt e_geom_series mult.left_commute mult_cancel_left) +qed + +(* [D] 4.21 *) +definition F :: "nat \ nat \ nat \ nat" where + "(F q c b) = (\t = 0..q. 2^c * b^t)" + +lemma f_geom_series: + assumes "b = 2^(Suc c)" + shows "(F q c b = f) \ ( (b-1) * f = 2^c * (b^(Suc q) - 1) )" +proof- + have "F q c b = 2^c * E q b" by (auto simp: E_def F_def sum_distrib_left sum_distrib_right) + moreover have "b \ 2" using assms by fastforce + ultimately show ?thesis by (smt e_geom_series mult.left_commute mult_cancel_left) +qed + +(* AUX LEMMAS *) +lemma aux_lt_implies_mask: + assumes "a < 2^k" + shows "\r\k. a \ r = 0" + using nth_bit_def assms apply auto +proof - (* found by e *) + fix r :: nat + assume a1: "a < 2 ^ k" + assume a2: "k \ r" + have "a div 2 ^ k = 0" + using a1 Euclidean_Division.div_eq_0_iff by blast + then have "2 = (0::nat) \ a < 2 ^ r" + using a2 by (metis (no_types) div_le_mono nat_zero_less_power_iff neq0_conv not_le power_diff) + then show "a div 2 ^ r mod 2 = 0" + by simp +qed + +lemma lt_implies_mask: + fixes a b :: nat + assumes "\k. a < 2^k \ (\r b" +proof - + obtain k where assms: "a < 2^k \ (\rr r \ b \ r" using nth_bit_bounded + by (simp add: \a < 2 ^ k \ (\r r = 1)\) + hence k2: "\r\k. a \ r = 0" using aux_lt_implies_mask assms by auto + show ?thesis using masks_leq_equiv + by auto (metis k1 k2 le0 not_less) +qed + +lemma mask_conversed_shift: + fixes a b k :: nat + assumes asm: "a \ b" + shows "a * 2^k \ b * 2^k" +proof - + have shift: "x \ y \ 2*x \ 2*y" for x y by (induction x; auto) + have "a * 2 ^ k \ b * 2 ^ k \ 2 * (a * 2 ^ k) \ 2 * (b * 2 ^ k)" for k + using shift[of "a*2^k" "b*2^k"] by auto + thus ?thesis by (induction k; auto simp: asm shift algebra_simps) +qed + +lemma base_summation_bound: + fixes c q :: nat + and f :: "(nat \ nat)" + +defines b: "b \ B c" +assumes bound: "\t. f t < 2 ^ Suc c - (1::nat)" + +shows "(\t = 0..q. f t * b^t) < b^(Suc q)" +proof (induction q) + case 0 + then show ?case using B_def b bound less_imp_diff_less not_less_eq + by auto blast +next + case (Suc q) + have "(\t = 0..Suc q. f t * b ^ t) = f (Suc q) * b ^ (Suc q) + (\t = 0..q. f t * b ^ t)" + by (auto cong: sum.cong) + also have "... < (f (Suc q) + 1) * b ^ (Suc q)" + using Suc.IH by auto + also have "... < b * b ^ (Suc q)" + by (metis bound b less_diff_conv B_def mult_less_cancel2 zero_less_numeral zero_less_power) + finally show ?case by auto +qed + +lemma mask_conserved_sum: + fixes y c q :: nat + and x :: "(nat \ nat)" + +defines b: "b \ B c" +assumes mask: "\t. x t \ y" +assumes xlt: "\t. x t \ 2 ^ c - Suc 0" +assumes ylt: "y \ 2 ^ c - Suc 0" + +shows "(\t = 0..q. x t * b^t) \ (\t = 0..q. y * b^t)" +proof (induction q) + case 0 + then show ?case + using mask by auto +next + case (Suc q) + + have xb: "\t. x t < 2^Suc c - Suc 0" + using xlt + by (smt Suc_pred leI le_imp_less_Suc less_SucE less_trans n_less_m_mult_n numeral_2_eq_2 + power.simps(2) zero_less_numeral zero_less_power) + have yb: "y < 2^c" + using ylt b B_def leI order_trans by fastforce + + have sumxlt: "(\t = 0..q. x t * b ^ t) < b^(Suc q)" + using base_summation_bound xb b B_def by auto + have sumylt: "(\t = 0..q. y * b ^ t) < b^(Suc q)" + using base_summation_bound yb b B_def by auto + + have "((\t = 0..Suc q. x t * b ^ t) \ (\t = 0..Suc q. y * b ^ t)) + = (x (Suc q) * b^Suc q + (\t = 0..q. x t * b ^ t) \ + y * b^Suc q + (\t = 0..q. y * b ^ t))" + by (auto simp: atLeast0_lessThan_Suc add.commute) + also have "... = (x (Suc q) * b^Suc q \ y * b^Suc q) + \ (\t = 0..q. x t * b ^ t) \ (\t = 0..q. y * b ^ t)" + using mask_linear[where ?t = "Suc c * Suc q"] sumxlt sumylt Suc.IH b B_def + apply auto + apply (smt mask mask_conversed_shift power_Suc power_mult power_mult_distrib) + by (smt mask mask_linear power_Suc power_mult power_mult_distrib) + finally show ?case using mask_linear Suc.IH B_def + by (metis (no_types, lifting) b mask mask_conversed_shift power_mult) +qed + +lemma aux_powertwo_digits: + fixes k c :: nat + assumes "k < c" + shows "nth_bit (2^c) k = 0" +proof - + have h: "(2::nat) ^ c div 2 ^ k = 2 ^ (c - k)" + by (simp add: assms less_imp_le power_diff) + thus ?thesis + by (auto simp: h nth_bit_def assms) +qed + +lemma obtain_digit_rep: + fixes x c :: nat + shows "x && 2^c = (\t 2^c" by (simp add: lm0245) + hence "x && 2^c \ 2^c" by (simp add: masks_leq) + hence h: "x && 2^c < 2^Suc c" + by (smt Suc_lessD le_neq_implies_less lessI less_trans_Suc n_less_m_mult_n numeral_2_eq_2 + power_Suc zero_less_power) + have "\t. (x && 2^c) \ t = (nth_bit x t) * (nth_bit (2^c) t)" + using bitAND_digit_mult by auto + then show ?thesis using h digit_sum_repr[of "(x && 2^c)" "Suc c"] + by (auto) (simp add: mult.commute semiring_normalization_rules(19)) +qed + +lemma nth_digit_bitAND_equiv: + fixes x c :: nat + shows "2^c * nth_bit x c = (x && 2^c)" +proof - + have d1: "nth_bit (2^c) c = 1" + using nth_bit_def by auto + + moreover have "x && 2^c = (2::nat)^c * (x \ c) * (((2::nat)^c) \ c) + + (\t t) * (((2::nat)^c) \ t))" + using obtain_digit_rep by (auto cong: sum.cong) + + moreover have "(\t x" +assumes "x < 2 ^ Suc c" + +shows "nth_bit x c = 1" +proof - + obtain b where b: "x = 2^c + b" + using assms(1) le_Suc_ex by auto + have bb: "b < 2^c" + using assms(2) b by auto + have "(2 ^ c + b) div 2 ^ c mod 2 = (1 + b div 2 ^ c) mod 2" + by (auto simp: div_add_self1) + also have "... = 1" + by (auto simp: bb) + finally show ?thesis + by (simp only: nth_bit_def b) +qed + +lemma aux_bitAND_distrib: "2 * (a && b) = (2 * a) && (2 * b)" + by (induct a b rule: bitAND_nat.induct; auto) + +lemma bitAND_distrib: "2^c * (a && b) = (2^c * a) && (2^c * b)" +proof (induction c) + case 0 + then show ?case by auto +next + case (Suc c) + have "2 ^ Suc c * (a && b) = 2 * (2 ^ c * (a && b))" by auto + also have "... = 2 * ((2^c * a) && (2^c * b))" using Suc.IH by auto + also have "... = ((2^Suc c * a) && (2^Suc c * b))" + using aux_bitAND_distrib[of "2^c * a" "2^c * b"] + by (auto simp add: ab_semigroup_mult_class.mult_ac(1)) + finally show ?case by auto +qed + +lemma bitAND_linear_sum: + fixes x y :: "nat \ nat" + and c :: nat + and q :: nat + +defines b: "b == 2 ^ Suc c" + +assumes xb: "\t. x t < 2 ^ Suc c - 1" +assumes yb: "\t. y t < 2 ^ Suc c - 1" + +shows "(\t = 0..q. (x t && y t) * b^t) = + (\t = 0..q. x t * b^t) && (\t = 0..q. y t * b^t)" +proof (induction q) + case 0 + then show ?case + by (auto simp: b B_def) +next + case (Suc q) + have "(\t = 0..Suc q. (x t && y t) * b ^ t) = (x (Suc q) && y (Suc q)) * b ^ Suc q + + (\t = 0..q. (x t && y t) * b ^ t)" + by (auto cong: sum.cong) + + moreover have h0: "(x (Suc q) && y (Suc q)) * b ^ Suc q + = (x (Suc q) * b^Suc q) && (y (Suc q) * b^Suc q)" + using b bitAND_distrib by (auto) (smt mult.commute power_Suc power_mult) + + moreover have h1: "(\t = 0..q. (x t && y t) * b ^ t) + = (\t = 0..q. x t * b^t) && (\t = 0..q. y t * b^t)" + using Suc.IH by auto + + ultimately have h2: "(\t = 0..Suc q. (x t && y t) * b ^ t) + = ((x (Suc q) * b^Suc q) && (y (Suc q) * b^Suc q)) + + ((\t = 0..q. x t * b^t) && (\t = 0..q. y t * b^t))" + by auto + + have sumxb: "(\t = 0..q. x t * b ^ t) < b ^ Suc q" + using base_summation_bound xb b B_def by auto + have sumyb: "(\t = 0..q. y t * b ^ t) < b ^ Suc q" + using base_summation_bound yb b B_def by auto + + have h3: "((x (Suc q) * b^Suc q) && (y (Suc q) * b^Suc q)) + + ((\t = 0..q. x t * b^t) && (\t = 0..q. y t * b^t)) + = ((\t = 0..q. x t * b^t) + x (Suc q) * b^Suc q) + && ((\t = 0..q. y t * b^t) + y (Suc q) * b^Suc q)" + using sumxb sumyb bitAND_linear h2 h0 + by (auto) (smt add.commute b power_Suc power_mult) + + thus ?case using h2 by (auto cong: sum.cong) +qed + +lemma dmask_aux0: + fixes x :: nat + assumes "x > 0" + shows "(2 ^ x - Suc 0) div 2 = 2 ^ (x - 1) - Suc 0" +proof - + have 0: "(2^x - Suc 0) div 2 = (2^x - 2) div 2" + by (smt Suc_diff_Suc Suc_pred assms dvd_power even_Suc even_Suc_div_two nat_power_eq_Suc_0_iff + neq0_conv numeral_2_eq_2 zero_less_diff zero_less_power) + (* can do manual parity distinction *) + moreover have divides: "(2::nat) dvd 2^x" + by (simp add: assms dvd_power[of x "2::nat"]) + moreover have "(2^x - 2::nat) div 2 = 2^x div 2 - 2 div 2" + using div_plus_div_distrib_dvd_left[of "2" "2^x" "2"] divides + by auto + moreover have "... = 2 ^ (x - 1) - Suc 0" + by (simp add: Suc_leI assms power_diff) + ultimately have 1: "(2 ^ x - Suc 0) div 2 = 2 ^ (x - 1) - Suc 0" + by (smt One_nat_def) + thus ?thesis by simp +qed + +lemma dmask_aux: + fixes c :: nat + shows "d < c \ (2^c - Suc 0) div 2^d = 2 ^ (c - d) - Suc 0" +proof (induction d) + case 0 + then show ?case by (auto) +next + case (Suc d) + have d: "d < c" using Suc.prems by auto + have "(2 ^ c - Suc 0) div 2 ^ Suc d = (2 ^ c - Suc 0) div 2 ^ d div 2" + by (auto) (metis mult.commute div_mult2_eq) + also have "... = (2 ^ (c - d) - Suc 0) div 2" + by (subst Suc.IH) (auto simp: d) + also have "... = 2 ^ (c - Suc d) - Suc 0" + apply (subst dmask_aux0[of "c - d"]) + using d by (auto) + finally show ?case by auto +qed + + +(* REGISTERS *) +lemma register_cells_masked: + fixes l :: register + and t :: nat + and ic :: configuration + and p :: program + +assumes cells_bounded: "cells_bounded ic p c" +assumes l: "l < length (snd ic)" + +shows "R ic p l t \ 2^c - 1" +proof - + have a: "R ic p l t \ 2^c - 1" using cells_bounded less_Suc_eq_le + using l by fastforce + have b: "r < c \ nth_bit (2^c - 1) r = 1" for r + apply (auto simp: nth_bit_def) + apply (subst dmask_aux) + apply (auto) + by (metis Suc_pred dvd_power even_Suc mod_0_imp_dvd not_mod2_eq_Suc_0_eq_0 + zero_less_diff zero_less_numeral zero_less_power) + show ?thesis using lt_implies_mask cells_bounded l + by (auto) (metis One_nat_def b) +qed + +lemma lm04_15_register_masking: + fixes c :: nat + and l :: register + and ic :: configuration + and p :: program + and q :: nat + +defines "b == B c" +defines "d == D q c b" + +assumes cells_bounded: "cells_bounded ic p c" +assumes l: "l < length (snd ic)" + +defines "r == RLe ic p b q" + +shows "r l \ d" +proof - + have "\t. R ic p l t \ 2^c - 1" using cells_bounded l + by (rule register_cells_masked) + hence rmasked: "\t. R ic p l t \ 2^c - 1" + by (intro allI) + + have rlt: "\t. R ic p l t \ 2^c - 1" + using cells_bounded less_Suc_eq_le l by fastforce + + have rlmasked: "(\t = 0..q. R ic p l t * b^t) \ (\t = 0..q. (2^c - 1) * b^t)" + using rmasked rlt b_def B_def mask_conserved_sum by (auto) + + thus ?thesis + by (auto simp: r_def d_def D_def RLe_def mult.commute cong: sum.cong) +qed + +(* ZERO INDICATORS *) +lemma zero_cells_masked: + fixes l :: register + and t :: nat + and ic :: configuration + and p :: program + +assumes l: "l < length (snd ic)" + +shows "Z ic p l t \ 1" +proof - + have "nth_bit 1 0 = 1" by (auto simp: nth_bit_def) + thus ?thesis apply (auto) apply (rule lt_implies_mask) + by (metis (full_types) One_nat_def Suc_1 Z_bounded less_Suc_eq_le less_one power_one_right) +qed + +lemma lm04_15_zero_masking: + fixes c :: nat + and l :: register + and ic :: configuration + and p :: program + and q :: nat + +defines "b == B c" +defines "e == E q b" + +assumes cells_bounded: "cells_bounded ic p c" +assumes l: "l < length (snd ic)" +assumes c: "c > 0" + +defines "z == ZLe ic p b q" + +shows "z l \ e" +proof - + have "\t. Z ic p l t \ 1" using l + by (rule zero_cells_masked) + hence zmasked: "\t. Z ic p l t \ 1" + by (intro allI) + + have zlt: "\t. Z ic p l t \ 2 ^ c - 1" + using cells_bounded less_Suc_eq_le by fastforce + + have 1: "(1::nat) \ 2 ^ c - 1" using c + by (simp add: Nat.le_diff_conv2 numeral_2_eq_2 self_le_power) + + have rlmasked: "(\t = 0..q. Z ic p l t * b^t) \ (\t = 0..q. 1 * b^t)" + using zmasked zlt 1 b_def B_def mask_conserved_sum[of "Z ic p l" 1] + by (auto) + + thus ?thesis + by (auto simp: z_def e_def E_def ZLe_def mult.commute cong: sum.cong) +qed + +(* Relation between zero indicator and register *) +lemma lm04_19_zero_register_relations: + fixes c :: nat + and l :: register + and t :: nat + and ic :: configuration + and p :: program + +assumes cells_bounded: "cells_bounded ic p c" +assumes l: "l < length (snd ic)" + +defines "z == Z ic p" +defines "r == R ic p" + +shows "2^c * z l t = (r l t + 2^c - 1) && 2^c" +proof - + have a1: "R ic p l t \ 0 \ 2^c \ R ic p l t + 2^c - 1" + by auto + have a2: "R ic p l t + 2^c - 1 < 2^Suc c" using cells_bounded + by (simp add: l less_imp_diff_less) + + have "Z ic p l t = nth_bit (R ic p l t + 2^c - 1) c" + apply (cases "R ic p l t = 0") + subgoal by (auto simp add: Z_def R_def nth_bit_def) + subgoal using cells_bounded bitAND_single_digit a1 a2 Z_def + by auto + done + + also have "2^c * nth_bit (R ic p l t + 2^c - 1) c = ((R ic p l t + 2^c - 1) && 2^c)" + using nth_digit_bitAND_equiv by auto + + finally show ?thesis by (auto simp: z_def r_def) +qed + +lemma lm04_20_zero_definition: + fixes c :: nat + and l :: register + and ic :: configuration + and p :: program + and q :: nat + +defines "b == B c" +defines "f == F q c b" +defines "d == D q c b" + +assumes cells_bounded: "cells_bounded ic p c" +assumes l: "l < length (snd ic)" + +assumes c: "c > 0" + +defines "z == ZLe ic p b q" +defines "r == RLe ic p b q" + +shows "2^c * z l = (r l + d) && f" +proof - + have "\t. 2^c * Z ic p l t = (R ic p l t + 2^c - 1) && 2^c" + by (rule lm04_19_zero_register_relations cells_bounded l) + + hence raw_sums: "(\t = 0..q. 2^c * Z ic p l t * b^t) + = (\t = 0..q. ((R ic p l t + 2^c - 1) && 2^c) * b^t)" + by auto + + have "(\t = 0..q. 2^c * Z ic p l t * b^t) = 2^c * (\t = 0..q. Z ic p l t * b^t)" + by (auto simp: sum_distrib_left mult.assoc cong: sum.cong) + also have "... = 2^c * z l" + by (auto simp: z_def ZLe_def mult.commute) + finally have lhs: "(\t = 0..q. 2^c * Z ic p l t * b^t) = 2^c * z l" + by auto + + have "(\t = 0..q. (R ic p l t + (2^c - 1)) * b^t) + = (\t = 0..q. R ic p l t * b^t + (2^c - 1) * b^t)" + apply (rule sum.cong) + apply (auto simp: add.commute mult.commute) + subgoal for x using distrib_left[of "b^x" "R ic p l x" "2^c - 1"] by (auto simp: algebra_simps) + done + also have "... = (\t = 0..q. (R ic p l t * b^t)) + (\t = 0..q. (2^c - 1) * b^t)" + by (rule sum.distrib) + also have "... = r l + d" + by (auto simp: r_def RLe_def d_def D_def mult.commute) + finally have split_sums: "(\t = 0..q. (R ic p l t + (2^c - 1)) * b^t) = r l + d" + by auto + + have a1: "(2::nat) ^ c < (2::nat) ^ Suc c - 1" using c by (induct c, auto, fastforce) + have a2: "\t. R ic p l t + 2 ^ c - 1 \ 2 ^ Suc c" using cells_bounded B_def + by (simp add: less_imp_diff_less l) (simp add: Suc_leD l less_imp_le_nat numeral_Bit0) + have "(\t = 0..q. ((R ic p l t + 2^c - 1) && 2^c) * b^t) + = (\t = 0..q. (R ic p l t + 2^c - 1) * b^t) && (\t = 0..q. 2^c * b^t)" + using bitAND_linear_sum[of "\t. R ic p l t + 2^c - 1" "c" "\t. 2^c"] + cells_bounded b_def B_def a1 a2 + apply auto + by (smt One_nat_def Suc_less_eq Suc_pred a1 add.commute add_gr_0 l mult_2 + nat_add_left_cancel_less power_Suc zero_less_numeral zero_less_power) + also have "... = (\t = 0..q. (R ic p l t + 2^c - 1) * b^t) && f" + by (auto simp: f_def F_def) + also have "... = (r l + d) && f" using split_sums + by auto + finally have rhs: "(\t = 0..q. ((R ic p l t + 2^c - 1) && 2^c) * b^t) = (r l + d) && f" + by auto + + show ?thesis using raw_sums lhs rhs + by auto +qed + +lemma state_mask: +fixes c :: nat + and l :: register + and ic :: configuration + and p :: program + and q :: nat + and a :: nat + +defines "b \ B c" + and "m \ length p - 1" + +defines "e \ E q b" + +assumes is_val: "is_valid_initial ic p a" + and q: "q > 0" + and "c > 0" + +assumes terminate: "terminates ic p q" + shows "SKe ic p b q k \ e" +proof - + have "1 \ 2 ^ c - Suc 0" using \c>0\ by (metis One_nat_def Suc_leI one_less_numeral_iff + one_less_power semiring_norm(76) zero_less_diff) + have Smask: "S ic p k t \ 1" for t by (simp add: S_def) + have Sbound: "S ic p k t \ 2 ^ c - Suc 0" for t using \1\2^c-Suc 0\ by (simp add: S_def) + have rlmasked: "(\t = 0..q. S ic p k t * b^t) \ (\t = 0..q. 1 * b^t)" + using b_def B_def Smask Sbound mask_conserved_sum[of "S ic p k" 1] \1 \ 2^c-Suc 0\ by auto + + thus ?thesis using SKe_def e_def E_def by (auto simp: mult.commute) +qed + +lemma state_sum_mask: +fixes c :: nat + and l :: register + and ic :: configuration + and p :: program + and q :: nat + and a :: nat + +defines "b \ B c" + and "m \ length p - 1" + +defines "e \ E q b" + +assumes is_val: "is_valid_initial ic p a" + and q: "q > 0" + and "c > 0" + and "b > 1" + +assumes "M\m" + +assumes terminate: "terminates ic p q" +shows "(\k\M. SKe ic p b q k) \ e" +proof - + have e_aux: "nth_digit e t b = (if t\q then 1 else 0)" for t + unfolding e_def E_def b_def B_def + using `b>1` b_def nth_digit_gen_power_series[of "\k. Suc 0" "c" "q"] + by (auto simp: b_def B_def) + + have state_unique: "\k\m. S ic p k t = 1 \ (\j\k. S ic p j t = 0)" for t + using S_def by (induction t, auto) + + have h1: "\t. nth_digit (\k\M. SKe ic p b q k) t b \ (if t\q then 1 else 0)" + proof - { + fix t + have aux_bound_1: "(\k\M. S ic p k t') \ 1" for t' + proof (cases "\k\M. S ic p k t' = 1") + case True + then obtain k where k: "k\M \ S ic p k t' = 1" by auto + moreover have "\j\M. j \ k \ S ic p j t' = 0" + using state_unique `M<=m` k S_def + by (auto) (presburger) + ultimately have "(\k\M. S ic p k t') = 1" + using S_def by auto + then show ?thesis + by auto + next + case False + then show ?thesis using S_bounded + by (auto) (metis (no_types, lifting) S_def atMost_iff eq_imp_le le_SucI sum_nonpos) + qed + hence aux_bound_2: "\t'. (\k\M. S ic p k t') < 2^c" + by (metis Suc_1 `c>0` le_less_trans less_Suc_eq one_less_power) + + have h2: "(\k\M. SKe ic p b q k) = (\t = 0..q. \k\M. b ^ t * S ic p k t)" + unfolding SKe_def using sum.swap by auto + hence "(\k\M. SKe ic p b q k) = (\t = 0..q. b^t * (\k\M. S ic p k t))" + unfolding SKe_def by (simp add: sum_distrib_left) + + hence "nth_digit (\k\M. SKe ic p b q k) t b = (if t\q then (\k\M. S ic p k t) else 0)" + using `c>0` aux_bound_2 h2 unfolding SKe_def + using nth_digit_gen_power_series[of "\t. (\k\M. S ic p k t)" "c" "q" "t"] + by (smt B_def Groups.mult_ac(2) assms(7) aux_bound_1 b_def le_less_trans sum.cong) + hence "nth_digit (\k\M. SKe ic p b q k) t b \ (if t\q then 1 else 0)" + using aux_bound_1 by auto + } thus ?thesis by auto + qed + moreover have "\t>q. nth_digit (\k\M. SKe ic p b q k) t b = 0" + by (metis (full_types) h1 le_0_eq not_less) + ultimately have "\t. \ik\M. SKe ic p b q k) t b \ i + \ nth_digit e t b \ i" + using aux_lt_implies_mask linorder_neqE_nat e_aux + by (smt One_nat_def le_0_eq le_SucE less_or_eq_imp_le nat_zero_less_power_iff + numeral_2_eq_2 zero_less_Suc) + + hence "\t. \ik\M. SKe ic p b q k) \ (Suc c * t + i) \ e \ (Suc c * t + i)" + using digit_gen_pow2_reduct[where ?c = "Suc c" and ?a = "(\k\M. SKe ic p b q k)"] + using digit_gen_pow2_reduct[where ?c = "Suc c" and ?a = e] + by (simp add: b_def B_def) + moreover have "\j. \t i. i < Suc c \ j = (Suc c * t + i)" + using mod_less_divisor zero_less_Suc + by (metis add.commute mod_mult_div_eq) + ultimately have "\j. (\k\M. SKe ic p b q k) \ j \ e \ j" + by metis + + thus ?thesis + using masks_leq_equiv by auto +qed + +end diff --git a/thys/DPRM_Theorem/Register_Machine/MultipleStepRegister.thy b/thys/DPRM_Theorem/Register_Machine/MultipleStepRegister.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Register_Machine/MultipleStepRegister.thy @@ -0,0 +1,456 @@ +subsection \Multiple step relations\ + +subsubsection \Registers\ + +theory MultipleStepRegister + imports SingleStepRegister +begin + +lemma lm04_22_multiple_register: + fixes c :: nat + and l :: register + and ic :: configuration + and p :: program + and q :: nat + and a :: nat + + defines "b == B c" + and "m == length p" + and "n == length (snd ic)" + +assumes is_val: "is_valid_initial ic p a" +assumes c_gt_cells: "cells_bounded ic p c" +assumes l: "l < n" +and "0 < l" +and q: "q > 0" + +assumes terminate: "terminates ic p q" + +assumes c: "c > 1" + + defines "r == RLe ic p b q" + and "z == ZLe ic p b q" + and "s == SKe ic p b q" + +shows "r l = b * r l + + b * (\R+ p l s) + - b * (\R- p l (\k. z l && s k))" +proof - + have 0: "snd ic ! l = 0" using assms(4, 7) by (cases "ic"; auto simp add: is_valid_initial_def) + + have "b^(Suc t) * (\R- p l (\k. (Z ic p l t) * S ic p k t)) \ b^(Suc t) * R ic p l t " for t + proof (cases "t=0") + case True + hence "R ic p l 0 = 0" by (auto simp add: 0 R_def) + thus ?thesis by (auto simp add: True Z_def sum_rsub.simps) + next + case False + define cs where "cs \ fst (steps ic p t)" + have sub: "(\R- p l (\k. Z ic p l t * S ic p k t)) + = (if issub (p!cs) \ l = modifies (p!cs) then Z ic p l t else 0)" + using single_step_sub Z_def R_def is_val l n_def cs_def by auto + show ?thesis using sub by (auto simp add: sum_rsub.simps R_def Z_def) + qed + + from this have positive: "b^(Suc t) * (\R- p l (\k. (Z ic p l t) * S ic p k t)) + \ b^(Suc t) * R ic p l t + + b^(Suc t) * (\R+ p l (\k. S ic p k t))" for t + by (auto simp add: Nat.trans_le_add1) + + have commute_add: "(\t=0..q-1. \R+ p l (\k. b^t * S ic p k t)) + = \R+ p l (\k. \t=0..q-1. (b^t * S ic p k t))" + using sum_radd_commutative[of "p" "l" "\k t. b^t * S ic p k t " "q-1"] by auto + + have r_q: "l R ic p l q = 0" + using terminate terminates_def correct_halt_def by (auto simp: n_def R_def) + hence z_q: "l Z ic p l q = 0" + using terminate terminates_def correct_halt_def by (auto simp: Z_def) + have "\k ishalt (p!k)" + using is_val is_valid_initial_def[of "ic" "p" "a"] is_valid_def[of "ic" "p"] + program_includes_halt.simps by blast + hence s_q: "\k < length p - 1. S ic p k q = 0" + using terminate terminates_def correct_halt_def S_def by auto + + from r_q have rq: "(\x = 0..q - 1. int b ^ x * int (snd (steps ic p x) ! l)) = + (\x = 0..q. int b ^ x * int (snd (steps ic p x) ! l))" + by (auto simp: r_q R_def l; + smt Suc_pred mult_0_right of_nat_0 of_nat_mult power_mult_distrib q sum.atLeast0_atMost_Suc zero_power) + + have "(\t = 0..q - 1. b ^ t * (Z ic p l t * S ic p k t)) + + (b^(Suc (q-1)) * (Z ic p l (Suc (q-1)) * S ic p k (Suc (q-1)))) + = (\t = 0..Suc (q-1). b ^ t * (Z ic p l t * S ic p k t)) " for k + using comm_monoid_add_class.sum.atLeast0_atMost_Suc by auto + hence zq: "(\t = 0..q - 1. b ^ t * (Z ic p l t * S ic p k t)) + = (\t = 0..q. b ^ t * (Z ic p l t * S ic p k t)) " for k + using z_q q l by auto + + have "(if isadd (p ! k) \ l = modifies (p ! k) then \t = 0..q - Suc 0. b ^ t * S ic p k t else 0) + = (if isadd (p ! k) \ l = modifies (p ! k) then \t = 0..q. b ^ t * S ic p k t else 0)" for k + proof (cases "p!k") + case (Add x11 x12) + have sep: "(\t = 0..q-1. b ^ t * S ic p k t) + b^q * S ic p k q + = (\t = 0..(Suc (q-1)). b ^ t * S ic p k t)" + using comm_monoid_add_class.sum.atLeast0_atMost_Suc[of "\t. b^t * S ic p k t" "q-1"] q + by auto + have "ishalt (p ! (fst (steps ic p q)))" + using terminates_halt_state[of "ic" "p"] is_val terminate by auto + hence "S ic p k q = 0" using Add S_def[of "ic" "p" "k" "q"] by auto + with sep q have "(\t = 0..q - Suc 0. b ^ t * S ic p k t) = (\t = 0..q. b ^ t * S ic p k t)" + by auto + thus ?thesis by auto + next + case (Sub x21 x22 x23) + then show ?thesis by auto + next + case Halt + then show ?thesis by auto + qed + + hence add_q: "\R+ p l (\k. \t=0..(q-1). b^t * S ic p k t) + = \R+ p l (\k. \t=0..q. b^t * S ic p k t)" + using sum_radd.simps single_step_add[of "ic" "p" "a" "l" "snd ic"] is_val l n_def by auto + + (* Start *) + have "r l = (\t = 0..q. b^t * R ic p l t)" using r_def RLe_def by auto + also have "... = R ic p l 0 + (\t = 1..q. b^t * R ic p l t)" + by (auto simp: q comm_monoid_add_class.sum.atLeast_Suc_atMost) + also have "... = (\t \ {1..q}. b^t * R ic p l t)" + by (simp add: R_def 0) + also have "... = (\t \ (Suc ` {0..(q-1)}). b^t * R ic p l t)" using q by auto + also have "... = (sum ((\t. b^t * R ic p l t) \ Suc)) {0..(q-1)}" + using comm_monoid_add_class.sum.reindex[of "Suc" "{0..(q-1)}" "(\t. b^t * R ic p l t)"] by auto + also have "... = (\t = 0..(q-1). b^(Suc t) *(R ic p l t + + (\R+ p l (\k. S ic p k t)) + - (\R- p l (\k. (Z ic p l t) * S ic p k t))))" + using lm04_06_one_step_relation_register[of "ic" "p" "a" "l"] is_val l + by (simp add: n_def m_def) + + also have "... = (\t \ {0..(q-1)}. b^(Suc t) * R ic p l t + + b^(Suc t) * (\R+ p l (\k. S ic p k t)) + - b^(Suc t) * (\R- p l (\k. (Z ic p l t) * S ic p k t)))" + by (auto simp add: algebra_simps) + + finally have "int (r l) = (\t \ {0..(q-1)}. int( + b^(Suc t) * R ic p l t + + b^(Suc t) * (\R+ p l (\k. S ic p k t)) + - b^(Suc t) * (\R- p l (\k. (Z ic p l t) * S ic p k t))))" + by auto + + also have "... = (\t \ {0..(q-1)}. int (b^(Suc t) * R ic p l t) + + int (b^(Suc t) * (\R+ p l (\k. S ic p k t))) + - int (b^(Suc t) * (\R- p l (\k. (Z ic p l t) * S ic p k t))))" + by (simp only: sum_int positive) + + also have "... = (\t \ {0..(q-1)}. int (b^(Suc t) * R ic p l t) + + (int (b^(Suc t) * (\R+ p l (\k. S ic p k t))) + - int (b^(Suc t) * (\R- p l (\k. (Z ic p l t) * S ic p k t)))))" + by (simp add: add_diff_eq) + + also have "... = (\t \ {0..(q-1)}. int( b^(Suc t) * R ic p l t )) + + (\t \ {0..(q-1)}. int( b^(Suc t) * (\R+ p l (\k. S ic p k t))) + - int( b^(Suc t) * (\R- p l (\k. (Z ic p l t) * S ic p k t ))))" + by (auto simp only: sum.distrib) + + also have "... = int b * int (\t \ {0..(q-1)}. b^t * R ic p l t ) + + int b * (\t \ {0..(q-1)}. int(b^t * (\R+ p l (\k. S ic p k t))) + - int(b^t * (\R- p l (\k. (Z ic p l t) * S ic p k t ))))" + by (auto simp: sum_distrib_left mult.assoc right_diff_distrib) + + also have "... = int b * int (\t \ {0..(q-1)}. b^t * R ic p l t ) + + int b * (\t \ {0..(q-1)}. int(b^t * (\R+ p l (\k. S ic p k t)))) + - int b * (\t \ {0..(q-1)}. int(b^t * (\R- p l (\k. (Z ic p l t) * S ic p k t))))" + by (auto simp add: sum.distrib int_distrib(4) sum_subtractf) + + also have "... = int b * int (\t \ {0..(q-1)}. b^t * R ic p l t ) + + int b * (\t \ {0..(q-1)}. int(\R+ p l (\k. b^t * S ic p k t))) + - int b * (\t \ {0..(q-1)}. int(\R- p l (\k. b^t * (Z ic p l t * S ic p k t))))" + using sum_radd_distrib sum_rsub_distrib by auto + + also have "... = int b * int (\t = 0..q-1. b^t * R ic p l t) + + int b * int (\t = 0..q-1. \R+ p l (\k. b^t * S ic p k t)) + - int b * int (\t = 0..q-1. \R- p l (\k. b^t * (Z ic p l t * S ic p k t)))" + by auto + + also have "... = int b * int (\t = 0..q-1. b^t * R ic p l t) + + int b * int (\R+ p l (\k. \t=0..q-1. b^t * S ic p k t)) + - int b * int (\R- p l (\k. \t=0..q-1. b^t * (Z ic p l t * S ic p k t)))" + using sum_rsub_commutative[of "p" "l" "\k t. b^t * (Z ic p l t * S ic p k t)" "q-1"] + using sum_radd_commutative[of "p" "l" "\k t. b^t * S ic p k t " "q-1"] by auto + + (* extend all sums until q, because values don't change at time q *) + also have "... = int b * int (\t=0..q. b^t * R ic p l t) + + int b * int (\R+ p l (\k. \t=0..q-1. b^t * S ic p k t)) + - int b * int (\R- p l (\k. \t=0..q-1. b^t * (Z ic p l t * S ic p k t)))" + by (auto simp: rq R_def; smt One_nat_def rq) + + also have "... = int b * int (\t=0..q. b^t * R ic p l t) + + int b * int (\R+ p l (\k. \t=0..q. b^t * S ic p k t)) + - int b * int (\R- p l (\k. \t=0..q. b^t * (Z ic p l t * S ic p k t)))" + using zq add_q by auto + + also have "... = int b * int (RLe ic p b q l) + + int b * int (\R+ p l (SKe ic p b q)) + - int b * int (\R- p l (\k. \t=0..q. b^t * (Z ic p l t * S ic p k t)))" + by (auto simp: RLe_def; metis SKe_def) + + (* prove multiplication turns into bitAND *) + also have "... = int b * int (RLe ic p b q l) + + int b * int (\R+ p l (SKe ic p b q)) + - int b * int (\R- p l (\k. ZLe ic p b q l && SKe ic p b q k))" + using mult_to_bitAND c_gt_cells b_def c by auto + + finally have "int(r l) = int b * int (r l) + + int b * int (\R+ p l s) + - int b * int (\R- p l (\k. z l && s k))" + by (auto simp: r_def s_def z_def) + + hence "r l = b * r l + + b * \R+ p l s + - b * \R- p l (\k. z l && s k)" + using int_ops(5) int_ops(7) nat_int nat_minus_as_int by presburger + + thus ?thesis by simp +qed + +lemma lm04_23_multiple_register1: + fixes c :: nat + and l :: register + and ic :: configuration + and p :: program + and q :: nat + and a :: nat + + defines "b == B c" + and "m == length p" + and "n == length (snd ic)" + +assumes is_val: "is_valid_initial ic p a" +assumes c_gt_cells: "cells_bounded ic p c" +assumes l: "l = 0" +and q: "q > 0" + +assumes c: "c > 1" + + assumes terminate: "terminates ic p q" + + defines "r == RLe ic p b q" + and "z == ZLe ic p b q" + and "s == SKe ic p b q" + +shows "r l = a + b * r l + + b * (\R+ p l s) + - b * (\R- p l (\k. z l && s k))" +proof - + have n: "n > 0" using is_val + by (auto simp add: is_valid_initial_def n_def) + + have 0: "snd ic ! l = a" + using assms by (cases "ic"; auto simp add: is_valid_initial_def List.hd_conv_nth) + + find_theorems "hd ?l = ?l ! 0" + + have bound_fst_ic: "(if fst ic \ length p-1 then 1 else 0) \ Suc 0" by auto + have "(if issub (p ! k) \ l = modifies (p ! k) then if fst ic = k then 1 else 0 else 0) + = (if k = fst ic \ issub (p ! k) \ l = modifies (p ! k) then 1 else 0)" for k by auto + hence "(if issub (p ! k) \ l = modifies (p ! k) then if fst ic = k then Suc 0 else 0 else 0) + \ (if k = fst ic then 1 else 0)" for k + apply (cases "p!k") + apply (cases "modifies (p!k)") + by auto + hence sub: " (\k = 0..length p-1. if issub (p ! k) \ l = modifies (p ! k) + then if fst ic = k then Suc 0 else 0 else 0) \ Suc 0" + using Groups_Big.ordered_comm_monoid_add_class.sum_mono[of "{0..length p-1}" + "\k. (if issub (p ! k) \ l = modifies (p ! k) then if fst ic = k then Suc 0 else 0 else 0)" + "\k. (if k = fst ic then 1 else 0)"] bound_fst_ic Orderings.ord_class.ord_eq_le_trans by auto + + have "b^(Suc t) * (\R- p l (\k. (Z ic p l t) * S ic p k t)) \ b^(Suc t) * R ic p l t " for t + proof (cases "t=0") + case True + hence "a = R ic p l 0" by (auto simp add: 0 R_def) + thus ?thesis + apply (cases "a=0") + subgoal by (auto simp add: True R_def Z_def sum_rsub.simps) + subgoal + apply (auto simp add: True R_def Z_def sum_rsub.simps S_def) + using sub by auto + done + next + case False + define cs where "cs \ fst (steps ic p t)" + have sub: "(\R- p l (\k. Z ic p l t * S ic p k t)) + = (if issub (p!cs) \ l = modifies (p!cs) then Z ic p l t else 0)" + using single_step_sub Z_def R_def is_val l n_def cs_def n by auto + show ?thesis using sub by (auto simp add: sum_rsub.simps R_def Z_def) + qed + + from this have positive: "b^(Suc t) * (\R- p l (\k. (Z ic p l t) * S ic p k t)) + \ b^(Suc t) * R ic p l t + + b^(Suc t) * (\R+ p l (\k. S ic p k t))" for t + by (auto simp add: Nat.trans_le_add1) + + have distrib_add: "\t. b^t * \R+ p l (\k. S ic p k t) = \R+ p l (\k. b ^ t * S ic p k t)" + by (simp add: sum_radd_distrib) + have distrib_sub: "\t. b^t * \R- p l (\k. Z ic p l t * S ic p k t) + = \R- p l (\k. b ^ t * (Z ic p l t * S ic p k t))" + by (simp add: sum_rsub_distrib) + + have commute_add: "(\t=0..q-1. \R+ p l (\k. b^t * S ic p k t)) + = \R+ p l (\k. \t=0..q-1. (b^t * S ic p k t))" + using sum_radd_commutative[of "p" "l" "\k t. b^t * S ic p k t " "q-1"] by auto + + have "length (snd ic) > 0" using is_val is_valid_initial_def[of "ic" "p" "a"] by auto + hence r_q: "R ic p l q = 0" + using terminate terminates_def correct_halt_def l by (auto simp: n_def R_def) + hence z_q: "Z ic p l q = 0" + using terminate by (auto simp: Z_def) + + have "\k ishalt (p!k)" + using is_val is_valid_initial_def[of "ic" "p" "a"] is_valid_def[of "ic" "p"] + program_includes_halt.simps by blast + hence s_q: "\k < length p - 1. S ic p k q = 0" + using terminate terminates_def correct_halt_def by (auto simp: S_def) + + from r_q have rq: "(\x = 0..q - 1. int b ^ x * int (snd (steps ic p x) ! l)) = + (\x = 0..q. int b ^ x * int (snd (steps ic p x) ! l))" + by (auto simp: r_q R_def; smt Suc_pred mult_0_right of_nat_0 of_nat_mult power_mult_distrib q + sum.atLeast0_atMost_Suc zero_power) + + have "(\t = 0..q - 1. b ^ t * (Z ic p l t * S ic p k t)) + + (b^(Suc (q-1)) * (Z ic p l (Suc (q-1)) * S ic p k (Suc (q-1)))) + = (\t = 0..Suc (q-1). b ^ t * (Z ic p l t * S ic p k t)) " for k + using comm_monoid_add_class.sum.atLeast0_atMost_Suc by auto + hence zq: "(\t = 0..q - 1. b ^ t * (Z ic p l t * S ic p k t)) + = (\t = 0..q. b ^ t * (Z ic p l t * S ic p k t)) " for k + using z_q q by auto + + have "(if isadd (p ! k) \ l = modifies (p ! k) then \t = 0..q - Suc 0. b ^ t * S ic p k t else 0) + = (if isadd (p ! k) \ l = modifies (p ! k) then \t = 0..q. b ^ t * S ic p k t else 0)" for k + proof (cases "p!k") + case (Add x11 x12) + have sep: "(\t = 0..q-1. b ^ t * S ic p k t) + b^q * S ic p k q + = (\t = 0..(Suc (q-1)). b ^ t * S ic p k t)" + using comm_monoid_add_class.sum.atLeast0_atMost_Suc[of "\t. b^t * S ic p k t" "q-1"] q + by auto + have "ishalt (p ! (fst (steps ic p q)))" + using terminates_halt_state[of "ic" "p"] is_val terminate by auto + hence "S ic p k q = 0" using Add S_def[of "ic" "p" "k" "q"] by auto + with sep q have "(\t = 0..q - Suc 0. b ^ t * S ic p k t) = (\t = 0..q. b ^ t * S ic p k t)" + by auto + thus ?thesis by auto + next + case (Sub x21 x22 x23) + then show ?thesis by auto + next + case Halt + then show ?thesis by auto + qed + + hence add_q: "\R+ p l (\k. \t=0..(q-1). b^t * S ic p k t) + = \R+ p l (\k. \t=0..q. b^t * S ic p k t)" + using sum_radd.simps single_step_add[of "ic" "p" "a" "l" "snd ic"] is_val l n_def by auto + + (* Start *) + have "r l = (\t = 0..q. b^t * R ic p l t)" using r_def RLe_def by auto + also have "... = R ic p l 0 + (\t = 1..q. b^t * R ic p l t)" + by (auto simp: q comm_monoid_add_class.sum.atLeast_Suc_atMost) + also have "... = a + (\t \ {1..q}. b^t * R ic p l t)" + by (simp add: R_def 0) + also have "... = a + (\t = (Suc 0)..(Suc (q-1)). b^t * R ic p l t)" using q by auto + also have "... = a + (\t \ (Suc ` {0..(q-1)}). b^t * R ic p l t)" by auto + also have "... = a + (sum ((\t. b^t * R ic p l t) \ Suc)) {0..(q-1)}" + using comm_monoid_add_class.sum.reindex[of "Suc" "{0..(q-1)}" "(\t. b^t * R ic p l t)"] by auto + also have "... = a + (\t = 0..(q-1). b^(Suc t) * R ic p l (Suc t))" by auto + also have "... = a + (\t = 0..(q-1). b^(Suc t) *(R ic p l t + + (\R+ p l (\k. S ic p k t)) + - (\R- p l (\k. (Z ic p l t) * S ic p k t))))" + using lm04_06_one_step_relation_register[of "ic" "p" "a" "l"] is_val n n_def l + by (auto simp add: n_def m_def) + + also have "... = a + (\t \ {0..(q-1)}. b^(Suc t) * R ic p l t + + b^(Suc t) * (\R+ p l (\k. S ic p k t)) + - b^(Suc t) * (\R- p l (\k. (Z ic p l t) * S ic p k t)))" + by (auto simp add: algebra_simps) + + finally have "int (r l) = int a +(\t \ {0..(q-1)}. int( + b^(Suc t) * R ic p l t + + b^(Suc t) * (\R+ p l (\k. S ic p k t)) + - b^(Suc t) * (\R- p l (\k. (Z ic p l t) * S ic p k t))))" + by auto + + also have "... = int a + (\t \ {0..(q-1)}. int (b^(Suc t) * R ic p l t) + + int (b^(Suc t) * (\R+ p l (\k. S ic p k t))) + - int (b^(Suc t) * (\R- p l (\k. (Z ic p l t) * S ic p k t))))" + by (simp only: sum_int positive) + + also have "... = int a + (\t \ {0..(q-1)}. int (b^(Suc t) * R ic p l t) + + (int (b^(Suc t) * (\R+ p l (\k. S ic p k t))) + - int (b^(Suc t) * (\R- p l (\k. (Z ic p l t) * S ic p k t)))))" + by (simp add: add_diff_eq) + + also have "... = int a + (\t \ {0..(q-1)}. int( b^(Suc t) * R ic p l t )) + + (\t \ {0..(q-1)}. int( b^(Suc t) * (\R+ p l (\k. S ic p k t))) + - int( b^(Suc t) * (\R- p l (\k. (Z ic p l t) * S ic p k t ))))" + by (auto simp only: sum.distrib) + + also have "... = int a + int b * int (\t \ {0..(q-1)}. b^t * R ic p l t ) + + int b * (\t \ {0..(q-1)}. int(b^t * (\R+ p l (\k. S ic p k t))) + - int(b^t * (\R- p l (\k. (Z ic p l t) * S ic p k t ))))" + by (auto simp: sum_distrib_left mult.assoc right_diff_distrib) + + also have "... = int a + int b * int (\t \ {0..(q-1)}. b^t * R ic p l t ) + + int b * (\t \ {0..(q-1)}. int(b^t * (\R+ p l (\k. S ic p k t)))) + - int b * (\t \ {0..(q-1)}. int(b^t * (\R- p l (\k. (Z ic p l t) * S ic p k t))))" + by (auto simp add: sum.distrib int_distrib(4) sum_subtractf) + + also have "... = int a + int b * int (\t \ {0..(q-1)}. b^t * R ic p l t ) + + int b * (\t \ {0..(q-1)}. int(\R+ p l (\k. b^t * S ic p k t))) + - int b * (\t \ {0..(q-1)}. int(\R- p l (\k. b^t * (Z ic p l t * S ic p k t))))" + using distrib_add distrib_sub by auto + + also have "... = int a + int b * int (\t = 0..q-1. b^t * R ic p l t) + + int b * int (\t = 0..q-1. \R+ p l (\k. b^t * S ic p k t)) + - int b * int (\t = 0..q-1. \R- p l (\k. b^t * (Z ic p l t * S ic p k t)))" + by auto + + also have "... = int a + int b * int (\t = 0..q-1. b^t * R ic p l t) + + int b * int (\R+ p l (\k. \t=0..q-1. b^t * S ic p k t)) + - int b * int (\R- p l (\k. \t=0..q-1. b^t * (Z ic p l t * S ic p k t)))" + using sum_rsub_commutative[of "p" "l" "\k t. b^t * (Z ic p l t * S ic p k t)" "q-1"] + using sum_radd_commutative[of "p" "l" "\k t. b^t * S ic p k t " "q-1"] by auto + + (* extend all sums until q, because values don't change at time q *) + also have "... = int a + int b * int (\t=0..q. b^t * R ic p l t) + + int b * int (\R+ p l (\k. \t=0..q-1. b^t * S ic p k t)) + - int b * int (\R- p l (\k. \t=0..q-1. b^t * (Z ic p l t * S ic p k t)))" + by (auto simp: rq R_def; smt One_nat_def rq) + + also have "... = int a + int b * int (\t=0..q. b^t * R ic p l t) + + int b * int (\R+ p l (\k. \t=0..q. b^t * S ic p k t)) + - int b * int (\R- p l (\k. \t=0..q. b^t * (Z ic p l t * S ic p k t)))" + using zq add_q by auto + + also have "... = int a + int b * int (RLe ic p b q l) + + int b * int (\R+ p l (SKe ic p b q)) + - int b * int (\R- p l (\k. \t=0..q. b^t * (Z ic p l t * S ic p k t)))" + by (auto simp: RLe_def; metis SKe_def) + + (* prove multiplication turns into bitAND *) + also have "... = int a + int b * int (RLe ic p b q l) + + int b * int (\R+ p l (SKe ic p b q)) + - int b * int (\R- p l (\k. ZLe ic p b q l && SKe ic p b q k))" + using mult_to_bitAND c_gt_cells b_def c by auto + + finally have "int(r l) = int a + int b * int (r l) + + int b * int (\R+ p l s) + - int b * int (\R- p l (\k. z l && s k))" + by (auto simp: r_def s_def z_def) + + hence "r l = a + b * r l + + b * \R+ p l s + - b * \R- p l (\k. z l && s k)" + using int_ops(5) int_ops(7) nat_int nat_minus_as_int by presburger + + thus ?thesis by simp +qed + +end diff --git a/thys/DPRM_Theorem/Register_Machine/MultipleStepState.thy b/thys/DPRM_Theorem/Register_Machine/MultipleStepState.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Register_Machine/MultipleStepState.thy @@ -0,0 +1,404 @@ +subsubsection \States\ + +theory MultipleStepState + imports SingleStepState +begin + +lemma lm04_24_multiple_step_states: +fixes c :: nat + and l :: register + and ic :: configuration + and p :: program + and q :: nat + and a :: nat + + defines "b == B c" + and "m == length p" + +assumes is_val: "is_valid_initial ic p a" +assumes c_gt_cells: "cells_bounded ic p c" +assumes d: "d \ m-1" and "0 < d" + and q: "q > 0" + +assumes terminate: "terminates ic p q" + +assumes c: "c > 1" + + defines "r \ RLe ic p b q" + and "z \ ZLe ic p b q" + and "s \ SKe ic p b q" + and "e \ \t = 0..q. b^t" + +shows "s d = b * (\S+ p d s) + + b * (\S- p d (\k. z (modifies (p!k)) && s k)) + + b * (\S0 p d (\k. (e - z (modifies (p!k))) && s k))" +proof - + have "program_includes_halt p" + using is_val is_valid_initial_def[of "ic" "p" "a"] is_valid_def[of "ic" "p"] by auto + + have halt_term0: "t \ q-1 \ (if ishalt (p!(fst (steps ic p t))) \ d = fst (steps ic p t) + then Suc 0 else 0) = 0" for t + using terminate terminates_def by auto + + have single_step: "S ic p d (Suc t) = (\S+ p d (\k. S ic p k t)) + + (\S- p d (\k. Z ic p (modifies (p!k)) t * S ic p k t)) + + (\S0 p d (\k. (1 - Z ic p (modifies (p!k)) t) * S ic p k t)) + + (if ishalt (p!(fst (steps ic p t))) \ d = fst (steps ic p t) then Suc 0 else 0)" for t + using lm04_07_one_step_relation_state[of "ic" "p" "a" "d"] is_val `d>0` d + by (simp add: m_def) + + have b: "b > 0" using b_def B_def by auto + have halt: "ishalt (p!fst(steps ic p q))" using terminate terminates_def correct_halt_def by auto + have add_conditions: "(if isadd (p ! k) \ d = goes_to (p ! k) + then (\t = 0..q - Suc 0. b ^ t * S ic p k t) + b ^ q * S ic p k q else 0) + = (if isadd (p ! k) \ d = goes_to (p ! k) + then \t = 0..q - Suc 0. b ^ t * S ic p k t else 0)" for k + apply (cases "p!k"; cases "d = goes_to (p!k)") using q S_def b halt by auto + have "b * b ^ (q - Suc 0) = b ^ (q - Suc 0 + Suc 0)" using q + by (simp add: power_eq_if) + have "(\k. (\t = 0..(q-1). b^t * S ic p k t) + b^(Suc (q-1)) * S ic p k (Suc (q-1))) + = (\k. (\t = 0..(Suc (q-1)). b^t * S ic p k t))" by auto + hence "\S+ p d (\k. (\t = 0..(q-1). b^t * S ic p k t) + b^q * S ic p k (Suc (q-1))) + = \S+ p d (\k. \t = 0..(Suc (q-1)). b^t * S ic p k t)" using q + by auto + hence add_q: "\S+ p d (\k. \t = 0..(q-1). b^t * S ic p k t) + = \S+ p d (\k. \t = 0..q. b^t * S ic p k t)" + by (auto simp add: sum_sadd.simps q add_conditions) + + have "issub (p!k) \ b ^ (Suc (q-1)) * (Z ic p (modifies (p ! k)) (Suc (q-1)) * + (if fst (steps ic p (Suc (q-1))) = k then Suc 0 else 0)) = 0" for k + by (auto simp: q halt) + hence sum_equiv_nzero: "issub (p!k) \ + (\t = 0..q-1. b ^ t * (Z ic p (modifies (p ! k)) t * + (if fst (steps ic p t) = k then Suc 0 else 0))) + = (\t = 0..(Suc (q-1)). b ^ t * (Z ic p (modifies (p ! k)) t * + (if fst (steps ic p t) = k then Suc 0 else 0)))" for k + using sum.atLeast0_atMost_Suc[of "\t. b ^ t * (Z ic p (modifies (p ! k)) t + * (if fst (steps ic p t) = k then Suc 0 else 0))" "q-1"] by auto + hence sub_nzero_conditions: "(if issub (p ! k) \ d = goes_to (p ! k) then + \t = 0..q - Suc 0. b ^ t * (Z ic p (modifies (p ! k)) t * S ic p k t) else 0) + = (if issub (p ! k) \ d = goes_to (p ! k) then + \t = 0..q. b ^ t * (Z ic p (modifies (p ! k)) t * S ic p k t) else 0)" for k + apply (cases "issub (p!k)") using q S_def halt b by auto + have "(\k. (\t=0..(q-1). b^t * (Z ic p (modifies (p!k)) t * S ic p k t)) + + b^(Suc (q-1)) * (Z ic p (modifies (p!k)) (Suc (q-1)) * S ic p k (Suc (q-1)))) + = (\k. \t=0..(Suc (q-1)). b^t * (Z ic p (modifies (p!k)) t * S ic p k t))" by auto + hence sub_nzero_q: "(\S- p d (\k. \t=0..(q-1). b^t * (Z ic p (modifies (p!k)) t * S ic p k t))) + = (\S- p d (\k. \t=0..q. b^t * (Z ic p (modifies (p!k)) t * S ic p k t)))" + by (auto simp: sum_ssub_nzero.simps q sub_nzero_conditions) + + have "issub (p!k) \ b ^ (Suc (q-1)) * ((Suc 0 - Z ic p (modifies (p ! k)) (Suc (q-1))) + * S ic p k (Suc (q-1))) = 0" for k using q halt S_def by auto + hence sum_equiv_zero: "issub (p!k) \ + (\t = 0..q-1. b ^ t * ((Suc 0 - Z ic p (modifies (p ! k)) t) * S ic p k t)) + = (\t = 0..Suc (q-1). b ^ t * ((Suc 0 - Z ic p (modifies (p ! k)) t) * S ic p k t))" for k + using sum.atLeast0_atMost_Suc[of "\t. b ^ t * ((Suc 0 - Z ic p (modifies (p ! k)) t) + * S ic p k t)" "q-1"] by auto + have "(if issub (p ! k) \ d = goes_to_alt (p ! k) then + \t = 0..q - Suc 0. b ^ t * ((Suc 0 - Z ic p (modifies (p ! k)) t) * S ic p k t) else 0) + = (if issub (p ! k) \ d = goes_to_alt (p ! k) then + \t = 0..q. b ^ t * ((Suc 0 - Z ic p (modifies (p ! k)) t) * S ic p k t) else 0)" for k + apply (cases "issub (p!k)") using sum_equiv_zero[of "k"] q by auto + hence sub_zero_q: "(\S0 p d (\k.\t=0..q-1. b^t * ((1 - Z ic p (modifies(p!k)) t) * S ic p k t))) + = (\S0 p d (\k.\t=0..q. b^t * ((1 - Z ic p (modifies (p!k)) t) * S ic p k t)))" + using sum_ssub_zero.simps q by auto + + (* Start *) + have "s d = (\t = 0..q. b^t * S ic p d t)" using s_def SKe_def by auto + also have "... = S ic p d 0 + (\t = 1..q. b^t * S ic p d t)" + by (auto simp: q comm_monoid_add_class.sum.atLeast_Suc_atMost) + also have "... = (\t = 1..q. b^t * S ic p d t)" + using S_def `d>0` is_val is_valid_initial_def[of "ic" "p" "a"] by auto + also have "... = (\t \ (Suc ` {0..(q-1)}). b^t * S ic p d t)" using q by auto + also have "... = (sum ((\t. b^t * S ic p d t) \ Suc)) {0..(q-1)}" + using comm_monoid_add_class.sum.reindex[of "Suc" "{0..(q-1)}" "(\t. b^t * S ic p d t)"] by auto + also have "... = (\t = 0..(q-1). b^(Suc t) *((\S+ p d (\k. S ic p k t)) + + (\S- p d (\k. Z ic p (modifies (p!k)) t * S ic p k t)) + + (\S0 p d (\k. (1 - Z ic p (modifies (p!k)) t) * S ic p k t)) + + (if ishalt (p!(fst (steps ic p t))) \ d = fst (steps ic p t) + then Suc 0 else 0)))" + using single_step by auto + also have "... = (\t = 0..(q-1). b^(Suc t) *((\S+ p d (\k. S ic p k t)) + + (\S- p d (\k. Z ic p (modifies (p!k)) t * S ic p k t)) + + (\S0 p d (\k. (1 - Z ic p (modifies (p!k)) t) * S ic p k t))))" + using halt_term0 by auto + also have "... = (\t = 0..(q-1). (b^(Suc t) * (\S+ p d (\k. S ic p k t)) + + b^(Suc t) * (\S- p d (\k. Z ic p (modifies (p!k)) t * S ic p k t)) + + b^(Suc t) * (\S0 p d (\k. (1 - Z ic p (modifies (p!k)) t) * S ic p k t))))" + by (simp add: algebra_simps) + also have "... = (\t = 0..(q-1). (b^(Suc t) * (\S+ p d (\k. S ic p k t)))) + +(\t=0..(q-1). b^(Suc t)*(\S- p d (\k. Z ic p (modifies (p!k)) t * S ic p k t))) + +(\t=0..(q-1). b^(Suc t)*(\S0 p d (\k. (1 - Z ic p (modifies (p!k)) t) * S ic p k t)))" + by (auto simp only: sum.distrib) + also have "... = b * (\t = 0..(q-1). (b^t * (\S+ p d (\k. S ic p k t)))) + + b*(\t=0..(q-1). b^t*(\S- p d (\k. Z ic p (modifies (p!k)) t * S ic p k t))) + + b*(\t=0..(q-1). b^t*(\S0 p d (\k. (1 - Z ic p (modifies (p!k)) t) * S ic p k t)))" + by (auto simp: algebra_simps sum_distrib_left) + also have "... = b * (\t = 0..(q-1). (\S+ p d (\k. b^t * S ic p k t))) + + b*(\t=0..(q-1). (\S- p d (\k. b^t * (Z ic p (modifies (p!k)) t * S ic p k t)))) + + b*(\t=0..(q-1). (\S0 p d (\k. b^t * ((1 - Z ic p (modifies (p!k)) t) * S ic p k t))))" + using sum_sadd_distrib sum_ssub_nzero_distrib sum_ssub_zero_distrib by auto + also have "... = b * (\S+ p d (\k. \t = 0..(q-1). b^t * S ic p k t)) + + b*(\S- p d (\k. \t=0..(q-1). b^t * (Z ic p (modifies (p!k)) t * S ic p k t))) + + b*(\S0 p d (\k. \t=0..(q-1). b^t * ((1 - Z ic p (modifies (p!k)) t) * S ic p k t)))" + using sum_sadd_commutative sum_ssub_nzero_commutative sum_ssub_zero_commutative by auto + (* extend all sums until q *) + finally have eq1: "s d = b * (\S+ p d (\k. \t = 0..q. b^t * S ic p k t)) + + b*(\S- p d (\k. \t=0..q. b^t * (Z ic p (modifies (p!k)) t * S ic p k t))) + + b*(\S0 p d (\k. \t=0..q. b^t * ((1 - Z ic p (modifies (p!k)) t) * S ic p k t)))" + using add_q sub_nzero_q sub_zero_q by auto + also have "... = b * (\S+ p d (\k. s k)) + + b*(\S- p d (\k. \t=0..q. b^t * (Z ic p (modifies (p!k)) t * S ic p k t))) + + b*(\S0 p d (\k. \t=0..q. b^t * ((1 - Z ic p (modifies (p!k)) t) * S ic p k t)))" + using SKe_def s_def by auto + finally have "s d = b * (\S+ p d s) + + b*(\S- p d (\k. \t=0..q. b^t * (Z ic p (modifies (p!k)) t * S ic p k t))) + + b*(\S0 p d (\k. \t=0..q. b^t * ((1 - Z ic p (modifies (p!k)) t) * S ic p k t)))" + by auto + also have "... = b * (\S+ p d s) + + b*(\S- p d (\k. ZLe ic p b q (modifies (p!k)) && SKe ic p b q k)) + + b*(\S0 p d (\k. \t=0..q. b^t * ((1 - Z ic p (modifies (p!k)) t) * S ic p k t)))" + using mult_to_bitAND c_gt_cells b_def c by auto + finally have "s d = b * (\S+ p d s) + + b*(\S- p d (\k. ZLe ic p b q (modifies (p!k)) && SKe ic p b q k)) + + b*(\S0 p d (\k. (e - ZLe ic p b q (modifies (p!k))) && SKe ic p b q k))" + using mult_to_bitAND_state c_gt_cells b_def c e_def by auto + thus ?thesis using s_def z_def by auto +qed + +lemma lm04_25_multiple_step_state1: +fixes c :: nat + and l :: register + and ic :: configuration + and p :: program + and q :: nat + and a :: nat + + defines "b == B c" + and "m == length p" + +assumes is_val: "is_valid_initial ic p a" +assumes c_gt_cells: "cells_bounded ic p c" +assumes d: "d=0" + and q: "q > 0" + +assumes terminate: "terminates ic p q" + +assumes c: "c > 1" + + defines "r \ RLe ic p b q" + and "z \ ZLe ic p b q" + and "s \ SKe ic p b q" + and "e \ \t = 0..q. b^t" + +shows "s d = 1 + b * (\S+ p d s) + + b * (\S- p d (\k. z (modifies (p!k)) && s k)) + + b * (\S0 p d (\k. (e - z (modifies (p!k))) && s k))" +proof - + have "program_includes_halt p" + using is_val is_valid_initial_def[of "ic" "p" "a"] is_valid_def[of "ic" "p"] by auto + hence "p \ []" by auto + have "\ ishalt (p!d)" using d m_def `program_includes_halt p` by auto + hence "(if ishalt (p ! fst (steps ic p t)) \ d = fst (steps ic p t) then Suc 0 else 0) = 0" for t + by auto + hence single_step: "\t. S ic p d (Suc t) = (\S+ p d (\k. S ic p k t)) + + (\S- p d (\k. Z ic p (modifies (p!k)) t * S ic p k t)) + + (\S0 p d (\k. (1 - Z ic p (modifies (p!k)) t) * S ic p k t))" + using lm04_07_one_step_relation_state[of "ic" "p" "a" "d"] is_val d `p \ []` by (simp add: m_def) + + have b: "b > 0" using b_def B_def by auto + have halt: "ishalt (p!fst(steps ic p q))" using terminate terminates_def correct_halt_def by auto + have add_conditions: "(if isadd (p ! k) \ d = goes_to (p ! k) + then (\t = 0..q - Suc 0. b ^ t * S ic p k t) + b ^ q * S ic p k q else 0) + = (if isadd (p ! k) \ d = goes_to (p ! k) + then \t = 0..q - Suc 0. b ^ t * S ic p k t else 0)" for k + apply (cases "p!k"; cases "d = goes_to (p!k)") using q S_def b halt by auto + have "b * b ^ (q - Suc 0) = b ^ (q - Suc 0 + Suc 0)" using q + by (simp add: power_eq_if) + have "(\k. (\t = 0..(q-1). b^t * S ic p k t) + b^(Suc (q-1)) * S ic p k (Suc (q-1))) + = (\k. (\t = 0..(Suc (q-1)). b^t * S ic p k t))" by auto + hence "\S+ p d (\k. (\t = 0..(q-1). b^t * S ic p k t) + b^q * S ic p k (Suc (q-1))) + = \S+ p d (\k. \t = 0..(Suc (q-1)). b^t * S ic p k t)" using q + by auto + hence add_q: "\S+ p d (\k. \t = 0..(q-1). b^t * S ic p k t) + = \S+ p d (\k. \t = 0..q. b^t * S ic p k t)" + by (auto simp add: sum_sadd.simps q add_conditions) + + have "issub (p!k) \ b ^ (Suc (q-1)) * (Z ic p (modifies (p ! k)) (Suc (q-1)) * + (if fst (steps ic p (Suc (q-1))) = k then Suc 0 else 0)) = 0" for k + by (auto simp: q halt) + hence sum_equiv_nzero: "issub (p!k) \ + (\t = 0..q-1. b ^ t * (Z ic p (modifies (p ! k)) t * + (if fst (steps ic p t) = k then Suc 0 else 0))) + = (\t = 0..(Suc (q-1)). b ^ t * (Z ic p (modifies (p ! k)) t * + (if fst (steps ic p t) = k then Suc 0 else 0)))" for k + using sum.atLeast0_atMost_Suc[of "\t. b ^ t * (Z ic p (modifies (p ! k)) t + * (if fst (steps ic p t) = k then Suc 0 else 0))" "q-1"] by auto + hence sub_nzero_conditions: "(if issub (p ! k) \ d = goes_to (p ! k) then + \t = 0..q - Suc 0. b ^ t * (Z ic p (modifies (p ! k)) t * S ic p k t) else 0) + = (if issub (p ! k) \ d = goes_to (p ! k) then + \t = 0..q. b ^ t * (Z ic p (modifies (p ! k)) t * S ic p k t) else 0)" for k + apply (cases "issub (p!k)") using q S_def halt b by auto + have "(\k. (\t=0..(q-1). b^t * (Z ic p (modifies (p!k)) t * S ic p k t)) + + b^(Suc (q-1)) * (Z ic p (modifies (p!k)) (Suc (q-1)) * S ic p k (Suc (q-1)))) + = (\k. \t=0..(Suc (q-1)). b^t * (Z ic p (modifies (p!k)) t * S ic p k t))" by auto + hence sub_nzero_q: "(\S- p d (\k. \t=0..(q-1). b^t * (Z ic p (modifies (p!k)) t * S ic p k t))) + = (\S- p d (\k. \t=0..q. b^t * (Z ic p (modifies (p!k)) t * S ic p k t)))" + by (auto simp: sum_ssub_nzero.simps q sub_nzero_conditions) + + have "issub (p!k) \ b ^ (Suc (q-1)) * ((Suc 0 - Z ic p (modifies (p ! k)) (Suc (q-1))) + * S ic p k (Suc (q-1))) = 0" for k using q halt S_def by auto + hence sum_equiv_zero: "issub (p!k) \ + (\t = 0..q-1. b ^ t * ((Suc 0 - Z ic p (modifies (p ! k)) t) * S ic p k t)) + = (\t = 0..Suc (q-1). b ^ t * ((Suc 0 - Z ic p (modifies (p ! k)) t) * S ic p k t))" for k + using sum.atLeast0_atMost_Suc[of "\t. b ^ t * ((Suc 0 - Z ic p (modifies (p ! k)) t) + * S ic p k t)" "q-1"] by auto + have "(if issub (p ! k) \ d = goes_to_alt (p ! k) then + \t = 0..q - Suc 0. b ^ t * ((Suc 0 - Z ic p (modifies (p ! k)) t) * S ic p k t) else 0) + = (if issub (p ! k) \ d = goes_to_alt (p ! k) then + \t = 0..q. b ^ t * ((Suc 0 - Z ic p (modifies (p ! k)) t) * S ic p k t) else 0)" for k + apply (cases "issub (p!k)") using sum_equiv_zero[of "k"] q by auto + hence sub_zero_q: "(\S0 p d (\k.\t=0..q-1. b^t * ((1 - Z ic p (modifies(p!k)) t) * S ic p k t))) + = (\S0 p d (\k.\t=0..q. b^t * ((1 - Z ic p (modifies (p!k)) t) * S ic p k t)))" + using sum_ssub_zero.simps q by auto + + have S0: "S ic p d 0 = 1" using S_def is_val is_valid_initial_def[of "ic" "p" "a"] d by auto + + (* Start *) + have "s d = (\t = 0..q. b^t * S ic p d t)" using s_def SKe_def by auto + also have "... = S ic p d 0 + (\t = 1..q. b^t * S ic p d t)" + by (auto simp: q comm_monoid_add_class.sum.atLeast_Suc_atMost) + also have "... = b^0 * S ic p d 0 + (\t = 1..q. b^t * S ic p d t)" + using S_def is_val is_valid_initial_def[of "ic" "p" "a"] by auto + also have "... = 1 + (\t \ (Suc ` {0..(q-1)}). b^t * S ic p d t)" using q S0 by auto + also have "... = 1 + (sum ((\t. b^t * S ic p d t) \ Suc)) {0..(q-1)}" + using comm_monoid_add_class.sum.reindex[of "Suc" "{0..(q-1)}" "(\t. b^t * S ic p d t)"] by auto + also have "... = 1 + (\t = 0..(q-1). b^(Suc t) *((\S+ p d (\k. S ic p k t)) + + (\S- p d (\k. Z ic p (modifies (p!k)) t * S ic p k t)) + + (\S0 p d (\k. (1 - Z ic p (modifies (p!k)) t) * S ic p k t))))" + using single_step by auto + also have "... = 1 + (\t = 0..(q-1). (b^(Suc t) * (\S+ p d (\k. S ic p k t)) + + b^(Suc t) * (\S- p d (\k. Z ic p (modifies (p!k)) t * S ic p k t)) + + b^(Suc t) * (\S0 p d (\k. (1 - Z ic p (modifies (p!k)) t) * S ic p k t))))" + by (simp add: algebra_simps) + also have "... = 1 + (\t = 0..(q-1). (b^(Suc t) * (\S+ p d (\k. S ic p k t)))) + +(\t=0..(q-1). b^(Suc t)*(\S- p d (\k. Z ic p (modifies (p!k)) t * S ic p k t))) + +(\t=0..(q-1). b^(Suc t)*(\S0 p d (\k. (1 - Z ic p (modifies (p!k)) t) * S ic p k t)))" + by (auto simp only: sum.distrib) + also have "... = 1 + b * (\t = 0..(q-1). (b^t * (\S+ p d (\k. S ic p k t)))) + + b*(\t=0..(q-1). b^t*(\S- p d (\k. Z ic p (modifies (p!k)) t * S ic p k t))) + + b*(\t=0..(q-1). b^t*(\S0 p d (\k. (1 - Z ic p (modifies (p!k)) t) * S ic p k t)))" + by (auto simp: algebra_simps sum_distrib_left) + also have "... = 1 + b * (\t = 0..(q-1). (\S+ p d (\k. b^t * S ic p k t))) + + b*(\t=0..(q-1). (\S- p d (\k. b^t * (Z ic p (modifies (p!k)) t * S ic p k t)))) + + b*(\t=0..(q-1). (\S0 p d (\k. b^t * ((1 - Z ic p (modifies (p!k)) t) * S ic p k t))))" + using sum_sadd_distrib sum_ssub_nzero_distrib sum_ssub_zero_distrib by auto + also have "... = 1 + b * (\S+ p d (\k. \t = 0..(q-1). b^t * S ic p k t)) + + b*(\S- p d (\k. \t=0..(q-1). b^t * (Z ic p (modifies (p!k)) t * S ic p k t))) + + b*(\S0 p d (\k. \t=0..(q-1). b^t * ((1 - Z ic p (modifies (p!k)) t) * S ic p k t)))" + using sum_sadd_commutative sum_ssub_nzero_commutative sum_ssub_zero_commutative by auto + (* extend all sums until q *) + finally have eq1: "s d = 1 + b * (\S+ p d (\k. \t = 0..q. b^t * S ic p k t)) + + b*(\S- p d (\k. \t=0..q. b^t * (Z ic p (modifies (p!k)) t * S ic p k t))) + + b*(\S0 p d (\k. \t=0..q. b^t * ((1 - Z ic p (modifies (p!k)) t) * S ic p k t)))" + using add_q sub_nzero_q sub_zero_q by auto + also have "... = 1 + b * (\S+ p d (\k. s k)) + + b*(\S- p d (\k. \t=0..q. b^t * (Z ic p (modifies (p!k)) t * S ic p k t))) + + b*(\S0 p d (\k. \t=0..q. b^t * ((1 - Z ic p (modifies (p!k)) t) * S ic p k t)))" + using SKe_def s_def by auto + finally have "s d = 1 + b * (\S+ p d s) + + b*(\S- p d (\k. \t=0..q. b^t * (Z ic p (modifies (p!k)) t * S ic p k t))) + + b*(\S0 p d (\k. \t=0..q. b^t * ((1 - Z ic p (modifies (p!k)) t) * S ic p k t)))" + by auto + also have "... = 1 + b * (\S+ p d s) + + b*(\S- p d (\k. ZLe ic p b q (modifies (p!k)) && SKe ic p b q k)) + + b*(\S0 p d (\k. \t=0..q. b^t * ((1 - Z ic p (modifies (p!k)) t) * S ic p k t)))" + using mult_to_bitAND c_gt_cells b_def c by auto + finally have "s d = 1 + b * (\S+ p d s) + + b*(\S- p d (\k. ZLe ic p b q (modifies (p!k)) && SKe ic p b q k)) + + b*(\S0 p d (\k. (e - ZLe ic p b q (modifies (p!k))) && SKe ic p b q k))" + using mult_to_bitAND_state c_gt_cells b_def c e_def by auto + thus ?thesis using s_def z_def by auto +qed + +lemma halting_condition_04_27: +fixes c :: nat + and l :: register + and ic :: configuration + and p :: program + and q :: nat + and a :: nat + +defines "b == B c" + and "m == length p - 1" + +assumes is_val: "is_valid_initial ic p a" + and q: "q > 0" + +assumes terminate: "terminates ic p q" + +shows "SKe ic p b q m = b ^ q" +proof - + have halt: "ishalt (p ! (fst (steps ic p q)))" + using terminate terminates_def correct_halt_def by auto + have "\k ishalt (p!k)" using is_val is_valid_initial_def[of "ic" "p" "a"] + is_valid_def[of "ic" "p"] program_includes_halt.simps by blast + hence "ishalt (p!k) \ k \ length p - 1" for k using not_le_imp_less by auto + hence gt: "fst (steps ic p q) \ m" using halt m_def by auto + have "fst (steps ic p q) \ m" + using p_contains[of "ic" "p" "a" "q"] is_val m_def by auto + hence q_steps_m: "fst (steps ic p q) = m" using gt by auto + hence 1: "S ic p m q = 1" using S_def by auto + + have "ishalt (p!m)" using q_steps_m halt by auto + have "\t ishalt (p ! (fst (steps ic p t)))" using terminate terminates_def by auto + hence "\t (fst (steps ic p t) = m)" using `ishalt (p!m)` by auto + hence 0: "t \ q-1 \ S ic p m t = 0" for t using q S_def[of "ic" "p" "m" "t"] by auto + + have "SKe ic p b q m = (\t = 0..(Suc (q-1)). b ^ t * S ic p m t)" by (auto simp: q SKe_def) + also have "... = (\t = 0..(q-1). b^t * S ic p m t) + b ^ (Suc (q-1)) * S ic p m (Suc (q-1))" + by auto + also have "... = b ^ q" using 0 1 q by auto + finally show ?thesis by auto +qed + +lemma state_q_bound: +fixes c :: nat + and l :: register + and ic :: configuration + and p :: program + and q :: nat + and a :: nat + +defines "b == B c" + and "m == length p - 1" + +assumes is_val: "is_valid_initial ic p a" + and q: "q > 0" + and terminate: "terminates ic p q" + and c: "c > 0" + +assumes "k1" using B_def apply auto + by (metis One_nat_def one_less_numeral_iff power_gt1_lemma semiring_norm(76)) + hence b: "b > 2" using c b_def B_def + by (smt One_nat_def Suc_le_lessD less_Suc_eq_le less_trans_Suc linorder_neqE_nat + numeral_2_eq_2 power_Suc0_right power_inject_exp) + from \k have "\ ishalt (p!k)" using is_val + by (simp add: is_valid_def is_valid_initial_def is_val m_def) + hence "S ic p k q = 0" using terminate terminates_def correct_halt_def S_def by auto + hence "SKe ic p b q k = (\t = 0..q-1. b ^ t * S ic p k t)" + using \q>0\ apply (auto cong: sum.cong simp: SKe_def) by (metis (no_types, lifting) Suc_pred + add_cancel_right_right mult_0_right sum.atLeast0_atMost_Suc) + also have "... \ (\t = 0..q-1. b^t)" by (auto simp add: S_def gr_implies_not0 sum_mono) + also have "... < b ^ q" + using `q>0` sum_bt + by (metis Suc_diff_1 b) + + finally show ?thesis by auto +qed + +end diff --git a/thys/DPRM_Theorem/Register_Machine/MultipleToSingleSteps.thy b/thys/DPRM_Theorem/Register_Machine/MultipleToSingleSteps.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Register_Machine/MultipleToSingleSteps.thy @@ -0,0 +1,1148 @@ +subsection \From multiple to single step relations\ + +theory MultipleToSingleSteps + imports MachineEquations CommutationRelations "../Diophantine/Binary_And" +begin + +text \This file contains lemmas that are needed to prove the <-- direction of conclusion4.5 in the +file MachineEquationEquivalence. In particular, it is shown that single step equations follow +from the multiple step relations. The key idea of Matiyasevich's proof is to code all register +and state values over the time into one large number. A further central statement in this file +shows that the decoding of these numbers back to the single cell contents is indeed correct.\ + +context + fixes a :: nat + and ic:: configuration + and p :: program + and q :: nat + and r z :: "register \ nat" + and s :: "state \ nat" + and b c d e f :: nat + and m n :: nat + and Req Seq Zeq (* These variables are to store the single cell entries obtained from the + rows r s and z in the protocol *) + + assumes m_def: "m \ length p - 1" + and n_def: "n \ length (snd ic)" + + assumes is_val: "is_valid_initial ic p a" + + (* rm_equations *) + assumes m_eq: "mask_equations n r z c d e f" + and r_eq: "reg_equations p r z s b a n q" + and s_eq: "state_equations p s z b e q m" + and c_eq: "rm_constants q c b d e f a" + + assumes Seq_def: "Seq = (\k t. nth_digit (s k) t b)" + and Req_def: "Req = (\l t. nth_digit (r l) t b)" + and Zeq_def: "Zeq = (\l t. nth_digit (z l) t b)" + +begin + +text \Basic properties\ +lemma n_gt0: "n>0" + using n_def is_val is_valid_initial_def[of "ic" "p" "a"] is_valid_def + by auto + +lemma f_def: "f = (\t = 0..q. 2^c * b^t)" + using c_eq by (simp add: rm_constants_def F_def) +lemma e_def: "e = (\t = 0..q. b^t)" + using c_eq by (simp add: rm_constants_def E_def) +lemma d_def: "d = (\t = 0..q. (2^c - 1) * b^t)" + using c_eq by (simp add: D_def rm_constants_def) +lemma b_def: "b = 2^(Suc c)" + using c_eq by (simp add: B_def rm_constants_def) + +lemma b_gt1: "b > 1" using c_eq B_def rm_constants_def by auto + +lemma c_gt0: "c > 0" using rm_constants_def c_eq by auto +lemma h0: "1 < (2::nat)^c" + using c_gt0 one_less_numeral_iff one_less_power semiring_norm(76) by blast +(* this even implies b > 2, in fact b \ 4 *) + +lemma rl_fst_digit_zero: + assumes "l < n" + shows "nth_digit (r l) t b \ c = 0" +proof - + have "2 ^ c - (Suc 0) < 2 ^ Suc c" using c_gt0 by (simp add: less_imp_diff_less) + hence "\t. nth_digit d t b = (if t\q then 2^c - 1 else 0)" + using nth_digit_gen_power_series[of "\x. 2^c - 1" "c"] d_def c_gt0 b_def + by (simp add: d_def) + then have d_lead_digit_zero: "\t. (nth_digit d t b) \ c = 0" + by (auto simp: nth_bit_def) + + from m_eq have "(r l) \ d" + by (simp add: mask_equations_def assms) + then have "\k. (r l) \ k \ d \ k" + by (auto simp: masks_leq_equiv) + then have "\t. (nth_digit (r l) t b \ c) \ (nth_digit d t b \ c)" + using digit_gen_pow2_reduct[where ?c = "Suc c"] by (auto simp: b_def) + thus ?thesis + by (auto simp: d_lead_digit_zero) +qed + +lemma e_mask_bound: + assumes "x \ e" + shows "nth_digit x t b \ 1" +proof - + have x_bounded: "nth_digit x t' b \ nth_digit e t' b" for t' + proof - + have "\t'. x \ t' \ e \ t'" using assms masks_leq_equiv by auto + then have k_lt_c: "\t'. \k' k' + \ nth_digit e t' b \ k'" + using digit_gen_pow2_reduct by (auto simp: b_def) (metis power_Suc) + + have "k\Suc c \ x mod (2 ^ Suc c) div 2 ^ k = 0" for k x::nat + by (metis Euclidean_Division.div_eq_0_iff One_nat_def Suc_le_lessD b_gt1 b_def less_le_trans + mod_less_divisor nat_power_less_imp_less not_less not_less0 not_less_eq_eq + numeral_2_eq_2 zero_less_Suc) + then have "\k\Suc c. nth_digit x y b \ k = 0" for x y + using b_def nth_bit_def nth_digit_def by auto + then have k_gt_c: "\t'. \k'\Suc c. nth_digit x t' b \ k' + \ nth_digit e t' b \ k'" + by auto + + from k_lt_c k_gt_c have "nth_digit x t' b \ nth_digit e t' b" for t' + using bitwise_leq by (meson not_le) + thus ?thesis by auto + qed + + have "\k. Suc 0 < 2^c" using c_gt0 h0 by auto + hence e_aux: "nth_digit e tt b \ 1" for tt + using e_def b_def c_gt0 nth_digit_gen_power_series[of "\k. Suc 0" "c" "q"] by auto + + show ?thesis using e_aux[of "t"] x_bounded[of "t"] using le_trans by blast +qed + +(* --- individual bounds --- *) +lemma sk_bound: + shows "\t k. k\length p - 1 \ nth_digit (s k) t b \ 1" +proof - + have "\k\length p - 1. s k \ e" using s_eq state_equations_def m_def by auto + thus ?thesis using e_mask_bound by auto +qed + +lemma sk_bitAND_bound: + shows "\t k. k\length p - 1 \ nth_digit (s k && x k) t b \ 1" + using bitAND_nth_digit_commute sk_bound bitAND_lt masks_leq + by (auto simp: b_def) (meson dual_order.trans) + +lemma s_bound: + shows "\jM\m. (\k\M. s k) \ e" + using s_eq state_equations_def by auto + +lemma sk_sum_bound: + shows "\t M. M\length p - 1 \ nth_digit (\k\M. s k) t b \ 1" + using sk_sum_masked e_mask_bound m_def by auto + +lemma sum_sk_bound: + shows "(\k\length p - 1. nth_digit (s k) t b) \ 1" +proof - + have "\t m. m \ length p - 1 \ nth_digit (sum s {0..m}) t b < 2 ^ c" + using sk_sum_bound b_def c_gt0 h0 + by (metis atLeast0AtMost le_less_trans) + moreover have "\t k. k \ length p - 1 \ nth_digit (s k) t b < 2 ^ c" + using sk_bound b_def c_gt0 h0 + by (metis le_less_trans) + + ultimately have "nth_digit (\k\length p - 1. s k) t b + = (\k\length p - 1. nth_digit (s k) t b)" + using b_def c_gt0 + using finite_sum_nth_digit_commute2[where ?M = "length p - 1"] + by (simp add: atMost_atLeast0) + + thus ?thesis using sk_sum_bound by (metis order_refl) +qed + +lemma bitAND_sum_lt: "(\k\length p - 1. nth_digit (s k && x k) t b) + \ (\k\length p - 1. Seq k t)" +proof - + have "(\k\length p - 1. nth_digit (s k && x k) t b) + = (\k\length p - 1. nth_digit (s k) t b && nth_digit (x k) t b)" + using bitAND_nth_digit_commute b_def by auto + also have "... \ (\k\length p - 1. nth_digit (s k) t b)" + using bitAND_lt by (simp add: sum_mono) + finally show ?thesis using Seq_def by auto +qed + + +lemma states_unique_RAW: + "\k\m. Seq k t = 1 \ (\j\m. j \ k \ Seq j t = 0)" +proof - + { + fix k + assume "k\m" + assume skt_1: "Seq k t = 1" + + have "\j\m. j \ k \ Seq j t = 0" + proof - + { + fix j + assume "j\m" + assume "j \ k" + let ?fct = "(\k. Seq k t)" + + have "Seq j t = 0" + proof (rule ccontr) + assume "Seq j t \ 0" + then have "Seq j t + Seq k t > 1" + using skt_1 by auto + moreover have "sum ?fct {0..m} \ sum ?fct {j, k}" + using `j\m` `k\m` sum_mono2 + by (metis atLeastAtMost_iff empty_subsetI finite_atLeastAtMost insert_subset le0) + ultimately have "(\k\m. Seq k t) > 1" + by (simp add: \j \ k\ atLeast0AtMost) + thus "False" + using sum_sk_bound[where ?t = t] + by (auto simp: Seq_def m_def) + qed + } + thus ?thesis by auto + qed + } + thus ?thesis by auto +qed + +lemma block_sum_radd_bound: + shows "\t. (\R+ p l (\k. nth_digit (s k) t b)) \ 1" +proof - + { + fix t + have "(\R+ p l (\k. Seq k t)) \ (\k\length p - 1. Seq k t)" + unfolding sum_radd.simps + by (simp add: atMost_atLeast0 sum_mono) + hence "(\R+ p l (\k. Seq k t)) \ 1" + using sum_sk_bound[of t] Seq_def + using dual_order.trans by blast + } + thus ?thesis using Seq_def by auto +qed + +lemma block_sum_rsub_bound: + shows "\t. (\R- p l (\k. nth_digit (s k && z l) t b)) \ 1" +proof - + { + fix t + have "(\R- p l (\k. nth_digit (s k && z l) t b)) + \ (\k\length p - 1. nth_digit (s k && z l) t b)" + unfolding sum_rsub.simps + by (simp add: atMost_atLeast0 sum_mono) + also have "... \ (\k\length p - 1. Seq k t)" + using bitAND_sum_lt[where ?x = "\k. z l"] by blast + finally have "(\R- p l (\k. nth_digit (s k && z l) t b)) \ 1" + using sum_sk_bound[of t] Seq_def + using dual_order.trans by blast + } + thus ?thesis using Seq_def by auto +qed + +lemma block_sum_rsub_special_bound: + shows "\t. (\R- p l (\k. nth_digit (s k) t b)) \ 1" +proof - + { + fix t + have "(\R- p l (\k. nth_digit (s k) t b)) + \ (\k\length p - 1. nth_digit (s k) t b)" + unfolding sum_rsub.simps + by (simp add: atMost_atLeast0 sum_mono) + then have "(\R- p l (\k. nth_digit (s k) t b)) \ 1" + using sum_sk_bound[of t] + using dual_order.trans by blast + } + thus ?thesis using Seq_def by auto +qed + +lemma block_sum_sadd_bound: + shows "\t. (\S+ p j (\k. nth_digit (s k) t b)) \ 1" +proof - + { + fix t + have "(\S+ p j (\k. Seq k t)) \ (\k\length p - 1. Seq k t)" + unfolding sum_sadd.simps + by (simp add: atMost_atLeast0 sum_mono) + hence "(\S+ p j (\k. Seq k t)) \ 1" + using sum_sk_bound[of t] Seq_def + using dual_order.trans by blast + } + thus ?thesis using Seq_def by auto +qed + +lemma block_sum_ssub_bound: + shows "\t. (\S- p j (\k. nth_digit (s k && z (l k)) t b)) \ 1" +proof - + { + fix t + have "(\S- p j (\k. nth_digit (s k && z (l k)) t b)) + \ (\k\length p - 1. nth_digit (s k && z (l k)) t b)" + unfolding sum_ssub_nzero.simps + by (simp add: atMost_atLeast0 sum_mono) + also have "... \ (\k\length p - 1. Seq k t)" + using bitAND_sum_lt[where ?x = "\k. z (l k)"] by blast + finally have "(\S- p j (\k. nth_digit (s k && z (l k)) t b)) \ 1" + using sum_sk_bound[of t] Seq_def + using dual_order.trans by blast + } + thus ?thesis using Seq_def by auto +qed + +lemma block_sum_szero_bound: + shows "\t. (\S0 p j (\k. nth_digit (s k && (e - z (l k))) t b)) \ 1" +proof - + { + fix t + have "(\S0 p j (\k. nth_digit (s k && e - z (l k)) t b)) + \ (\k\length p - 1. nth_digit (s k && e - z (l k)) t b)" + unfolding sum_ssub_zero.simps + by (simp add: atMost_atLeast0 sum_mono) + also have "... \ (\k\length p - 1. Seq k t)" + using bitAND_sum_lt[where ?x = "\k. e - z (l k)"] by blast + finally have "(\S0 p j (\k. nth_digit (s k && e - z (l k)) t b)) \ 1" + using sum_sk_bound[of t] Seq_def + using dual_order.trans by blast + } + thus ?thesis using Seq_def by auto +qed + +lemma sum_radd_nth_digit_commute: + shows "nth_digit (\R+ p l (\k. s k)) t b = \R+ p l (\k. nth_digit (s k) t b)" +proof - + have a1: "\t. \k\length p - 1. nth_digit (s k) t b < 2^c" + using sk_bound h0 by (meson le_less_trans) + + have a2: "\t. (\R+ p l (\k. nth_digit (s k) t b)) < 2^c" + using block_sum_radd_bound h0 by (meson le_less_trans) + + show ?thesis + using a1 a2 c_gt0 b_def unfolding sum_radd.simps + using sum_nth_digit_commute[where ?g = "\l k. isadd (p ! k) \ l = modifies (p ! k)"] + by blast +qed + +lemma sum_rsub_nth_digit_commute: + shows "nth_digit (\R- p l (\k. s k && z l)) t b + = \R- p l (\k. nth_digit (s k && z l) t b)" +proof - + have a1: "\t. \k\length p - 1. nth_digit (s k && z l) t b < 2^c" + using sk_bitAND_bound[where ?x = "\k. z l"] h0 le_less_trans by blast + + have a2: "\t. (\R- p l (\k. nth_digit (s k && z l) t b)) < 2^c" + using block_sum_rsub_bound h0 by (meson le_less_trans) + + show ?thesis + using a1 a2 c_gt0 b_def unfolding sum_rsub.simps + using sum_nth_digit_commute + [where ?g = "\l k. issub (p ! k) \ l = modifies (p ! k)" and ?fct = "\k. s k && z l"] + by blast +qed + +lemma sum_sadd_nth_digit_commute: + shows "nth_digit (\S+ p j (\k. s k)) t b = \S+ p j (\k. nth_digit (s k) t b)" +proof - + have a1: "\t. \k\length p - 1. nth_digit (s k) t b < 2^c" + using sk_bound h0 by (meson le_less_trans) + + have a2: "\t. (\S+ p j (\k. nth_digit (s k) t b)) < 2^c" + using block_sum_sadd_bound h0 by (meson le_less_trans) + + show ?thesis + using a1 a2 b_def c_gt0 unfolding sum_sadd.simps + using sum_nth_digit_commute[where ?g = "\j k. isadd (p ! k) \ j = goes_to (p ! k)"] + by blast +qed + +lemma sum_ssub_nth_digit_commute: + shows "nth_digit (\S- p j (\k. s k && z (l k))) t b + = \S- p j (\k. nth_digit (s k && z (l k)) t b)" +proof - + have a1: "\t. \k\length p - 1. nth_digit (s k && z (l k)) t b < 2^c" + using sk_bitAND_bound[where ?x = "\k. z (l k)"] h0 le_less_trans by blast + + have a2: "\t. (\S- p j (\k. nth_digit (s k && z (l k)) t b)) < 2^c" + using block_sum_ssub_bound h0 by (meson le_less_trans) + + show ?thesis + using a1 a2 b_def c_gt0 unfolding sum_ssub_nzero.simps + using sum_nth_digit_commute + [where ?g = "\j k. issub (p ! k) \ j = goes_to (p ! k)" and ?fct = "\k. s k && z (l k)"] + by blast +qed + +lemma sum_szero_nth_digit_commute: + shows "nth_digit (\S0 p j (\k. s k && (e - z (l k)))) t b + = \S0 p j (\k. nth_digit (s k && (e - z (l k))) t b)" +proof - + have a1: "\t. \k\length p - 1. nth_digit (s k && (e - z (l k))) t b < 2^c" + using sk_bitAND_bound[where ?x = "\k. e - z (l k)"] h0 le_less_trans by blast + + have a2: "\t. (\S0 p j (\k. nth_digit (s k && (e - z (l k))) t b)) < 2^c" + using block_sum_szero_bound h0 by (meson le_less_trans) + + show ?thesis + using a1 a2 b_def c_gt0 unfolding sum_ssub_zero.simps + using sum_nth_digit_commute + [where ?g = "\j k. issub (p ! k) \ j = goes_to_alt (p ! k)" and ?fct = "\k. s k && e - z (l k)"] + by blast +qed + +lemma block_bound_impl_fst_digit_zero: + assumes "nth_digit x t b \ 1" + shows "(nth_digit x t b) \ c = 0" + using assms apply (auto simp: nth_bit_def) + by (metis (no_types, opaque_lifting) c_gt0 div_le_dividend le_0_eq le_Suc_eq mod_0 mod_Suc + mod_div_trivial numeral_2_eq_2 power_eq_0_iff power_mod) + +lemma sum_radd_block_bound: + shows "nth_digit (\R+ p l (\k. s k)) t b \ 1" + using block_sum_radd_bound sum_radd_nth_digit_commute by auto +lemma sum_radd_fst_digit_zero: + shows "(nth_digit (\R+ p l s) t b) \ c = 0" + using sum_radd_block_bound block_bound_impl_fst_digit_zero by auto + +lemma sum_sadd_block_bound: + shows "nth_digit (\S+ p j (\k. s k)) t b \ 1" + using block_sum_sadd_bound sum_sadd_nth_digit_commute by auto +lemma sum_sadd_fst_digit_zero: + shows "(nth_digit (\S+ p j s) t b) \ c = 0" + using sum_sadd_block_bound block_bound_impl_fst_digit_zero by auto + +lemma sum_ssub_block_bound: + shows "nth_digit (\S- p j (\k. s k && z (l k))) t b \ 1" + using block_sum_ssub_bound sum_ssub_nth_digit_commute by auto +lemma sum_ssub_fst_digit_zero: + shows "(nth_digit (\S- p j (\k. s k && z (l k))) t b) \ c = 0" + using sum_ssub_block_bound block_bound_impl_fst_digit_zero by auto + +lemma sum_szero_block_bound: + shows "nth_digit (\S0 p j (\k. s k && (e - z (l k)))) t b \ 1" + using block_sum_szero_bound sum_szero_nth_digit_commute by auto +lemma sum_szero_fst_digit_zero: + shows "(nth_digit (\S0 p j (\k. s k && (e - z (l k)))) t b) \ c = 0" + using sum_szero_block_bound block_bound_impl_fst_digit_zero by auto + +lemma sum_rsub_special_block_bound: + shows "nth_digit (\R- p l (\k. s k)) t b \ 1" +proof - + have a1: "\t k. k \ length p - 1 \ nth_digit (s k) t b < 2^c" + using sk_bound h0 le_less_trans by blast + have a2: "\t. \R- p l (\k. nth_digit (s k) t b) < 2^c" + using block_sum_rsub_special_bound h0 le_less_trans by blast + + have "nth_digit (\R- p l (\k. s k)) t b = \R- p l (\k. nth_digit (s k) t b)" + using a1 a2 b_def c_gt0 unfolding sum_rsub.simps + using sum_nth_digit_commute[where ?g = "\l k. issub (p ! k) \ l = modifies (p ! k)"] + by blast + + thus ?thesis + using block_sum_rsub_special_bound by auto +qed + +lemma sum_state_special_block_bound: + shows "nth_digit (\S+ p j (\k. s k) + + \S0 p j (\k. s k && (e - z (l k)))) t b \ 1" +proof - + have aux_sum_zero: + "\S0 p j (\k. nth_digit (s k) t b && nth_digit (e - z (l k)) t b) + \ \S0 p j (\k. nth_digit (s k) t b)" + unfolding sum_ssub_zero.simps + by (auto simp: bitAND_lt sum_mono) + + have aux_addsub_excl: "(if isadd (p ! k) then Seq k t else 0) + + (if issub (p ! k) then Seq k t else 0) + = (if isadd (p ! k) \ issub (p ! k) then Seq k t else 0)" for k + by auto + + have aux_sum_add_lt: + "\S+ p j (\k. Seq k t) \ (\k = 0..length p - 1. if isadd (p ! k) then Seq k t else 0)" + unfolding sum_sadd.simps by (simp add: sum_mono) + have aux_sum_sub_lt: + "\S0 p j (\k. Seq k t) \ (\k = 0..length p - 1. if issub (p ! k) then Seq k t else 0)" + unfolding sum_ssub_zero.simps by (simp add: sum_mono) + + have "nth_digit (\S+ p j (\k. s k) + + \S0 p j (\k. s k && e - z (l k))) t b + = nth_digit (\S+ p j (\k. s k)) t b + + nth_digit (\S0 p j (\k. s k && e - z (l k))) t b" + using sum_sadd_fst_digit_zero sum_szero_fst_digit_zero block_additivity + by (auto simp: c_gt0 b_def) + also have "... = \S+ p j (\k. nth_digit (s k) t b) + + \S0 p j (\k. nth_digit (s k && e - z (l k)) t b)" + by (simp add: sum_sadd_nth_digit_commute sum_szero_nth_digit_commute) + also have "... \ \S+ p j (\k. Seq k t) + \S0 p j (\k. Seq k t)" + using bitAND_nth_digit_commute aux_sum_zero + unfolding Seq_def by (simp add: b_def) + also have "... \ (\k = 0..length p - 1. if isadd (p ! k) then Seq k t else 0) + + (\k = 0..length p - 1. if issub (p ! k) then Seq k t else 0)" + using aux_sum_add_lt aux_sum_sub_lt by auto + also have "... = (\k\length p - 1. if (isadd (p ! k) \ issub (p ! k)) + then Seq k t else 0)" + using aux_addsub_excl + using sum.distrib[where ?g = "\k. if isadd (p ! k) then Seq k t else 0" + and ?h = "\k. if issub (p ! k) then Seq k t else 0"] + by (auto simp: aux_addsub_excl atMost_atLeast0) + also have "... \ (\k\length p - 1. Seq k t)" + by (smt eq_iff le0 sum_mono) + + finally show ?thesis using sum_sk_bound[of t] Seq_def by auto +qed +lemma sum_state_special_fst_digit_zero: + shows "(nth_digit (\S+ p j (\k. s k) + + \S0 p j (\k. s k && (e - z (modifies (p!k))))) t b) \ c = 0" + using sum_state_special_block_bound block_bound_impl_fst_digit_zero by auto + +text \Main three redution lemmas: Zero Indicators, Registers, States\ + +lemma Z: + assumes "l 0 then Suc 0 else 0)" +proof - + have cond: "2^c * (z l) = (r l + d) && f" using m_eq mask_equations_def assms by auto + have d_block: "\t\q. nth_digit d t b = 2^c - 1" using d_def b_def + less_imp_diff_less nth_digit_gen_power_series[of "\_. 2^c-1" "c"] c_gt0 by auto + have rl_bound: "t\q \ nth_digit (r l) t b \ c= 0" for t by (simp add: assms rl_fst_digit_zero) + have f_block: "\t\q. nth_digit f t b = 2^c" + using f_def b_def less_imp_diff_less nth_digit_gen_power_series[of "\_. 2^c" c] c_gt0 by auto + then have "\t\q.\k k = 0" by (simp add: aux_powertwo_digits) + + moreover have AND_gen: "\t\q.\k\c. nth_digit ((r l + d) && f) t b \ k = (nth_digit (r l + d) t b \ k) * nth_digit f t b \ k" + using b_def digit_gen_pow2_reduct bitAND_digit_mult digit_gen_pow2_reduct le_imp_less_Suc by presburger + ultimately have "\t\q.\k k = 0" using f_def by auto + moreover have "(r l + d) && f < b ^ Suc q" using lm0245[of "r l + d" f] masks_leq[of "(r l + d) && f" f] f_def + proof- + have "2 < b" using b_def c_gt0 gr0_conv_Suc not_less_iff_gr_or_eq by fastforce + then have "b^u + b^u < b* b^ u" for u using zero_less_power[of b u] mult_less_mono1[of 2 b "b^u"] by linarith + then have "(\t\{..t\{..q. b^q" "{..t\{.. f" using lm0245[of "r l + d" f] masks_leq[of "(r l + d) && f" f] by auto + ultimately show ?thesis by auto + qed + then have rldf0: "t>q \ nth_digit ((r l + d) && f) t b = 0" for t using nth_digit_def[of "r l + d && f" t b] + div_less[of "r l + d && f" "b^t"] b_def power_increasing[of "Suc q" t b] by auto + moreover have "\t>q.\k k = 0" using aux_lt_implies_mask rldf0 by fastforce + ultimately have AND_zero: "\t.\k k = 0" using leI by blast + + have "0 k< Suc c \ nth_digit (z l) t b \ k = nth_digit ((r l + d) && f) (Suc t) b \ (k - 1)" + for k using b_def nth_digit_bound digit_gen_pow2_reduct[of k "Suc c" "z l" t] aux_digit_shift[of "z l" c "t + c * t + k"] + digit_gen_pow2_reduct[of "k-1" "Suc c" "z l * 2^c" "Suc t"] cond by (simp add: add.commute add.left_commute mult.commute) + then have aux: "0 k< Suc c \ nth_digit (z l) t b \ k = 0" for k using AND_zero by auto + have zl_formula: "nth_digit (z l) t b = nth_digit (z l) t b \ 0 " + using b_def digit_sum_repr[of "nth_digit (z l) t b" "Suc c"] + proof - + have "nth_digit (z l) t b < 2 ^ Suc c + \ nth_digit (z l) t b = (\k\{0.. k * 2 ^ k)" + using b_def digit_sum_repr[of "nth_digit (z l) t b" "Suc c"] + by (simp add: atLeast0LessThan) + hence "nth_digit (z l) t b < 2 ^ Suc c + \ nth_digit (z l) t b = nth_digit (z l) t b \ 0 + + (\k\{0<.. k * 2 ^ k)" + by (metis One_nat_def atLeastSucLessThan_greaterThanLessThan mult_numeral_1_right + numeral_1_eq_Suc_0 power_0 sum.atLeast_Suc_lessThan zero_less_Suc) + thus ?thesis using aux nth_digit_bound b_def by auto + qed + + consider (tleq) "t\q" |(tgq) "t>q" by linarith + then show ?thesis + proof cases + case tleq + then have t_bound: "t \ q" by auto + have "nth_digit ((r l + d) && f) t b \ c = (nth_digit (r l + d) t b \ c)" + using f_block bitAND_single_digit AND_gen t_bound by auto + moreover have "nth_digit (r l + d && f) t b < 2 ^ Suc c" using nth_digit_def b_def by simp + ultimately have AND_all:"nth_digit ((r l + d) && f) t b = (nth_digit (r l + d) t b \ c) * 2^c" using AND_gen AND_zero + using digit_sum_repr[of "nth_digit ((r l + d) && f) t b" "Suc c"] by auto + + then have "\k k = 0" using cond AND_zero by metis + moreover have "nth_digit (2^c * (z l)) t b \ c = nth_digit (z l) t b \ 0" + using digit_gen_pow2_reduct[of c "Suc c" " (2^c * (z l))" t] + digit_gen_pow2_reduct[of 0 "Suc c" "z l" t] b_def by (simp add: aux_digit_shift mult.commute) + ultimately have zl0: "nth_digit (2^c * (z l)) t b = 2^c * nth_digit (z l) t b \ 0" + using digit_sum_repr[of "nth_digit (2^c * (z l)) t b" "Suc c"] nth_digit_bound b_def by auto + + have "nth_digit (2^c * (z l)) t b = 2^c * nth_digit (z l) t b" using zl0 zl_formula by auto + then have zl_block: "nth_digit (z l) t b = nth_digit (r l + d) t b \ c" using AND_all cond by auto + + consider (g0) "Req l t > 0" | (e0) "Req l t = 0 " by auto + then show ?thesis + proof cases + case e0 + show ?thesis using e0 apply(auto simp add: Req_def Zeq_def) subgoal + proof- + assume asm: "nth_digit (r l) t b = 0" + have add:"((nth_digit d t b) + (nth_digit (r l) t b)) \ c = 0" by (simp add: asm d_block nth_bit_def t_bound) + from d_block t_bound have "nth_digit d (t-1) b \ c = 0" + using add asm by auto + then have "(nth_digit (r l + d) t b) \ c = 0" + using add digit_wise_block_additivity[of "r l" "t" "c" "d" "c"] rl_bound[of "t-1"] b_def asm t_bound c_gt0 by auto + then show ?thesis using zl_block by simp + qed done + next + case g0 + show ?thesis using g0 apply(auto simp add: Req_def Zeq_def) subgoal + proof - + assume "0 < nth_digit (r l) t b" + then obtain k0 where k0_def: "nth_digit (r l) t b \ k0 = 1" using aux0_digit_wise_equiv by auto + then have "k0\c" using nth_digit_bound[of "r l" t c] b_def aux_lt_implies_mask by (metis Suc_leI leI zero_neq_one) + then have k0bound: "k0k k = 1" using d_block t_bound nth_bit_def[of "nth_digit d t b"] + by (metis One_nat_def Suc_1 Suc_diff_Suc Suc_pred dmask_aux even_add even_power odd_iff_mod_2_eq_one + one_mod_two_eq_one plus_1_eq_Suc zero_less_Suc zero_less_power) + ultimately have "nth_digit d t b \ k0 = 1" by simp + then have "bin_carry (nth_digit d t b) (nth_digit (r l) t b) (Suc k0) = 1" using + k0_def sum_carry_formula carry_bounded less_eq_Suc_le by simp + moreover have "\n. Suc k0 \ n \ n < c \ bin_carry (nth_digit d t b) (nth_digit (r l) t b) n = + Suc 0 \ bin_carry (nth_digit d t b) (nth_digit (r l) t b) (Suc n) = Suc 0" subgoal for n + proof- + assume "n c = 1" + using sum_digit_formula[of "nth_digit d t b" "nth_digit (r l) t b" c] + d_block nth_bit_def t_bound assms rl_fst_digit_zero by auto + + from d_block t_bound have "nth_digit d (t-1) b \ c = 0" + by (smt aux_lt_implies_mask diff_le_self diff_less le_eq_less_or_eq le_trans + zero_less_numeral zero_less_one zero_less_power) + then have "(nth_digit (r l + d) t b) \ c = 1" using add b_def t_bound + block_additivity assms rl_fst_digit_zero c_gt0 d_block by (simp add: add.commute) + then show ?thesis using zl_block by simp + qed done + qed + next + case tgq + then have t_bound: "qk k = 0" using cond AND_zero by simp + (* the next two statements are already proven above but here they rely on rl0 *) + moreover have "nth_digit (2^c * (z l)) t b \ c = nth_digit (z l) t b \ 0" + using digit_gen_pow2_reduct[of c "Suc c" " (2^c * (z l))" t] + digit_gen_pow2_reduct[of 0 "Suc c" "z l" t] b_def by (simp add: aux_digit_shift mult.commute) + ultimately have zl0: "nth_digit (2^c * (z l)) t b = 2^c * nth_digit (z l) t b \ 0" + using digit_sum_repr[of "nth_digit (2^c * (z l)) t b" "Suc c"] nth_digit_bound b_def by auto + have "0 k< Suc c \ nth_digit (z l) t b \ k = nth_digit ((r l + d) && f) (Suc t) b \ (k - 1)" + for k using b_def nth_digit_bound digit_gen_pow2_reduct[of k "Suc c" "z l" t] aux_digit_shift[of "z l" c "t + c * t + k"] + digit_gen_pow2_reduct[of "k-1" "Suc c" "z l * 2^c" "Suc t"] cond by (simp add: add.commute add.left_commute mult.commute) + (* Using some simplification lemmas, the result follows *) + then show ?thesis using Zeq_def Req_def cond rl0 zl0 rldf0 zl_formula t_bound by auto + qed +qed + +lemma zl_le_rl: "l z l \ r l" for l +proof - + assume l: "l < n" + have "Zeq l t \ Req l t" for t using Z l by auto + hence "nth_digit (z l) t b \ nth_digit (r l) t b" for t + using Zeq_def Req_def by auto + thus ?thesis using digitwise_leq b_gt1 by auto +qed + + +lemma modifies_valid: "\k\m. modifies (p!k) < n" +proof - + have reg_check: "program_register_check p n" + using is_val by (cases ic, auto simp: is_valid_initial_def n_def is_valid_def) + { + fix k + assume "k \ m" + then have "p ! k \ set p" + by (metis \k \ m\ add_eq_if diff_le_self is_val le_antisym le_trans m_def + n_not_Suc_n not_less not_less0 nth_mem p_contains) + then have "instruction_register_check n (p ! k)" + using reg_check by (auto simp: list_all_def) + then have "modifies (p!k) < n" by (cases "p ! k", auto simp: n_gt0) + } + thus ?thesis by auto +qed + +lemma seq_bound: "k \ length p - 1 \ Seq k t \ 1" + using sk_bound Seq_def by blast + +lemma skzl_bitAND_to_mult: + assumes "k \ length p - 1" + assumes "l < n" + shows "nth_digit (z l) t b && nth_digit (s k) t b = (Zeq l t) * Seq k t" +proof - + have "nth_digit (z l) t b && nth_digit (s k) t b = (Zeq l t) && Seq k t" + using Zeq_def Seq_def by simp + also have "... = (Zeq l t) * Seq k t" + using bitAND_single_bit_mult_equiv[of "(Zeq l t)" "Seq k t"] seq_bound Z assms by auto + finally show ?thesis by auto +qed + +lemma skzl_bitAND_to_mult2: + assumes "k \ length p - 1" + assumes "\k \ length p - 1. l k < n" + shows "(1 - nth_digit (z (l k)) t b) && nth_digit (s k) t b + = (1 - Zeq (l k) t) * Seq k t" +proof - + have "(1 - nth_digit (z (l k)) t b) && nth_digit (s k) t b + = (1 - Zeq (l k) t) && Seq k t" + using Zeq_def Seq_def by simp + also have "... = (1 - Zeq (l k) t) * Seq k t" + using bitAND_single_bit_mult_equiv[of "(1 - Zeq (l k) t)" "Seq k t"] seq_bound Z assms by auto + finally show ?thesis by auto +qed + +lemma state_equations_digit_commute: + assumes "t < q" and "j \ m" + defines "l \ \k. modifies (p!k)" + shows "nth_digit (s j) (Suc t) b = + (\S+ p j (\k. Seq k t)) + + (\S- p j (\k. Zeq (l k) t * Seq k t)) + + (\S0 p j (\k. (1 - Zeq (l k) t) * Seq k t))" +proof - + define o' :: nat where "o' \ if j = 0 then 1 else 0" + have o'_div: "o' div b = 0" using b_gt1 by (auto simp: o'_def) + + have l: "\k\length p - 1. (l k) < n" + using l_def by (auto simp: m_def modifies_valid) + + have "\k. Suc 0 < 2^c" using c_gt0 h0 by auto + hence e_aux: "\tt. nth_digit e tt b = (if tt\q then Suc 0 else 0)" + using e_def b_def c_gt0 nth_digit_gen_power_series[of "\k. Suc 0" "c" "q"] by auto + have zl_bounded: "k\m \ \t'. nth_digit (z (l k)) t' b \ nth_digit e t' b" for k + proof - + assume "k\m" + from m_eq have "\l e" using mask_equations_def by auto + then have "\lt'. (z l) \ t' \ e \ t'" using masks_leq_equiv by auto + then have k_lt_c: "\lt'. \k' k' + \ nth_digit e t' b \ k'" + using digit_gen_pow2_reduct by (auto simp: b_def) (metis power_Suc) + + have "k\Suc c \ x mod (2 ^ Suc c) div 2 ^ k = 0" for k x::nat + by (metis Euclidean_Division.div_eq_0_iff One_nat_def Suc_le_lessD b_gt1 b_def less_le_trans + mod_less_divisor nat_power_less_imp_less not_less not_less0 not_less_eq_eq + numeral_2_eq_2 zero_less_Suc) + then have "\k\Suc c. nth_digit x y b \ k = 0" for x y + using b_def nth_bit_def nth_digit_def by auto + then have k_gt_c: "\lt'. \k'\Suc c. nth_digit (z l) t' b \ k' + \ nth_digit e t' b \ k'" + by auto + from k_lt_c k_gt_c have "\lt'. nth_digit (z l) t' b \ nth_digit e t' b" + using bitwise_leq by (meson not_le) + thus ?thesis by (auto simp: modifies_valid l_def `k\m`) + qed + + have "\t k. k\m \ nth_digit (e - z (l k)) t b = + nth_digit e t b - nth_digit (z (l k)) t b" + using zl_bounded block_subtractivity by (auto simp: c_gt0 b_def l_def) + then have sum_szero_aux: + "\t k. t k\m \ nth_digit (e - z (l k)) t b = 1-nth_digit (z (l k)) t b" + using e_aux by auto + + have skzl_bound2: "\k\length p - 1. (l k) < n \ + \t. \k\length p - 1. nth_digit (s k && (e - z (l k))) t b < 2^c" + proof - + assume l: "\k\length p - 1. (l k) < n" + have "\t. \k\length p - 1. nth_digit (s k && (e - z (l k))) t b + = nth_digit (s k) t b && nth_digit (e - z (l k)) t b" + using bitAND_nth_digit_commute Zeq_def b_def by auto + + moreover have "\tk\length p - 1. + nth_digit (s k) t b && nth_digit (e - z (l k)) t b + = nth_digit (s k) t b && (1 - nth_digit (z (l k)) t b)" + using sum_szero_aux by (simp add: m_def) + + moreover have "\t. \k\length p - 1. + nth_digit (s k) t b && (1 - nth_digit (z (l k)) t b) + \ nth_digit (s k) t b" + using Z l using lm0245 masks_leq by (simp add: lm0244) + + moreover have "\t. \k\length p - 1. nth_digit (s k) t b < 2^c" + using sk_bound h0 by (meson le_less_trans) + + ultimately show ?thesis + using le_less_trans by (metis lm0244 masks_leq) + qed + + (* START *) + have "s j = o' + b*\S+ p j (\k. s k) + b*\S- p j (\k. s k && z (modifies (p!k))) + + b*\S0 p j (\k. s k && (e - z (modifies (p!k))))" + using s_eq state_equations_def \j\m\ by (auto simp: o'_def) + then have "s j div b^Suc t mod b = + ( o' + b*\S+ p j (\k. s k) + + b*\S- p j (\k. s k && z (modifies (p!k))) + + b*\S0 p j (\k. s k && (e - z (modifies (p!k)))) ) div b div b^t mod b" + by (auto simp: algebra_simps div_mult2_eq) + also have "... = (\S+ p j (\k. s k) + + \S- p j (\k. s k && z (modifies (p!k))) + + \S0 p j (\k. s k && (e - z (modifies (p!k)))) ) div b^t mod b" + using o'_div + by (auto simp: algebra_simps div_mult2_eq) + (smt Nat.add_0_right add_mult_distrib2 b_gt1 div_mult_self2 gr_implies_not0) + (* Interchanged order in the following with add.commute to ease next step *) + also have "... = nth_digit (\S- p j (\k. s k && z (l k)) + + \S+ p j (\k. s k) + + \S0 p j (\k. s k && (e - z (l k)))) t b" + by (auto simp: nth_digit_def l_def add.commute) + + (* STEP 2: Commute nth_digit to the inside of all expressions. *) + also have "... = nth_digit (\S- p j (\k. s k && z (l k))) t b + + nth_digit (\S+ p j (\k. s k) + + \S0 p j (\k. s k && (e - z (l k)))) t b" + using block_additivity sum_ssub_fst_digit_zero sum_state_special_fst_digit_zero + by (auto simp: l_def c_gt0 b_def add.assoc) + also have "... = nth_digit (\S+ p j (\k. s k)) t b + + nth_digit (\S- p j (\k. s k && z (l k))) t b + + nth_digit (\S0 p j (\k. s k && (e - z (l k)))) t b" + using block_additivity sum_sadd_fst_digit_zero sum_szero_fst_digit_zero + by (auto simp: l_def c_gt0 b_def) + also have "... = nth_digit (\S+ p j (\k. s k)) t b + + (\S- p j (\k. nth_digit (s k && z (l k)) t b)) + + nth_digit (\S0 p j (\k. s k && (e - z (l k)))) t b" + using sum_ssub_nth_digit_commute by auto + also have "... = nth_digit (\S+ p j (\k. s k)) t b + + \S- p j (\k. nth_digit (s k && z (l k)) t b) + + \S0 p j (\k. nth_digit (s k && (e - z (l k))) t b)" + using l_def l skzl_bound2 sum_szero_nth_digit_commute by (auto) + also have "... = \S+ p j (\k. nth_digit (s k) t b) + + \S- p j (\k. nth_digit (s k && z (l k)) t b) + + \S0 p j (\k. nth_digit (s k && (e - z (l k))) t b)" + using sum_sadd_nth_digit_commute by auto + also have "... = \S+ p j (\k. nth_digit (s k) t b) + + \S- p j (\k. nth_digit (z (l k)) t b && nth_digit (s k) t b) + + \S0 p j (\k. (nth_digit (e - z (l k)) t b) && nth_digit (s k) t b)" + using bitAND_nth_digit_commute b_def by (auto simp: bitAND_commutes) + also have "... = (\S+ p j (\k. nth_digit (s k) t b)) + + (\S- p j (\k. nth_digit (z (l k)) t b && nth_digit (s k) t b)) + + (\S0 p j (\k. (1 - nth_digit (z (l k)) t b) && nth_digit (s k) t b))" + using sum_szero_aux assms sum_ssub_zero.simps m_def \t + apply (auto) using sum.cong atLeastAtMost_iff by smt + (* this ATP proof ensures that the \S0 only uses the sum_szero_aux lemma with k \ m + because the summation of sum_ssub_zero ranges from k = 0 .. (length p - 1) *) + ultimately have "s j div (b ^ Suc t) mod b = + (\S+ p j (\k. nth_digit (s k) t b)) + + (\S- p j (\k. nth_digit (z (l k)) t b && nth_digit (s k) t b)) + + (\S0 p j (\k. (1 - nth_digit (z (l k)) t b) && nth_digit (s k) t b))" + by auto + + moreover have "(\S- p j (\k. nth_digit (z (l k)) t b && nth_digit (s k) t b)) + = (\S- p j (\k. Zeq (l k) t * Seq k t))" + using skzl_bitAND_to_mult sum_ssub_nzero.simps l + by (smt atLeastAtMost_iff sum.cong) + + moreover have "(\S0 p j (\k. (1 - nth_digit (z (l k)) t b) && nth_digit (s k) t b)) + = (\S0 p j (\k. (1 - Zeq (l k) t) * Seq k t))" + using skzl_bitAND_to_mult2 sum_ssub_zero.simps l + by (auto) (smt atLeastAtMost_iff sum.cong) + + ultimately have "nth_digit (s j) (Suc t) b = + (\S+ p j (\k. Seq k t)) + + (\S- p j (\k. Zeq (l k) t * Seq k t)) + + (\S0 p j (\k. (1 - Zeq (l k) t) * Seq k t))" + using Seq_def nth_digit_def by auto + + thus ?thesis by auto +qed + +lemma aux_nocarry_sk: + assumes "t\q" + shows "i \ j \ i\m \ j\m \ nth_digit (s i) t b * nth_digit (s j) t b = 0" +proof (cases "t=q") + case True + have "j < m \ Seq j q = 0" for j using s_bound Seq_def nth_digit_def by auto + then show ?thesis using True Seq_def apply auto by (metis le_less less_nat_zero_code) +next + case False + hence "k\m \ nth_digit (s k) t b = 1 \ + (\j\m. j \ k \ nth_digit (s j) t b = 0)" for k + using states_unique_RAW[of "t"] Seq_def assms by auto + thus ?thesis + by (auto) (metis One_nat_def le_neq_implies_less m_def not_less_eq sk_bound) +qed + +lemma nocarry_sk: + assumes "i \ j" and "i\m" and "j\m" + shows "(s i) \ k * (s j) \ k = 0" +proof - + have reduct: "(s i) \ k = nth_digit (s i) (k div Suc c) b \ (k mod Suc c)" for i + using digit_gen_pow2_reduct[of "k mod Suc c" "Suc c" "s i" "k div Suc c"] b_def + using mod_less_divisor zero_less_Suc by presburger + have "k div Suc c \ q \ + nth_digit (s i) (k div Suc c) b * nth_digit (s j) (k div Suc c) b = 0" + using aux_nocarry_sk assms by auto + moreover have "k div Suc c > q \ + nth_digit (s i) (k div Suc c) b * nth_digit (s j) (k div Suc c) b = 0" + using nth_digit_def s_bound apply auto + using b_gt1 div_greater_zero_iff leD le_less less_trans mod_less neq0_conv power_increasing_iff + by (smt assms) + ultimately have "nth_digit (s i) (k div Suc c) b \ (k mod Suc c) + * nth_digit (s j) (k div Suc c) b \ (k mod Suc c) = 0" + using nth_bit_def by auto + thus ?thesis using reduct[of "i"] reduct[of "j"] by auto +qed + + +lemma commute_sum_rsub_bitAND: "\R- p l (\k. s k && z l) = \R- p l (\k. s k) && z l" +proof - + show ?thesis apply (auto simp: sum_rsub.simps) + using m_def nocarry_sk aux_commute_bitAND_sum_if[of "m" + "s" "\k. issub (p ! k) \ l = modifies (p ! k)" "z l"] + by (auto simp add: atMost_atLeast0) +qed + +lemma sum_rsub_bound: "l \R- p l (\k. s k && z l) \ r l + \R+ p l s" +proof - + assume "lR- p l (\k. s k) && z l \ z l" by (auto simp: lm0245 masks_leq) + also have "... \ r l" using zl_le_rl `lObtaining single step register relations from multiple step register relations \ +lemma mult_to_single_reg: + "c>0 \ l Req l (Suc t) = Req l t + (\R+ p l (\k. Seq k t)) + - (\R- p l (\k. (Zeq l t) * Seq k t))" for l t +proof - + assume l: "l 0" + + have a_div: "a div b = 0" using c_eq rm_constants_def B_def by auto + + have subtract_bound: "\t'. nth_digit (\R- p l (\k. s k && z l)) t' b + \ nth_digit (r l + \R+ p l (\k. s k)) t' b" + proof - + { + fix t' + have "nth_digit (z l) t' b \ nth_digit (r l) t' b" + using Zeq_def Req_def Z l by auto + then have "nth_digit (\R- p l (\k. s k)) t' b && nth_digit (z l) t' b + \ nth_digit (r l) t' b" + using sum_rsub_special_block_bound + by (meson dual_order.trans lm0245 masks_leq) + then have "nth_digit (\R- p l (\k. s k && z l)) t' b + \ nth_digit (r l) t' b" + using commute_sum_rsub_bitAND bitAND_nth_digit_commute b_def by auto + then have "nth_digit (\R- p l (\k. s k && z l)) t' b + \ nth_digit (r l) t' b + nth_digit (\R+ p l (\k. s k)) t' b" + by auto + then have "nth_digit (\R- p l (\k. s k && z l)) t' b + \ nth_digit (r l + \R+ p l (\k. s k)) t' b" + using block_additivity rl_fst_digit_zero sum_radd_fst_digit_zero + by (auto simp: b_def c l) + } + then show ?thesis by auto + qed + + define a' where "a' \ (if l = 0 then a else 0)" + have a'_div: "a' div b = 0" using a_div a'_def by auto + + (* START PROOF CHAIN *) + (* STEP 1: Remove a' using divisibility properties. *) + have "r l div (b * b ^ t) mod b = + (a' + b*r l + b*\R+ p l (\k. s k) - b*\R- p l (\k. s k && z l)) div (b * b ^ t) mod b" + using r_eq reg_equations_def by (auto simp: a'_def l) + also have "... = + (a' + b * (r l + \R+ p l (\k. s k) - \R- p l (\k. s k && z l))) div b div b^t mod b" + by (auto simp: algebra_simps div_mult2_eq) + (metis Nat.add_diff_assoc add_mult_distrib2 mult_le_mono2 sum_rsub_bound l) + also have "... = + ((r l + \R+ p l (\k. s k) - \R- p l (\k. s k && z l)) + a' div b) div b ^ t mod b" + using b_gt1 by auto + also have "... = (r l + \R+ p l (\k. s k) - \R- p l (\k. s k && z l)) div b ^ t mod b" + using a'_div by auto + also have "... = nth_digit (r l + \R+ p l (\k. s k) - \R- p l (\k. s k && z l)) t b" + using nth_digit_def by auto + + (* STEP 2: Commute nth_digit to the inside of all expressions. *) + also have "... = nth_digit (r l + \R+ p l (\k. s k)) t b + - nth_digit (\R- p l (\k. s k && z l)) t b" + using block_subtractivity subtract_bound + by (auto simp: c b_def) + also have "... = nth_digit (r l) t b + + nth_digit (\R+ p l (\k. s k)) t b + - nth_digit (\R- p l (\k. s k && z l)) t b" + using block_additivity rl_fst_digit_zero sum_radd_fst_digit_zero + by (auto simp: l b_def c) + also have "... = nth_digit (r l) t b + + \R+ p l (\k. nth_digit (s k) t b) + - \R- p l (\k. nth_digit (s k && z l) t b)" + using sum_radd_nth_digit_commute + using sum_rsub_nth_digit_commute + by auto + ultimately have "r l div (b * b ^ t) mod b = + (nth_digit (r l) t b) + + \R+ p l (\k. nth_digit (s k) t b) + - \R- p l (\k. nth_digit (z l) t b && nth_digit (s k) t b)" + using bitAND_nth_digit_commute b_def by (simp add: bitAND_commutes) + + then show ?thesis using Req_def Seq_def nth_digit_def skzl_bitAND_to_mult l + by (auto simp: sum_rsub.simps) (smt atLeastAtMost_iff sum.cong) +qed + +text \Obtaining single step state relations from multiple step state relations\ +lemma mult_to_single_state: + fixes t j :: nat + defines "l \ \k. modifies (p!k)" + shows "j\m \ t Seq j (Suc t) = (\S+ p j (\k. Seq k t)) + + (\S- p j (\k. Zeq (l k) t * Seq k t)) + + (\S0 p j (\k. (1 - Zeq (l k) t) * Seq k t))" +proof - + assume "j \ m" + assume "t < q" + + have "nth_digit (s j) (Suc t) b = + (\S+ p j (\k. Seq k t)) + + (\S- p j (\k. Zeq (l k) t * Seq k t)) + + (\S0 p j (\k. (1 - Zeq (l k) t) * Seq k t))" + using state_equations_digit_commute \j\m\ \t l_def by auto + + then show ?thesis using nth_digit_def l_def Seq_def by auto +qed + +text \Conclusion: + The central equivalence showing that the cell entries obtained from r s z indeed coincide with + the correct cell values when executing the register machine. This statement is proven by + induction using the single step relations for Req and Seq as well as the statement for Zeq. \ + +lemma rzs_eq: + "l j\m \ t\q \ R ic p l t = Req l t \ Z ic p l t = Zeq l t \ S ic p j t = Seq j t" +proof (induction t arbitrary: j l) + have "m>0" using m_def is_val is_valid_initial_def[of "ic" "p"] is_valid_def[of "ic" "p"] by auto + + case 0 + (* STATES *) + have mod_aux0: "Suc (b * k) mod b = 1" for k + using euclidean_semiring_cancel_class.mod_mult_self2[of "1" "b" "k"] b_gt1 by auto + have step_state0: "s 0 = 1 + b*\S+ p 0 (\k. s k) + b*\S- p 0 (\k. s k && z (modifies (p!k))) + + b*\S0 p 0 (\k. s k && (e - z (modifies (p!k))))" + using s_eq state_equations_def by auto + hence "Seq 0 0 = 1" using Seq_def by (auto simp: nth_digit_def mod_aux0) + hence S00: "Seq 0 0 = S ic p 0 0" using S_def is_val is_valid_initial_def[of "ic"] by auto + + have "s m = b^q" using s_eq state_equations_def by auto + hence "Seq m 0 = 0" using Seq_def nth_digit_def c_eq rm_constants_def by auto + hence Sm0: "S ic p m 0 = Seq m 0" + using is_val is_valid_initial_def[of "ic" "p" "a"] S_def `m>0` by auto + + have step_states: "\d>0. d s d = b*\S+ p d (\k. s k) + + b*\S- p d (\k. s k && z (modifies (p!k))) + + b*\S0 p d (\k. s k && (e - z (modifies (p!k))))" + using s_eq state_equations_def by auto + hence "\k>0. k Seq k 0 = 0" using Seq_def by (auto simp: nth_digit_def) + hence "k>0 \ k Seq k 0 = S ic p k 0" for k + using S_def is_val is_valid_initial_def[of "ic"] by auto + + with S00 Sm0 have Sid: "k\m \ Seq k 0 = S ic p k 0" for k + by (cases "k=0"; cases "k=m"; auto) + + (* REGISTERS *) + have "b * (r 0 + \R+ p 0 s - \R- p 0 (\k. s k && z 0)) + = b * (r 0 + \R+ p 0 s) - b * \R- p 0 (\k. s k && z 0)" + using Nat.diff_mult_distrib2[of "b" "r 0 + \R+ p 0 s" "\R- p 0 (\k. s k && z 0)"] by auto + also have "... = b * r 0 + b* \R+ p 0 s - b * \R- p 0 (\k. s k && z 0)" + using Nat.add_mult_distrib2[of "b" "r 0" "\R+ p 0 s"] by auto + ultimately have distrib: "a + b * (r 0 + \R+ p 0 s - \R- p 0 (\k. s k && z 0)) + = a + b * r 0 + b * \R+ p 0 s - b * \R- p 0 (\k. s k && z 0)" + by (auto simp: algebra_simps) + (metis Nat.add_diff_assoc add_mult_distrib2 mult_le_mono2 n_gt0 sum_rsub_bound) + + hence "Req 0 0 = (a + b * r 0 + b * \R+ p 0 s - b * \R- p 0 (\k. s k && z 0)) mod b" + using Req_def nth_digit_def r_eq reg_equations_def by auto + also have "... = (a + b * (r 0 + \R+ p 0 s - \R- p 0 (\k. s k && z 0))) mod b" + using distrib by auto + finally have "Req 0 0 = a" using c_eq rm_constants_def B_def by auto + hence R00: "R ic p 0 0 = Req 0 0" + using R_def is_val is_valid_initial_def[of "ic" "p" "a"] by auto + + have rl_transform: "l>0 \ r l = b * r l + b * \R+ p l s - b * \R- p l (\k. s k && z l)" + using reg_equations_def r_eq `l0 \ (b * r l + b * \R+ p l s - b * \R- p l (\k. s k && z l)) mod b = 0" + using Req_def nth_digit_def reg_equations_def r_eq by auto + hence "l>0 \ Req l 0 = 0" + using Req_def rl_transform nth_digit_def by auto + hence "l>0 \ Req l 0 = R ic p l 0" using is_val is_valid_initial_def[of "ic"] R_def by auto + hence Rid: "R ic p l 0 = Req l 0" using R00 by (cases "l=0"; auto) + + (* ZERO INDICATORS *) + hence Zid: "Z ic p l 0 = Zeq l 0" using Z Z_def 0 by auto + + show ?case using Sid Rid Zid `lm` by auto +next + case (Suc t) + + (* INDUCTIVE HYPOTHESIS *) + have "Suc t\q" using Suc by auto + then have "tm \ S ic p k t = Seq k t" for k using Suc m_def by auto + have Z_IH: "\l::nat. l Z ic p l t = Zeq l t" using Suc by auto + + (* REGISTERS *) + from S_IH have S1: "k\m \ + (if isadd (p ! k) \ l = modifies (p ! k) then Seq k t else 0) + = (if isadd (p ! k) \ l = modifies (p ! k) then S ic p k t else 0)" for k + by auto + have S2: "k \ {0..length p-1} \ + (if issub (p ! k) \ l = modifies (p ! k) then Zeq l t * Seq k t else 0) + = (if issub (p ! k) \ l = modifies (p ! k) then Zeq l t * S ic p k t else 0)" for k + using Suc m_def by auto + + have "Req l (Suc t) = Req l t + (\R+ p l (\k. Seq k t)) - (\R- p l (\k. (Zeq l t) * Seq k t))" + using mult_to_single_reg[of "l"] `lR+ p l (\k. S ic p k t)) + - (\R- p l (\k. (Z ic p l t) * S ic p k t))" + using Suc sum_radd.simps sum_rsub.simps S1 S2 m_def by auto + finally have R: "Req l (Suc t) = R ic p l (Suc t)" + using is_val `l Suc m" by (simp add: m_def) + + (* STATES *) + have "s m = b ^ q" using s_eq state_equations_def by auto + hence "Seq m t = 0" using Seq_def \t nth_digit_def apply auto + using b_gt1 bx_aux by auto + hence "S ic p m t = 0" using Suc by auto + hence "fst (steps ic p t) \ m" using S_def by auto + hence "fst (steps ic p t) < m" using is_val m_def + by (metis less_Suc_eq less_le_trans p_contains plength) + hence nohalt: "\ ishalt (p ! fst (steps ic p t))" using is_valid_def[of "ic" "p"] + is_valid_initial_def[of "ic" "p" "a"] m_def is_val by auto + + have "jm` m_def + by (metis (full_types) diff_less is_val length_greater_0_conv less_imp_diff_less less_one + list.size(3) nat_less_le not_less not_less_zero p_contains) + have "Seq j (Suc t) = (\S+ p j (\k. Seq k t)) + + (\S- p j (\k. Zeq (modifies (p!k)) t * Seq k t)) + + (\S0 p j (\k. (1 - Zeq (modifies (p!k)) t) * Seq k t))" + using mult_to_single_state `j\m` `tS+ p j (\k. Seq k t)) + + (\S- p j (\k. Z ic p (modifies (p!k)) t * Seq k t)) + + (\S0 p j (\k. (1 - Z ic p (modifies (p!k)) t) * Seq k t))" + using Z_IH modifies_valid sum_ssub_zero.simps sum_ssub_nzero.simps + by (auto simp: m_def, smt atLeastAtMost_iff sum.cong) + also have "... = (\S+ p j (\k. S ic p k t)) + + (\S- p j (\k. Z ic p (modifies (p!k)) t * S ic p k t)) + + (\S0 p j (\k. (1 - Z ic p (modifies (p!k)) t) * S ic p k t))" + using S_IH sum_ssub_zero.simps sum_ssub_nzero.simps sum_sadd.simps + by (auto simp: m_def, smt atLeastAtMost_iff sum.cong) + finally have S: "Seq j (Suc t) = S ic p j (Suc t)" + using is_val lm04_07_one_step_relation_state[of "ic" "p" "a" "j"] `jSimple Properties of Register Machines\ + +theory RegisterMachineProperties + imports "RegisterMachineSpecification" +begin + +lemma step_commutative: "steps (step c p) p t = step (steps c p t) p" + by (induction t; auto) + +lemma step_fetch_correct: + fixes t :: nat + and c :: configuration + and p :: program + assumes "is_valid c p" + defines "ct \ (steps c p t)" + shows "fst (steps (step c p) p t) = fetch (fst ct) p (read (snd ct) p (fst ct))" + using ct_def step_commutative step_def by auto + +subsubsection \From Configurations to a Protocol\ + +text \Register Values\ + +definition R :: "configuration \ program \ nat \ nat \ nat" + where "R c p n t = (snd (steps c p t)) ! n" + +fun RL :: "configuration \ program \ nat \ nat \ nat \ nat" where + "RL c p b 0 l = ((snd c) ! l)" | + "RL c p b (Suc t) l = ((snd c) ! l) + b * (RL (step c p) p b t l)" + +lemma RL_simp_aux: + \snd c ! l + b * RL (step c p) p b t l = + RL c p b t l + b * (b ^ t * snd (step (steps c p t) p) ! l)\ + by (induction t arbitrary: c) + (auto simp: step_commutative algebra_simps) + +declare RL.simps[simp del] +lemma RL_simp: + "RL c p b (Suc t) l = (snd (steps c p (Suc t)) ! l) * b ^ (Suc t) + (RL c p b t l)" +proof (induction t arbitrary: p c b) + case 0 + thus ?case by (auto simp: RL.simps) +next + case (Suc t p c b) + show ?case + by (subst RL.simps) (* \unfold one level\ *) + (auto simp: Suc step_commutative algebra_simps RL_simp_aux) +qed + +text \State Values\ + +definition S :: "configuration \ program \ nat \ nat \ nat" + where "S c p k t = (if (fst (steps c p t) = k) then (Suc 0) else 0)" + +definition S2 :: "configuration \ nat \ nat" + where "S2 c k = (if (fst c) = k then 1 else 0)" + +fun SK :: "configuration \ program \ nat \ nat \ nat \ nat" + where "SK c p b 0 k = (S2 c k)" | + "SK c p b (Suc t) k = (S2 c k) + b * (SK (step c p) p b t k)" + +lemma SK_simp_aux: + \SK c p b (Suc (Suc t)) k = + S2 (steps c p (Suc (Suc t))) k * b ^ Suc (Suc t) + SK c p b (Suc t) k\ + by (induction t arbitrary: c) (auto simp: step_commutative algebra_simps) + +declare SK.simps[simp del] +lemma SK_simp: + "SK c p b (Suc t) k = (S2 (steps c p (Suc t)) k) * b ^ (Suc t) + (SK c p b t k)" +proof (induction t arbitrary: p c b k) + case 0 + thus ?case by (auto simp: SK.simps) +next + case (Suc t p c b k) + show ?case + by (auto simp: Suc algebra_simps step_commutative SK_simp_aux) +qed + +text \Zero-Indicator Values\ + +definition Z :: "configuration \ program \ nat \ nat \ nat" where + "Z c p n t = (if (R c p n t > 0) then 1 else 0)" + +definition Z2 :: "configuration \ nat \ nat" where + "Z2 c n = (if (snd c) ! n > 0 then 1 else 0)" + +fun ZL :: "configuration \ program \ nat \ nat \ nat \ nat" + where "ZL c p b 0 l = (Z2 c l)" | + "ZL c p b (Suc t) l = (Z2 c l) + b * (ZL (step c p) p b t l)" + +lemma ZL_simp_aux: +"Z2 c l + b * ZL (step c p) p b t l = + ZL c p b t l + b * (b ^ t * Z2 (step (steps c p t) p) l)" + by (induction t arbitrary: c) (auto simp: step_commutative algebra_simps) + +declare ZL.simps[simp del] +lemma ZL_simp: + "ZL c p b (Suc t) l = (Z2 (steps c p (Suc t)) l) * b ^ (Suc t) + (ZL c p b t l)" +proof (induction t arbitrary: p c b) + case 0 + thus ?case by (auto simp: ZL.simps) +next + case (Suc t p c b) + show ?case + by (subst ZL.simps) (auto simp: Suc step_commutative algebra_simps ZL_simp_aux) +qed + +subsubsection \Protocol Properties\ + +lemma Z_bounded: "Z c p l t \ 1" + by (auto simp: Z_def) + +lemma S_bounded: "S c p k t \ 1" + by (auto simp: S_def) + +lemma S_unique: "\k\length p. (k \ fst (steps c p t) \ S c p k t = 0)" + by (auto simp: S_def) + + +(* takes c :: nat, the exponent defining the base b *) +fun cells_bounded :: "configuration \ program \ nat \ bool" where + "cells_bounded conf p c = ((\l<(length (snd conf)). \t. 2^c > R conf p l t) + \ (\k t. 2^c > S conf p k t) + \ (\l t. 2^c > Z conf p l t))" + +lemma steps_tape_length_invar: "length (snd (steps c p t)) = length (snd c)" + by (induction t; auto simp add: step_def update_def) + +lemma step_is_valid_invar: "is_valid c p \ is_valid (step c p) p" + by (auto simp add: step_def update_def is_valid_def) + +fun fetch_old + where + "(fetch_old p s (Add r next) _) = next" + | "(fetch_old p s (Sub r next nextalt) val) = (if val = 0 then nextalt else next)" + | "(fetch_old p s Halt _) = s" + +lemma fetch_equiv: + assumes "i = p!s" + shows "fetch s p v = fetch_old p s i v" + by (cases i; auto simp: assms fetch_def) + +(* Corollary: All states have instructions in the program list *) +lemma p_contains: "is_valid_initial ic p a \ (fst (steps ic p t)) < length p" +proof - + assume asm: "is_valid_initial ic p a" + hence "fst ic = 0" using is_valid_initial_def is_valid_def by blast + hence 0: "ic = (0, snd ic)" by (metis prod.collapse) + show ?thesis using 0 asm + apply (induct t) apply auto[1] + subgoal by (auto simp add: is_valid_initial_def is_valid_def) + apply (cases "p ! fst (steps ic p t)") + apply (auto simp add: list_all_length fetch_equiv step_def + is_valid_initial_def is_valid_def fetch_old.elims) + by (metis RegisterMachineSpecification.isc_add RegisterMachineSpecification.isc_sub + fetch_old.elims) + +qed + +lemma steps_is_valid_invar: "is_valid c p \ is_valid (steps c p t) p" + by (induction t; auto simp add: step_def update_def is_valid_def) + +lemma terminates_halt_state: "terminates ic p q \ is_valid_initial ic p a + \ ishalt (p ! (fst (steps ic p q)))" +proof - + assume terminate: "terminates ic p q" + assume is_val: "is_valid_initial ic p a" + have "1 < length p" using is_val is_valid_initial_def[of "ic" "p" "a"] + is_valid_def[of "ic" "p"] program_includes_halt.simps + by blast + hence "p \ []" by auto + hence "p ! (length p - 1) = last p" using List.last_conv_nth[of "p"] by auto + thus ?thesis + using terminate terminates_def correct_halt_def is_val is_valid_def[of "ic" "p"] by auto +qed + +lemma R_termination: + fixes l :: register and ic :: configuration + assumes is_val: "is_valid ic p" and terminate: "terminates ic p q" and l: "l < length (snd ic)" + shows "\t\q. R ic p l t = 0" +proof - + have ishalt: "ishalt (p ! fst (steps ic p q))" + using terminate terminates_def correct_halt_def is_valid_def is_val by auto + have halt: "ishalt (p ! fst (steps ic p (q + t)))" for t + apply (induction t) + using terminate terminates_def ishalt step_def fetch_def by auto + have "l<(length (snd ic)) \R ic p l (q+t) = 0" for t + apply (induction t arbitrary: l) + subgoal using terminate terminates_def correct_halt_def R_def by auto + subgoal using R_def step_def halt update_def by auto + done + thus ?thesis using le_Suc_ex l by force +qed + +lemma terminate_c_exists: "is_valid ic p \ terminates ic p q \ \c>1. cells_bounded ic p c" +proof - + assume is_val: "is_valid ic p" + assume terminate: "terminates ic p q" + define n where "n \ length (snd ic)" + define rmax where "rmax \ Max ({k. \lt {2})" + have "\lt {k. \lttl rmax" using rmax_def by auto + moreover have "\t\q. \l rmax" + using rmax_def R_termination terminate n_def is_val by auto + ultimately have r: "\lt. R ic p l t \ rmax" using not_le_imp_less by blast + have gt2: "rmax \ 2" using rmax_def by auto + hence sz: "(\k t. rmax > S ic p k t) \ (\l t. rmax > Z ic p l t)" + using S_bounded Z_bounded S_def Z_def by auto + have "(\lt. R ic p l t < 2^rmax) \ (\k t. S ic p k t < 2^rmax) + \ (\l t. Z ic p l t < 2^rmax)" + using less_exp[of "rmax"] r sz by (metis le_neq_implies_less dual_order.strict_trans) + moreover have "rmax > 1" using gt2 by auto + ultimately show ?thesis using n_def by auto +qed + +end diff --git a/thys/DPRM_Theorem/Register_Machine/RegisterMachineSimulation.thy b/thys/DPRM_Theorem/Register_Machine/RegisterMachineSimulation.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Register_Machine/RegisterMachineSimulation.thy @@ -0,0 +1,333 @@ +subsection \Simulation of a Register Machine\ + +theory RegisterMachineSimulation + imports RegisterMachineProperties "Digit_Expansions.Binary_Operations" +begin + +definition B :: "nat \ nat" where + "(B c) = 2^(Suc c)" + +definition "RLe c p b q l = (\t = 0..q. b^t * R c p l t)" +definition "SKe c p b q k = (\t = 0..q. b^t * S c p k t)" +definition "ZLe c p b q l = (\t = 0..q. b^t * Z c p l t)" + +fun sum_radd :: "program \ register \ (nat \ nat) \ nat" + where "sum_radd p l f = (\k = 0..length p-1. if isadd (p!k) \ l = modifies (p!k) then f k else 0)" + +abbreviation sum_radd_abbrev ("\R+ _ _ _" [999, 999, 999] 1000) + where "(\R+ p l f) \ (sum_radd p l f)" + +fun sum_rsub :: "program \ register \ (nat \ nat) \ nat" + where "sum_rsub p l f = (\k = 0..length p-1. if issub (p!k) \ l = modifies (p!k) then f k else 0)" + +abbreviation sum_rsub_abbrev ("\R- _ _ _ " [999, 999, 999] 1000) + where "(\R- p l f) \ (sum_rsub p l f)" + +(* Note: different naming convention for sums compared to original paper *) +fun sum_sadd :: "program \ state \ (nat \ nat) \ nat" + where "sum_sadd p d f = (\k = 0..length p-1. if isadd (p!k) \ d = goes_to (p!k) then f k else 0)" + +abbreviation sum_sadd_abbrev ("\S+ _ _ _ " [999, 999, 999] 1000) + where "(\S+ p d f) \ (sum_sadd p d f)" + +(* careful: f needs be passed the program so that z l t can be properly called with l = modifies (p!k) *) +fun sum_ssub_nzero :: "program \ state \ (nat \ nat) \ nat" + where "sum_ssub_nzero p d f = (\k = 0..length p-1. if issub (p!k) \ d = goes_to (p!k) then f k else 0)" + +abbreviation sum_ssub_nzero_abbrev ("\S- _ _ _ " [999, 999, 999] 1000) + where "(\S- p d f) \ (sum_ssub_nzero p d f)" + +fun sum_ssub_zero :: "program \ state \ (nat \ nat) \ nat" + where "sum_ssub_zero p d f = (\k = 0..length p-1. if issub (p!k) \ d = goes_to_alt (p!k) then f k else 0)" + +abbreviation sum_ssub_zero_abbrev ("\S0 _ _ _ " [999, 999, 999] 1000) + where "(\S0 p d f) \ (sum_ssub_zero p d f)" + +declare sum_radd.simps[simp del] +declare sum_rsub.simps[simp del] +declare sum_sadd.simps[simp del] +declare sum_ssub_nzero.simps[simp del] +declare sum_ssub_zero.simps[simp del] + +text \Special sum cong lemmas\ + +lemma sum_sadd_cong: + assumes "\k. k \ length p-1 \ isadd (p!k) \ l = goes_to (p!k) \ f k = g k" + shows "\S+ p l f = \S+ p l g" + unfolding sum_sadd.simps + by (rule sum.cong, simp) (rule if_cong, simp_all add: assms) + +lemma sum_ssub_nzero_cong: + assumes "\k. k \ length p - 1 \ issub (p!k) \ l = goes_to (p!k) \ f k = g k" + shows "\S- p l f = \S- p l g" + unfolding sum_ssub_nzero.simps + by (rule sum.cong, simp) (rule if_cong, simp_all add: assms) + +lemma sum_ssub_zero_cong: + assumes "\k. k \ length p - 1 \ issub (p!k) \ l = goes_to_alt (p!k) \ f k = g k" + shows "\S0 p l f = \S0 p l g" + unfolding sum_ssub_zero.simps + by (rule sum.cong, simp) (rule if_cong, simp_all add: assms) + +lemma sum_radd_cong: + assumes "\k. k \ length p - 1 \ isadd (p!k) \ l = modifies (p!k) \ f k = g k" + shows "\R+ p l f = \R+ p l g" + unfolding sum_radd.simps + by (rule sum.cong, simp) (rule if_cong, simp_all add: assms) + +lemma sum_rsub_cong: + assumes "\k. k \ length p - 1 \ issub (p!k) \ l = modifies (p!k) \ f k = g k" + shows "\R- p l f = \R- p l g" + unfolding sum_rsub.simps + by (rule sum.cong, simp) (rule if_cong, simp_all add: assms) + + + +text \Properties and simple lemmas\ +lemma RLe_equivalent: "RL c p b q l = RLe c p b q l" + by (induction q arbitrary: c) (auto simp add: RLe_def R_def RL.simps(1) RL_simp) + +lemma SKe_equivalent: "SK c p b q k = SKe c p b q k" + by (induction q arbitrary: c) (auto simp add: SKe_def S_def SK.simps(1) S2_def SK_simp) + +lemma ZLe_equivalent: "ZL c p b q l = ZLe c p b q l" + by (induction q arbitrary: c) (auto simp add: ZLe_def ZL.simps(1) R_def Z2_def Z_def ZL_simp) + + +lemma sum_radd_distrib: "a * (\R+ p l f) = (\R+ p l (\k. a * f k))" + by (auto simp add: sum_radd.simps sum_distrib_left; smt mult_is_0 sum.cong) + +lemma sum_rsub_distrib: "a * (\R- p l f) = (\R- p l (\k. a * f k))" + by (auto simp add: sum_rsub.simps sum_distrib_left; smt mult_is_0 sum.cong) + +lemma sum_sadd_distrib: "a * (\S+ p d f) = (\S+ p d (\k. a * f k))" for a + by (auto simp add: sum_sadd.simps sum_distrib_left; smt mult_is_0 sum.cong) + +lemma sum_ssub_nzero_distrib: "a * (\S- p d f) = (\S- p d (\k. a * f k))" for a + by (auto simp add: sum_ssub_nzero.simps sum_distrib_left; smt mult_is_0 sum.cong) + +lemma sum_ssub_zero_distrib: "a * (\S0 p d f) = (\S0 p d (\k. a * f k))" for a + by (auto simp add: sum_ssub_zero.simps sum_distrib_left; smt mult_is_0 sum.cong) + +lemma sum_distrib: + fixes SX :: "program \ nat \ (nat \ nat) \ nat" + and p :: program + +assumes SX_simps: "\h. SX p x h = (\k = 0..length p-1. if g x k then h k else 0)" + +shows "SX p x h1 + SX p x h2 = SX p x (\k. h1 k + h2 k)" + by (subst SX_simps)+ (auto simp: sum.distrib[symmetric] intro: sum.cong) + +lemma sum_commutative: + fixes SX :: "program \ nat \ (nat \ nat) \ nat" + and p :: program + +assumes SX_simps: "\h. SX p x h = (\k = 0..length p-1. if g x k then h k else 0)" + + shows "(\t=0..q::nat. SX p x (\k. f k t)) + = (SX p x (\k. \t=0..q. f k t))" +proof (induction q) + case 0 + then show ?case by (auto) +next + case (Suc q) + have SX_add: "SX p x h1 + SX p x h2 = SX p x (\k. h1 k + h2 k)" for h1 h2 + by (subst sum_distrib[where ?h1.0 = "h1"]) (auto simp: SX_simps) + + + have h1: "(\t\(Suc q). SX p x (\k. f k t)) = SX p x (\k. f k (Suc q)) + sum (\t. SX p x (\k. f k t)) {0..q}" + by (auto simp add: sum.atLeast0_atMost_Suc add.commute atMost_atLeast0) + also have h2: "... = SX p x (\k. f k (Suc q)) + SX p x (\k. sum (f k){0..q})" + using Suc.IH Suc.prems by auto + also have h3: "... = SX p x (\k. sum (f k) {0..(Suc q)})" + by (subst SX_add) (auto simp: atLeast0_atMost_Suc) + finally show ?case using Suc.IH by (simp add: atMost_atLeast0) +qed + +lemma sum_radd_commutative: "(\t=0..(q::nat). \R+ p l (\k. f k t)) = (\R+ p l (\k. \t=0..q. f k t))" + by (rule sum_commutative sum_radd.simps) + +lemma sum_rsub_commutative: "(\t=0..(q::nat). \R- p l (\k. f k t)) = (\R- p l (\k. \t=0..q. f k t))" + by (rule sum_commutative sum_rsub.simps) + +lemma sum_sadd_commutative: "(\t=0..(q::nat). \S+ p l (\k. f k t)) = (\S+ p l (\k. \t=0..q. f k t))" + by (rule sum_commutative sum_sadd.simps) + +lemma sum_ssub_nzero_commutative: "(\t=0..(q::nat). \S- p l (\k. f k t)) = (\S- p l (\k. \t=0..q. f k t))" + by (rule sum_commutative sum_ssub_nzero.simps) + +lemma sum_ssub_zero_commutative: "(\t=0..(q::nat). \S0 p l (\k. f k t)) = (\S0 p l (\k. \t=0..q. f k t))" + by (rule sum_commutative sum_ssub_zero.simps) + + +lemma sum_int: "c \ a + b \ int(a + b - c) = int(a) + int(b) - int(c)" + by (simp add: SMT.int_plus) + +lemma ZLe_bounded: "b > 2 \ ZLe c p b q l < b ^ (Suc q)" + using Z_bounded ZLe_def +proof (induction q) + case 0 + then show ?case by (simp add: Z_bounded ZLe_def Z_def) +next + case (Suc q) + have "ZLe c p b (Suc q) l = b ^ (Suc q) * Z c p l (Suc q) + ZLe c p b q l" + by (auto simp: ZLe_def) + also have "ZLe c p b q l < b ^ (Suc q)" using Suc.IH + by (auto simp: ZLe_def Z_def Suc.prems(1)) + also have "b ^ (Suc q) * Z c p l (Suc q) \ b ^ (Suc q)" using Suc.prems(1) + by (auto simp: Z_def) + finally have "ZLe c p b (Suc q) l < 2 * b ^ (Suc q)" + by auto + also have "... < b ^ Suc (Suc q)" + using Suc.prems(1) by auto + finally show ?case by simp +qed + +lemma SKe_bounded: "b > 2 \ SKe c p b q k < b ^ (Suc q)" + proof (induction q) + case 0 + then show ?case by (auto simp add: SKe_def S_bounded S_def) +next + case (Suc q) + have "SKe c p b (Suc q) k = b ^ (Suc q) * S c p k (Suc q) + SKe c p b q k" + by (auto simp: SKe_def) + also have "SKe c p b q k < b ^ (Suc q)" using Suc.IH + by (auto simp: Suc.prems(1)) + also have "b ^ (Suc q) * S c p k (Suc q) \ b ^ (Suc q)" using Suc.prems(1) + by (auto simp: S_def) + finally have "SKe c p b (Suc q) k < 2 * b ^ (Suc q)" + by auto + also have "... < b ^ Suc (Suc q)" + using Suc.prems(1) by auto + finally show ?case by simp +qed + +lemma mult_to_bitAND: + assumes cells_bounded: "cells_bounded ic p c" +and "c > 1" +and "b = B c" + +shows "(\t=0..q. b^t * (Z ic p l t * S ic p k t)) + = ZLe ic p b q l && SKe ic p b q k" +proof (induction q arbitrary: ic p c l k) + case 0 + then show ?case using S_bounded Z_bounded + by (auto simp add: SKe_def ZLe_def bitAND_single_bit_mult_equiv) +next + case (Suc q) + + have b4: "b > 2" using assms(2-3) apply (auto simp add: B_def) + by (metis One_nat_def Suc_less_eq2 lessI numeral_2_eq_2 power_gt1) + + have ske: "SKe ic p b q k < b ^ (Suc q)" using SKe_bounded b4 by auto + have zle: "ZLe ic p b q l < b ^ (Suc q)" using ZLe_bounded b4 by auto + + have ih: "(\t = 0..q. b ^ t * (Z ic p l t * S ic p k t)) = ZLe ic p b q l && SKe ic p b q k" + using Suc.IH by auto + + have "(\t = 0..Suc q. b ^ t * (Z ic p l t * S ic p k t)) + = b ^(Suc q) * (Z ic p l (Suc q) * S ic p k (Suc q)) + (\t = 0..q. b ^ t * (Z ic p l t * S ic p k t))" + by (auto simp: sum.atLeast0_atMost_Suc add.commute) + + also have "... = b ^ (Suc q) * (Z ic p l (Suc q) * S ic p k (Suc q)) + (ZLe ic p b q l && SKe ic p b q k)" + by (auto simp add: ih) + + also have "... = b ^ (Suc q) * (Z ic p l (Suc q) && S ic p k (Suc q)) + (ZLe ic p b q l && SKe ic p b q k)" + using bitAND_single_bit_mult_equiv S_bounded Z_bounded by (auto) + + also have "... = (b ^(Suc q) * Z ic p l (Suc q) + ZLe ic p b q l) && (b ^ (Suc q) * S ic p k (Suc q) + SKe ic p b q k)" + using bitAND_linear ske zle + by (auto) (smt B_def assms(3) bitAND_linear mult.commute power_Suc power_mult) + + also have "... = (ZLe ic p b (Suc q) l && SKe ic p b (Suc q) k)" + by (auto simp: ZLe_def SKe_def add.commute) + + finally show ?case by simp +qed + +lemma sum_bt: + fixes b q :: nat + assumes "b > 2" + shows "(\t = 0..q. b^t) < b ^ (Suc q)" + using assms +proof (induction q, auto) + fix qb :: nat + assume "sum ((^) b) {0..qb} < b * b ^ qb" +then have f1: "sum ((^) b) {0..qb} < b ^ Suc qb" + by fastforce +have "b ^ Suc qb * 2 < b ^ Suc (Suc qb)" + using assms by force +then have "2 * b ^ Suc qb < b ^ Suc (Suc qb)" + by simp +then have "b ^ Suc qb + sum ((^) b) {0..qb} < b ^ Suc (Suc qb)" + using f1 by linarith +then show "sum ((^) b) {0..qb} + b * b ^ qb < b * (b * b ^ qb)" + by simp +qed + +lemma mult_to_bitAND_state: + assumes cells_bounded: "cells_bounded ic p c" +and c: "c > 1" +and b: "b = B c" + +shows "(\t=0..q. b^t * ((1 - Z ic p l t) * S ic p k t)) + = ((\t = 0..q. b^t) - ZLe ic p b q l) && SKe ic p b q k" +proof (induction q arbitrary: ic p c l k) + case 0 + show ?case using Z_def S_def ZLe_def SKe_def by auto +next + case (Suc q) + + have b4: "b > 2" using assms(2-3) apply (auto simp add: B_def) + by (metis One_nat_def Suc_less_eq2 lessI numeral_2_eq_2 power_gt1) + + have ske: "SKe ic p b q k < b ^ (Suc q)" using SKe_bounded b4 by auto + have zle: "ZLe ic p b q l < b ^ (Suc q)" using ZLe_bounded b4 by auto + define cst where "cst \ Suc q" + define e where "e \ \t = 0..Suc q. b^t" + + have "(\t = 0..q. b^t) < b ^ (Suc q)" + using sum_bt b4 by auto + hence zle2: "(\t = 0..q. b^t) - ZLe ic p b q l < b ^ (Suc q)" + using less_imp_diff_less by blast + + have "(\t = 0..x. b^t) - ZLe ic p b x l = (\t=0..x. b^t - b^t * Z ic p l t)" for x + unfolding ZLe_def + using Z_bounded sum_subtractf_nat[where ?f = "(^) b" and ?g = "\t. b ^ t * Z ic p l t"] + by auto + hence aux_sum: "(\t = 0..x. b^t) - ZLe ic p b x l = (\t=0..x. b^t * (1 - Z ic p l t))" for x + using diff_Suc_1 diff_mult_distrib2 by auto + + have aux1: "b ^(Suc q) * (1 - Z ic p l (Suc q)) + (\t=0..q. b^t * (1 - Z ic p l t)) + = (\t = 0..cst. b ^ t * (1 - Z ic p l t))" + by (auto simp: sum.atLeast0_atMost_Suc cst_def) + also have aux2: "... = (\t = 0..cst. b ^ t) - ZLe ic p b cst l" + unfolding e_def ZLe_def using aux_sum[of "cst"] + by (auto simp: ZLe_def) + finally have aux_add_sub: + "(b ^(Suc q) * (1 - Z ic p l (Suc q)) + ((\t = 0..q. b^t) - ZLe ic p b q l)) + = (e - ZLe ic p b (Suc q) l)" + by (auto simp: cst_def e_def aux_sum) + + hence ih: "(\t = 0..q. b ^ t * ((1 - Z ic p l t) * S ic p k t)) + = (\t = 0..q. b^t) - ZLe ic p b q l && SKe ic p b q k" + using Suc[of "ic" "p" "l" "k"] by auto + + have "(\t = 0..Suc q. b ^ t * ((1 - Z ic p l t) * S ic p k t)) + = (\t = 0.. q. b ^ t * ((1 - Z ic p l t) * S ic p k t)) + + b^(Suc q) * ((1 - Z ic p l (Suc q)) * S ic p k (Suc q))" + by (auto cong: sum.cong) + + also have "... = ((\t = 0..q. b^t) - ZLe ic p b q l && SKe ic p b q k) + + b^(Suc q) * ((1 - Z ic p l (Suc q)) * S ic p k (Suc q))" + using ih by auto + + also have "... = ((\t = 0..q. b^t) - ZLe ic p b q l && SKe ic p b q k) + + b^(Suc q) * ((1 - Z ic p l (Suc q)) && S ic p k (Suc q))" + using bitAND_single_bit_mult_equiv by (simp add: S_def) + + also have "... = (b ^(Suc q) * (1 - Z ic p l (Suc q)) + ((\t = 0..q. b^t) - ZLe ic p b q l)) + && (b ^ (Suc q) * S ic p k (Suc q) + SKe ic p b q k)" + using bitAND_linear ske zle2 B_def b + by (smt add_ac(2) mult_ac(2) bitAND_linear power.simps(2) power_mult power_mult_distrib) + also have "... = (e - ZLe ic p b (Suc q) l && SKe ic p b (Suc q) k)" + using SKe_def aux_add_sub by (auto simp: add.commute) + + finally show ?case by (auto simp: e_def) +qed + +end diff --git a/thys/DPRM_Theorem/Register_Machine/RegisterMachineSpecification.thy b/thys/DPRM_Theorem/Register_Machine/RegisterMachineSpecification.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Register_Machine/RegisterMachineSpecification.thy @@ -0,0 +1,124 @@ +section \Register Machines\ + +subsection \Register Machine Specification\ +theory RegisterMachineSpecification + imports Main +begin + +subsubsection \Basic Datatype Definitions\ + +text \The following specification of register machines is inspired by @{cite "mech_turing"} (see + @{cite "mech_turing_afp"} for the corresponding AFP article).\ + +(* Type synonyms for registers (= register indices) the "tape" (sim. to a + * Turing machine) that contains a list of register values. + *) +type_synonym register = nat +type_synonym tape = "register list" + +(* The register machine understands "instructions" that operate on state(-id)s + * and modify register(-id)s. The machine stops at the HALT instruction. + *) +type_synonym state = nat +datatype instruction = + isadd: Add (modifies : register) (goes_to : state) | + issub: Sub (modifies : register) (goes_to : state) (goes_to_alt : state) | + ishalt: Halt +where + "modifies Halt = 0" | + "goes_to_alt (Add _ next) = next" + +(* A program, then, just becomes a list of these instructions *) +type_synonym program = "instruction list" + +(* A configuration of the (runtime of) a machine encodes information about the + * instruction and the state of the registers (i.e., the tape). We describe it + * here as a tuple. + *) +type_synonym configuration = "(state * tape)" + +subsubsection \Essential Functions to operate the Register Machine\ + +(* Given a tape of register values and some instruction(s) the register + * machine first reads the value of the register from the tape (by convention + * assume that the value "read" by the HALT state is zero). The machine then, + * fetches the next instruction from the program, and finally updates the + * tape to reflect changes by the last instruction. + *) + +definition read :: "tape \ program \ state \ nat" + where "read t p s = t ! (modifies (p!s))" + +definition fetch :: "state \ program \ nat \ state" where + "fetch s p v = (if issub (p!s) \ v = 0 then goes_to_alt (p!s) + else if ishalt (p!s) then s + else goes_to (p!s))" + +definition update :: "tape \ instruction \ tape" where + "update t i = (if ishalt i then t + else if isadd i then list_update t (modifies i) (t!(modifies i) + 1) + else list_update t (modifies i) (if t!(modifies i) = 0 then 0 else (t!(modifies i)) - 1) )" + +definition step :: "configuration \ program \ configuration" + where + "(step ic p) = (let nexts = fetch (fst ic) p (read (snd ic) p (fst ic)); + nextt = update (snd ic) (p!(fst ic)) + in (nexts, nextt))" + +fun steps :: "configuration \ program \ nat \ configuration" + where + steps_zero: "(steps c p 0) = c" + | steps_suc: "(steps c p (Suc n)) = (step (steps c p n) p)" + + +subsubsection \Validity Checks and Assumptions\ + +(* check bound for each type of instruction *) +(* take a m representing the upper bound for state number *) +fun instruction_state_check :: "nat \ instruction \ bool" + where isc_halt: "instruction_state_check _ Halt = True" + | isc_add: "instruction_state_check m (Add _ ns) = (ns < m)" + | isc_sub: "instruction_state_check m (Sub _ ns1 ns2) = ((ns1 < m) & (ns2 < m))" + +fun instruction_register_check :: "nat \ instruction \ bool" + where "instruction_register_check _ Halt = True" + | "instruction_register_check n (Add reg _) = (reg < n)" + | "instruction_register_check n (Sub reg _ _) = (reg < n)" + +(* passes function via currying into list_all *) +fun program_state_check :: "program \ bool" + where "program_state_check p = list_all (instruction_state_check (length p)) p" + +fun program_register_check :: "program \ nat \ bool" + where "program_register_check p n = list_all (instruction_register_check n) p" + +fun tape_check_initial :: "tape \ nat \ bool" + where "tape_check_initial t a = (t \ [] \ t!0 = a \ (\l>0. t ! l = 0))" + +fun program_includes_halt :: "program \ bool" + where "program_includes_halt p = (length p > 1 \ ishalt (p ! (length p -1)) \ (\k ishalt (p!k)))" + +text \Is Valid and Terminates\ + +definition is_valid + where "is_valid c p = (program_includes_halt p \ program_state_check p + \ (program_register_check p (length (snd c))))" + +definition is_valid_initial + where "is_valid_initial c p a = ((is_valid c p) + \ (tape_check_initial (snd c) a) + \ (fst c = 0))" + +definition correct_halt + where "correct_halt c p q = (ishalt (p ! (fst (steps c p q))) \ \halting\ + \ (\l<(length (snd c)). snd (steps c p q) ! l = 0))" + +definition terminates :: "configuration \ program \ nat \ bool" + where "terminates c p q = ((q>0) + \ (correct_halt c p q) + \ (\x ishalt (p ! (fst (steps c p x)))))" + +definition initial_config :: "nat \ nat \ configuration" where + "initial_config n a = (0, (a # replicate n 0))" + +end diff --git a/thys/DPRM_Theorem/Register_Machine/SingleStepRegister.thy b/thys/DPRM_Theorem/Register_Machine/SingleStepRegister.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Register_Machine/SingleStepRegister.thy @@ -0,0 +1,143 @@ +subsection \Single step relations\ + +subsubsection \Registers\ + +theory SingleStepRegister + imports RegisterMachineSimulation +begin + +lemma single_step_add: + fixes c :: configuration + and p :: program + and l :: register + and t a :: nat + +defines "cs \ fst (steps c p t)" + +assumes is_val: "is_valid_initial c p a" + and l: "l < length tape" + +shows "(\R+ p l (\k. S c p k t)) + = (if isadd (p!cs) \ l = modifies (p!cs) then 1 else 0)" +proof - + have ic: "c = (0, snd c)" + using is_val by (auto simp add: is_valid_initial_def) (metis prod.collapse) + + have add_if: "(\k = 0..length p-1. if isadd (p ! k) \ modifies (p ! cs) = modifies (p ! k) + then S c p k t else 0) + = (\k = 0..length p-1. if k=cs then + if isadd (p ! k) \ modifies (p ! cs) = modifies (p ! k) then S c p k t else 0 else 0)" + apply (rule sum.cong) + using S_unique cs_def by auto + + have bound: "fst (steps c p t) \ length p - 1" using is_val ic p_contains[of "c" "p" "a" "t"] + by (auto simp add: dual_order.strict_implies_order) + + thus ?thesis using S_unique add_if + apply (auto simp add: sum_radd.simps add_if S_def cs_def) + by (smt S_def sum.cong) +qed + +lemma single_step_sub: + fixes c :: configuration + and p :: program + and l :: register + and t a :: nat + +defines "cs \ fst (steps c p t)" + +assumes is_val: "is_valid_initial c p a" + +shows "(\R- p l (\k. Z c p l t * S c p k t)) + = (if issub (p!cs) \ l = modifies (p!cs) then Z c p l t else 0)" +proof - + have "fst c = 0" using is_val by (auto simp add: is_valid_initial_def) + hence ic: "c = (0, snd c)" by (metis prod.collapse) + + have bound: "cs \ length p - 1" using is_val ic p_contains[of "c" "p" "a" "t"] + by (auto simp add: dual_order.strict_implies_order cs_def) + + have sub_if: "(\k = 0..length p-1. if issub (p ! k) \ modifies (p ! cs) = modifies (p ! k) + then 1 * (if cs = k then (Suc 0) else 0) else 0) + =(\k = 0..length p-1. if k = cs then + (if issub (p ! k) \ modifies (p ! cs) = modifies (p ! k) + then (Suc 0) * (if cs = k then (Suc 0) else 0) + else 0) else 0)" + apply (rule sum.cong) using cs_def by auto + + show ?thesis using bound sub_if + apply (auto simp add: sum_rsub.simps cs_def Z_def S_def R_def) + by (metis One_nat_def cs_def) +qed + +lemma lm04_06_one_step_relation_register_old: + fixes l::register + and ic::configuration + and p::program + + defines "s \ fst ic" + and "tape \ snd ic" + + defines "m \ length p" + and "tape' \ snd (step ic p)" + + assumes is_val: "is_valid ic p" + and l: \l < length tape\ + + shows "(tape'!l) = (tape!l) + (if isadd (p!s) \ l = modifies (p!s) then 1 else 0) + - Z ic p l 0 * (if issub (p!s) \ l = modifies (p!s) then 1 else 0)" +proof - + show ?thesis + using l + apply (cases \p!s\) + apply (auto simp: assms(1-4) step_def update_def) + using nth_digit_0 by (auto simp add: Z_def R_def) +qed + +(* [T] 4.6 *) +lemma lm04_06_one_step_relation_register: + fixes l :: register + and c :: configuration + and p :: program + and t :: nat + and a :: nat + +defines "r \ R c p" +defines "s \ S c p" + +assumes is_val: "is_valid_initial c p a" + and l: "l < length (snd c)" + + shows "r l (Suc t) = r l t + (\R+ p l (\k. s k t)) + - (\R- p l (\k. (Z c p l t) * s k t))" +proof - + define cs where "cs \ fst (steps c p t)" + + have add: "(\R+ p l (\k. s k t)) + = (if isadd (p!cs) \ l = modifies (p!cs) then 1 else 0)" + using single_step_add[of "c" "p" "a" "l" "snd c" "t"] is_val l s_def cs_def by auto + + have sub: "(\R- p l (\k. Z c p l t * s k t)) + = (if issub (p!cs) \ l = modifies (p!cs) then Z c p l t else 0)" + using single_step_sub is_val l s_def cs_def Z_def R_def by auto + + have lhs: "r l (Suc t) = snd (steps c p (Suc t)) ! l" + by (simp add: r_def R_def del: steps.simps) + + have rhs: "r l t = snd (steps c p t) ! l" + by (simp add: r_def R_def del: steps.simps) + + have valid_time: "is_valid (steps c p t) p" using steps_is_valid_invar is_val + by (auto simp add: is_valid_initial_def) + + have l_time: "l < length (snd (steps c p t))" using l steps_tape_length_invar by auto + + from lhs rhs have "r l (Suc t) = r l t + (if isadd (p!cs) \ l = modifies (p!cs) then 1 else 0) + - (if issub (p!cs) \ l = modifies (p!cs) then Z c p l t else 0)" + using l_time valid_time lm04_06_one_step_relation_register_old steps.simps cs_def nth_digit_0 + Z_def R_def by auto + + thus ?thesis using add sub by simp +qed + +end diff --git a/thys/DPRM_Theorem/Register_Machine/SingleStepState.thy b/thys/DPRM_Theorem/Register_Machine/SingleStepState.thy new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/Register_Machine/SingleStepState.thy @@ -0,0 +1,79 @@ +subsubsection \States\ + +theory SingleStepState + imports RegisterMachineSimulation +begin + +lemma lm04_07_one_step_relation_state: + fixes d :: state + and c :: configuration + and p :: program + and t :: nat + and a :: nat + +defines "r \ R c p" +defines "s \ S c p" +defines "z \ Z c p" +defines "cs \ fst (steps c p t)" + +assumes is_val: "is_valid_initial c p a" + and "d < length p" + +shows "s d (Suc t) = (\S+ p d (\k. s k t)) + + (\S- p d (\k. z (modifies (p!k)) t * s k t)) + + (\S0 p d (\k. (1 - z (modifies (p!k)) t) * s k t)) + + (if ishalt (p!cs) \ d = cs then Suc 0 else 0)" +proof - + have ic: "c = (0, snd c)" + using is_val by (auto simp add: is_valid_initial_def) (metis prod.collapse) + have cs_bound: "cs < length p" using ic is_val p_contains[of "c" "p" "a" "t"] cs_def by auto + + have "(\k = 0..length p-1. + if isadd (p ! k) \ goes_to (p ! fst (steps c p t)) = goes_to (p ! k) + then if fst (steps c p t) = k + then Suc 0 else 0 else 0) + =(\k = 0..length p-1. + if fst (steps c p t) = k + then if isadd (p ! k) \ goes_to (p ! fst (steps c p t)) = goes_to (p ! k) + then Suc 0 else 0 else 0)" + apply (rule sum.cong) by auto + hence add: "(\S+ p d (\k. s k t)) = (if isadd (p!cs) \ d = goes_to (p!cs) then Suc 0 else 0)" + apply (auto simp add: sum_sadd.simps s_def S_def cs_def) + using cs_bound cs_def by auto + + have "(\k = 0..length p-1. + if issub (p ! k) \ goes_to (p ! fst (steps c p t)) = goes_to (p ! k) + then z (modifies (p ! k)) t * (if fst (steps c p t) = k then Suc 0 else 0) else 0) + = (\k = 0..length p-1. if k=cs then + if issub (p ! k) \ goes_to (p ! fst (steps c p t)) = goes_to (p ! k) + then z (modifies (p ! k)) t else 0 else 0)" + apply (rule sum.cong) + using z_def Z_def cs_def by auto + hence sub_zero: "(\S- p d (\k. z (modifies (p!k)) t * s k t)) + = (if issub (p!cs) \ d = goes_to (p!cs) then z (modifies (p!cs)) t else 0)" + apply (auto simp add: sum_ssub_nzero.simps s_def S_def cs_def) + using cs_bound cs_def by auto + + have "(\k = 0..length p-1. + if issub (p ! k) \ goes_to_alt (p ! fst (steps c p t)) = goes_to_alt (p ! k) + then (Suc 0 - z (modifies (p ! k)) t) * (if fst (steps c p t) = k then Suc 0 else 0) else 0) + = (\k = 0..length p-1. if k=cs then + if issub (p ! k) \ goes_to_alt (p ! fst (steps c p t)) = goes_to_alt (p ! k) + then (Suc 0 - z (modifies (p ! k)) t) else 0 else 0)" + apply (rule sum.cong) using z_def Z_def cs_def by auto + hence sub_nzero: "(\S0 p d (\k. (1 - z (modifies (p!k)) t) * s k t)) + = (if issub (p!cs) \ d = goes_to_alt (p!cs) then (1 - z (modifies (p!cs)) t) else 0)" + apply (auto simp: sum_ssub_zero.simps s_def S_def cs_def) + using cs_bound cs_def by auto + + have "s d (Suc t) = (if isadd (p!cs) \ d = goes_to (p!cs) then Suc 0 else 0) + + (if issub (p!cs) \ d = goes_to (p!cs) then z (modifies (p!cs)) t else 0) + + (if issub (p!cs) \ d = goes_to_alt (p!cs) then (1 - z (modifies (p!cs)) t) else 0) + + (if ishalt (p!cs) \ d = cs then Suc 0 else 0)" + apply (cases "p!cs") + by (auto simp: s_def S_def step_def fetch_def cs_def z_def Z_def Z_bounded R_def read_def) + + thus ?thesis using add sub_zero sub_nzero by auto +qed + +end diff --git a/thys/DPRM_Theorem/document/root.bib b/thys/DPRM_Theorem/document/root.bib new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/document/root.bib @@ -0,0 +1,123 @@ +@InProceedings{h10lecturenotes, + author = "Yuri Matiyasevich", + title = "On {H}ilbert's Tenth Problem", + publisher = "Pacific Institute for the Mathematical Sciences", + year = "2000", + editor = "Michael Lamoureux", + booktitle = "PIMS Distinguished Chair Lectures", + volume = "1" +} + +@InProceedings{cicm, + author="Bayer, Jonas + and David, Marco + and Pal, Abhik + and Stock, Benedikt", + editor="Kaliszyk, Cezary + and Brady, Edwin + and Kohlhase, Andrea + and Sacerdoti Coen, Claudio", + title="Beginners' Quest to Formalize Mathematics: A Feasibility Study in {I}sabelle", + booktitle="Intelligent Computer Mathematics", + year="2019", + publisher="Springer International Publishing", + address="Cham", + pages="16--27", + abstract="How difficult are interactive theorem provers to use? We respond by reviewing the formalization of Hilbert's tenth problem in Isabelle/HOL carried out by an undergraduate research group at Jacobs University Bremen. We argue that, as demonstrated by our example, proof assistants are feasible for beginners to formalize mathematics. With the aim to make the field more accessible, we also survey hurdles that arise when learning an interactive theorem prover. Broadly, we advocate for an increased adoption of interactive theorem provers in mathematical research and curricula.", + isbn="978-3-030-23250-4" +} + +@InProceedings{dprm_isabelle, + author = {Jonas Bayer and Marco David and Abhik Pal and Benedikt Stock and Dierk Schleicher}, + title = {{The DPRM Theorem in Isabelle (Short Paper)}}, + booktitle = {10th International Conference on Interactive Theorem Proving (ITP 2019)}, + pages = {33:1--33:7}, + series = {Leibniz International Proceedings in Informatics (LIPIcs)}, + ISBN = {978-3-95977-122-1}, + ISSN = {1868-8969}, + year = {2019}, + volume = {141}, + editor = {John Harrison and John O'Leary and Andrew Tolmach}, + publisher = {Schloss Dagstuhl--Leibniz-Zentrum fuer Informatik}, + address = {Dagstuhl, Germany}, + URL = {http://drops.dagstuhl.de/opus/volltexte/2019/11088}, + doi = {10.4230/LIPIcs.ITP.2019.33} +} + +@article{dprm_mizar1, + title = {The {M}atiyasevich Theorem. Preliminaries}, + volume = {25}, + url = {https://www.sciendo.com/article/10.1515/forma-2017-0029}, + doi = {10.1515/forma-2017-0029}, + pages = {315--322}, + number = {4}, + journal = {Formalized Mathematics}, + author = {Pak, Karol}, + urldate = {2021-06-20}, + date = {2018-03-28}, + year = {2018}, +} + +@article{dprm_mizar2, + title = {Diophantine sets. Preliminaries}, + volume = {26}, + url = {https://www.sciendo.com/article/10.2478/forma-2018-0007}, + doi = {10.2478/forma-2018-0007}, + pages = {81--90}, + number = {1}, + journal = {Formalized Mathematics}, + author = {Pak, Karol}, + year = {2018}, + urldate = {2021-06-20}, + date = {2018-07-28}, +} + +@InProceedings{dprm_coq, + author = {Dominique Larchey-Wendling and Yannick Forster}, + title = {{Hilbert's Tenth Problem in Coq}}, + booktitle = {4th International Conference on Formal Structures for Computation and Deduction (FSCD 2019)}, + pages = {27:1--27:20}, + series = {Leibniz International Proceedings in Informatics (LIPIcs)}, + ISBN = {978-3-95977-107-8}, + ISSN = {1868-8969}, + year = {2019}, + volume = {131}, + editor = {Herman Geuvers}, + publisher = {Schloss Dagstuhl--Leibniz-Zentrum fuer Informatik}, + address = {Dagstuhl, Germany}, + URL = {http://drops.dagstuhl.de/opus/volltexte/2019/10534}, + URN = {urn:nbn:de:0030-drops-105342}, + doi = {10.4230/LIPIcs.FSCD.2019.27}, + annote = {Keywords: Hilbert's tenth problem, Diophantine equations, undecidability, computability theory, reduction, Minsky machines, Fractran, Coq, type theory} +} + +@unpublished{dprm_lean, + author = {Carneiro, Mario}, + year = {2018}, + month = {02}, + title = {A {L}ean formalization of {M}atiyasevi\v{c}'s Theorem}, + note="\url{https://arxiv.org/abs/1802.01795v1}", +} + +@InProceedings{mech_turing, + author="Xu, Jian and Zhang, Xingyuan and Urban, Christian", + editor="Blazy, Sandrine and Paulin-Mohring, Christine and Pichardie, David", + title="Mechanising {T}uring Machines and Computability Theory in {I}sabelle/{HOL}", + booktitle="Interactive Theorem Proving. ITP 2013.", + series="Lecture Notes in Computer Science", + volume="7998", + year="2013", + publisher="Springer Berlin, Heidelberg", + pages="147--162" +} + +@article{mech_turing_afp, + author = {Jian Xu and Xingyuan Zhang and Christian Urban and Sebastiaan J. C. Joosten}, + title = {Universal {T}uring Machine}, + journal = {Archive of Formal Proofs}, + month = feb, + year = 2019, + note = {\url{https://isa-afp.org/entries/Universal_Turing_Machine.html}, + Formal proof development}, + ISSN = {2150-914x}, +} \ No newline at end of file diff --git a/thys/DPRM_Theorem/document/root.log b/thys/DPRM_Theorem/document/root.log new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/document/root.log @@ -0,0 +1,47 @@ +This is pdfTeX, Version 3.141592653-2.6-1.40.22 (MiKTeX 21.3) (preloaded format=pdflatex 2021.3.17) 22 DEC 2021 11:27 +entering extended mode +**./root.tex +(root.tex +LaTeX2e <2020-10-01> patch level 4 +L3 programming layer <2021-02-18> xparse <2020-03-03> +(C:\Users\jonas\AppData\Local\Programs\MiKTeX\tex/latex/base\article.cls +Document Class: article 2020/04/10 v1.4m Standard LaTeX document class +(C:\Users\jonas\AppData\Local\Programs\MiKTeX\tex/latex/base\size11.clo +File: size11.clo 2020/04/10 v1.4m Standard LaTeX file (size option) +) +\c@part=\count179 +\c@section=\count180 +\c@subsection=\count181 +\c@subsubsection=\count182 +\c@paragraph=\count183 +\c@subparagraph=\count184 +\c@figure=\count185 +\c@table=\count186 +\abovecaptionskip=\skip47 +\belowcaptionskip=\skip48 +\bibindent=\dimen138 +) + +! LaTeX Error: File `isabelle.sty' not found. + +Type X to quit or to proceed, +or enter new name. (Default extension: sty) + +Enter file name: +! Emergency stop. + + +l.3 + +*** (cannot \read from terminal in nonstop modes) + + +Here is how much of TeX's memory you used: + 220 strings out of 479334 + 2664 string characters out of 2857084 + 285137 words of memory out of 3000000 + 17766 multiletter control sequences out of 15000+200000 + 403730 words of font info for 28 fonts, out of 3000000 for 9000 + 1141 hyphenation exceptions out of 8191 + 44i,0n,50p,156b,36s stack positions out of 5000i,500n,10000p,200000b,50000s +! ==> Fatal error occurred, no output PDF file produced! diff --git a/thys/DPRM_Theorem/document/root.tex b/thys/DPRM_Theorem/document/root.tex new file mode 100644 --- /dev/null +++ b/thys/DPRM_Theorem/document/root.tex @@ -0,0 +1,105 @@ +\documentclass[11pt,a4paper]{article} +\usepackage{isabelle,isabellesym} +\usepackage{authblk} + +% further packages required for unusual symbols (see also +% isabellesym.sty), use only when needed + +%\usepackage{amssymb} + %for \, \, \, \, \, \, + %\, \, \, \, \, + %\, \, \ + +%\usepackage{eurosym} + %for \ + +%\usepackage[only,bigsqcap]{stmaryrd} + %for \ + +%\usepackage{eufrak} + %for \ ... \, \ ... \ (also included in amssymb) + +%\usepackage{textcomp} + %for \, \, \, \, \, + %\ + +% this should be the last package used +\usepackage{pdfsetup} + +% urls in roman style, theory text in math-similar italics +\urlstyle{rm} +\isabellestyle{it} + +% for uniform font size +%\renewcommand{\isastyle}{\isastyleminor} + + +\begin{document} + +\title{Diophantine Equations and the DPRM Theorem} + +\author{Jonas Bayer\thanks{Equal contribution.} \hspace*{10ex} Marco David\textsuperscript{*} + \hspace*{10ex} Benedikt Stock\textsuperscript{*} \\ Abhik Pal + \hspace*{10ex} Yuri Matiyasevich\thanks{Contributed by supplying a detailed proof and an + initial introduction to Isabelle.} + \hspace*{10ex} Dierk Schleicher} + +\maketitle + +%\footnotetext[*]{Text} + +\begin{abstract} + We present a formalization of Matiyasevich's proof of the DPRM theorem, which states that every + recursively enumerable set of natural numbers is Diophantine. This result from 1970 yields a + negative solution to Hilbert's 10th problem over the integers. To represent recursively + enumerable sets in equations, we implement and arithmetize register machines. We formalize a + general theory of Diophantine sets and relations to reason about them abstractly. + Using several number-theoretic lemmas, we prove that exponentiation has a Diophantine + representation. +\end{abstract} + +\tableofcontents + +\newpage + +% sane default for proof documents +\parindent 0pt\parskip 0.5ex + +% Some preliminary text +\paragraph{Overview} +A previous short paper~\cite{dprm_isabelle} gives an overview +of the formalization. In particular, the challenges of implementing the notion of +diophantine predicates is discussed and a formal definition of register machines is described. +Another meta-publication~\cite{cicm} recounts our learning experience throughout this project. + +The present formalisation is based on Yuri Matiyasevich's monograph~\cite{h10lecturenotes} which +contains a full proof of the DPRM theorem. This result or parts of its proof have also been +formalized in other interactive theorem provers, notably in Coq~\cite{dprm_coq}, +Lean~\cite{dprm_lean} and Mizar~\cite{dprm_mizar1,dprm_mizar2}. + +\paragraph{Acknowledgements} +We want to thank everyone who participated in the formalization +during the early stages of this project: +Deepak Aryal, Bogdan Ciurezu, Yiping Deng, Prabhat Devkota, +Simon Dubischar, Malte Haßler, Yufei Liu and Maria Antonia Oprea. Moreover, we would like to +express our sincere gratitude to the entire welcoming and supportive Isabelle +community. In particular, we are indebted to Christoph Benzmüller for his +expertise, his advice and for connecting us with relevant experts in the field. +Among those, we specially want to thank Mathias Fleury for all his help with Isabelle. +Finally, we would like to thank the DFG for supporting our attendance at several events and conferences, allowing us to present the project to a broad audience. + +\newpage + +% 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/Finite_Fields/Card_Irreducible_Polynomials.thy b/thys/Finite_Fields/Card_Irreducible_Polynomials.thy new file mode 100644 --- /dev/null +++ b/thys/Finite_Fields/Card_Irreducible_Polynomials.thy @@ -0,0 +1,231 @@ +subsection \Gauss Formula\label{sec:card_irred}\ + +theory Card_Irreducible_Polynomials + imports + Dirichlet_Series.Moebius_Mu + Card_Irreducible_Polynomials_Aux +begin + +hide_const "Polynomial.order" + +text \The following theorem is a slightly generalized form of the formula discovered by +Gauss for the number of monic irreducible polynomials over a finite field. He originally verified +the result for the case when @{term "R"} is a simple prime field. +The version of the formula here for the case where @{term "R"} may be an arbitrary finite field can +be found in Chebolu and Min{\'a}{\v{c}}~\cite{chebolu2010}.\ + +theorem (in finite_field) card_irred: + assumes "n > 0" + shows "n * card {f. monic_irreducible_poly R f \ degree f = n} = + (\d | d dvd n. moebius_mu d * (order R^(n div d)))" + (is "?lhs = ?rhs") +proof - + have "?lhs = dirichlet_prod moebius_mu (\x. int (order R) ^ x) n" + using card_irred_aux + by (intro moebius_inversion assms) (simp flip:of_nat_power) + also have "... = ?rhs" + by (simp add:dirichlet_prod_def) + finally show ?thesis by simp +qed + +text \In the following an explicit analytic lower bound for the cardinality of monic irreducible +polynomials is shown, with which existence follows. This part deviates from the classic approach, +where existence is verified using a divisibility argument. The reason for the deviation is that an +analytic bound can also be used to estimate the runtime of a randomized algorithm selecting an +irreducible polynomial, by randomly sampling monic polynomials.\ + +lemma (in finite_field) card_irred_1: + "card {f. monic_irreducible_poly R f \ degree f = 1} = order R" +proof - + have "int (1 * card {f. monic_irreducible_poly R f \ degree f = 1}) + = int (order R)" + by (subst card_irred, auto) + thus ?thesis by simp +qed + +lemma (in finite_field) card_irred_2: + "real (card {f. monic_irreducible_poly R f \ degree f = 2}) = + (real (order R)^2 - order R) / 2" +proof - + have "x dvd 2 \ x = 1 \ x = 2" for x :: nat + using nat_dvd_not_less[where m="2"] + by (metis One_nat_def even_zero gcd_nat.strict_trans2 + less_2_cases nat_neq_iff pos2) + hence a: "{d. d dvd 2} = {1,2::nat}" + by (auto simp add:set_eq_iff) + + have "2*real (card {f. monic_irreducible_poly R f \ degree f = 2}) + = of_int (2* card {f. monic_irreducible_poly R f \ degree f = 2})" + by simp + also have "... = + of_int (\d | d dvd 2. moebius_mu d * int (order R) ^ (2 div d))" + by (subst card_irred, auto) + also have "... = order R^2 - int (order R)" + by (subst a, simp) + also have "... = real (order R)^2 - order R" + by simp + finally have + "2 * real (card {f. monic_irreducible_poly R f \ degree f = 2}) = + real (order R)^2 - order R" + by simp + thus ?thesis by simp +qed + +lemma (in finite_field) card_irred_gt_2: + assumes "n > 2" + shows "real (order R)^n / (2*real n) \ + card {f. monic_irreducible_poly R f \ degree f = n}" + (is "?lhs \ ?rhs") +proof - + let ?m = "real (order R)" + have a:"?m \ 2" + using finite_field_min_order by simp + + have b:"moebius_mu n \ -(1::real)" for n :: nat + using abs_moebius_mu_le[where n="n"] + unfolding abs_le_iff by auto + + have c: "n > 0" using assms by simp + have d: "x < n - 1" if d_assms: "x dvd n" "x \ n" for x :: nat + proof - + have "x < n" + using d_assms dvd_nat_bounds c by auto + moreover have "\(n-1 dvd n)" using assms + by (metis One_nat_def Suc_diff_Suc c diff_zero + dvd_add_triv_right_iff nat_dvd_1_iff_1 + nat_neq_iff numeral_2_eq_2 plus_1_eq_Suc) + hence "x \ n-1" using d_assms by auto + ultimately show "x < n-1" by simp + qed + + have "?m^n / 2 = ?m^n - ?m^n/2" by simp + also have "... \ ?m^n - ?m^n/?m^1" + using a by (intro diff_mono divide_left_mono, simp_all) + also have "... \ ?m^n - ?m^(n-1)" + using a c by (subst power_diff, simp_all) + also have "... \ ?m^n - (?m^(n-1) - 1)/1" by simp + also have "... \ ?m^n - (?m^(n-1)-1)/(?m-1)" + using a by (intro diff_left_mono divide_left_mono, simp_all) + also have "... = ?m^n - (\i \ {.. ?m^n - (\i \ {k. k dvd n \ k \ n}. ?m^i)" + using d + by (intro diff_mono sum_mono2 subsetI, auto simp add:not_less) + also have "... = ?m^n + (\i \ {k. k dvd n \ k \ n}. (-1) * ?m^i)" + by (subst sum_distrib_left[symmetric], simp) + also have "... \ moebius_mu 1 * ?m^n + + (\i \ {k. k dvd n \ k \ n}. moebius_mu (n div i) * ?m^i)" + using b + by (intro add_mono sum_mono mult_right_mono) + (simp_all add:not_less) + also have "... = (\i \ insert n {k. k dvd n \ k \ n}. + moebius_mu (n div i) * ?m^i)" + using c by (subst sum.insert, auto) + also have "... = (\i \ {k. k dvd n}. moebius_mu (n div i) * ?m^i)" + by (intro sum.cong, auto simp add:set_eq_iff) + also have "... = dirichlet_prod (\i. ?m^i) moebius_mu n" + unfolding dirichlet_prod_def by (intro sum.cong, auto) + also have "... = dirichlet_prod moebius_mu (\i. ?m^i) n" + using dirichlet_prod_moebius_commute by metis + also have "... = + of_int (\d | d dvd n. moebius_mu d * order R^(n div d))" + unfolding dirichlet_prod_def by simp + also have "... = of_int (n * + card {f. monic_irreducible_poly R f \ length f - 1 = n})" + using card_irred[OF c] by simp + also have "... = n * ?rhs" by simp + finally have "?m^n / 2 \ n * ?rhs" by simp + hence "?m ^ n \ 2 * n * ?rhs" by simp + hence "?m^n/(2*real n) \ ?rhs" + using c by (subst pos_divide_le_eq, simp_all add:algebra_simps) + thus ?thesis by simp +qed + +lemma (in finite_field) exist_irred: + assumes "n > 0" + obtains f where "monic_irreducible_poly R f" "degree f = n" +proof - + consider (i) "n = 1" | (ii) "n = 2" | (iii) "n>2" + using assms by linarith + then have + "card {f. monic_irreducible_poly R f \ degree f = n} > 0" + (is "card ?A > 0") + proof (cases) + case i + hence "card ?A = order R" + using card_irred_1 by simp + also have "... > 0" + using finite_field_min_order by simp + finally show ?thesis by simp + next + case ii + have "0 < (real (order R) * (real (order R) - 1)) / 2" + using finite_field_min_order by simp + also have "... = (real (order R)^2 - order R) / 2" + by (simp add:power2_eq_square algebra_simps) + also have "... = real (card ?A)" + using ii by (subst card_irred_2[symmetric], simp) + finally have " 0 < real (card ?A)" by simp + then show ?thesis by simp + next + case iii + have "0 < real (order R)^n / (2*real n)" + using finite_field_min_order assms by simp + also have "... \ real (card ?A)" + using iii card_irred_gt_2 by simp + finally have "0 < real (card ?A)" by simp + then show ?thesis by simp + qed + hence "?A \ {}" + by (metis card.empty nless_le) + then obtain f where "monic_irreducible_poly R f" "degree f = n" + by auto + thus ?thesis using that by simp +qed + +theorem existence: + assumes "n > 0" + assumes "Factorial_Ring.prime p" + shows "\(F:: int set list set ring). finite_field F \ order F = p^n" +proof - + interpret zf: finite_field "ZFact (int p)" + using zfact_prime_is_finite_field assms by simp + + interpret zfp: polynomial_ring "ZFact p" "carrier (ZFact p)" + unfolding polynomial_ring_def polynomial_ring_axioms_def + using zf.field_axioms zf.carrier_is_subfield by simp + + have p_gt_0: "p > 0" using prime_gt_0_nat assms(2) by simp + + obtain f where f_def: + "monic_irreducible_poly (ZFact (int p)) f" + "degree f = n" + using zf.exist_irred assms by auto + + let ?F = "Rupt\<^bsub>(ZFact p)\<^esub> (carrier (ZFact p)) f" + have "f \ carrier (poly_ring (ZFact (int p)))" + using f_def(1) zf.monic_poly_carr + unfolding monic_irreducible_poly_def + by simp + moreover have "degree f > 0" + using assms(1) f_def by simp + ultimately have "order ?F = card (carrier (ZFact p))^degree f" + by (intro zf.rupture_order[OF zf.carrier_is_subfield]) auto + hence a:"order ?F = p^n" + unfolding f_def(2) card_zfact_carr[OF p_gt_0] by simp + + have "field ?F" + using f_def(1) zf.monic_poly_carr monic_irreducible_poly_def + by (subst zfp.rupture_is_field_iff_pirreducible) auto + moreover have "order ?F > 0" + unfolding a using assms(1,2) p_gt_0 by simp + ultimately have b:"finite_field ?F" + using card_ge_0_finite + by (intro finite_fieldI, auto simp add:Coset.order_def) + + show ?thesis + using a b + by (intro exI[where x="?F"], simp) +qed + +end diff --git a/thys/Finite_Fields/Card_Irreducible_Polynomials_Aux.thy b/thys/Finite_Fields/Card_Irreducible_Polynomials_Aux.thy new file mode 100644 --- /dev/null +++ b/thys/Finite_Fields/Card_Irreducible_Polynomials_Aux.thy @@ -0,0 +1,916 @@ +section \Counting Irreducible Polynomials \label{sec:card_irred}\ + +subsection \The polynomial $X^n - X$\ + +theory Card_Irreducible_Polynomials_Aux +imports + "HOL-Algebra.Multiplicative_Group" + Formal_Polynomial_Derivatives + Monic_Polynomial_Factorization +begin + +lemma (in domain) + assumes "subfield K R" + assumes "f \ carrier (K[X])" "degree f > 0" + shows embed_inj: "inj_on (rupture_surj K f \ poly_of_const) K" + and rupture_order: "order (Rupt K f) = card K^degree f" + and rupture_char: "char (Rupt K f) = char R" +proof - + interpret p: principal_domain "K[X]" + using univ_poly_is_principal[OF assms(1)] by simp + + interpret I: ideal "PIdl\<^bsub>K[X]\<^esub> f" "K[X]" + using p.cgenideal_ideal[OF assms(2)] by simp + + interpret d: ring "Rupt K f" + unfolding rupture_def using I.quotient_is_ring by simp + + have e: "subring K R" + using assms(1) subfieldE(1) by auto + + interpret h: + ring_hom_ring "R \ carrier := K \" + "Rupt K f" "rupture_surj K f \ poly_of_const" + using rupture_surj_norm_is_hom[OF e assms(2)] + using ring_hom_ringI2 subring_is_ring d.is_ring e + by blast + + have "field (R \carrier := K\)" + using assms(1) subfield_iff(2) by simp + hence "subfield K (R\carrier := K\)" + using ring.subfield_iff[OF subring_is_ring[OF e]] by simp + hence b: "subfield (rupture_surj K f ` poly_of_const ` K) (Rupt K f)" + unfolding image_image comp_def[symmetric] + by (intro h.img_is_subfield rupture_one_not_zero assms, simp) + + have "inj_on poly_of_const K" + using poly_of_const_inj inj_on_subset by auto + moreover have + "poly_of_const ` K \ ((\q. q pmod f) ` carrier (K [X]))" + proof (rule image_subsetI) + fix x assume "x \ K" + hence f: + "poly_of_const x \ carrier (K[X])" + "degree (poly_of_const x) = 0" + using poly_of_const_over_subfield[OF assms(1)] by auto + moreover + have "degree (poly_of_const x) < degree f" + using f(2) assms by simp + hence "poly_of_const x pmod f = poly_of_const x" + by (intro pmod_const(2)[OF assms(1)] f assms(2), simp) + ultimately show + "poly_of_const x \ ((\q. q pmod f) ` carrier (K [X]))" + by force + qed + hence "inj_on (rupture_surj K f) (poly_of_const ` K)" + using rupture_surj_inj_on[OF assms(1,2)] inj_on_subset by blast + ultimately show d: "inj_on (rupture_surj K f \ poly_of_const) K" + using comp_inj_on by auto + + have a: "d.dimension (degree f) (rupture_surj K f ` poly_of_const ` K) + (carrier (Rupt K f))" + using rupture_dimension[OF assms(1-3)] by auto + then obtain base where base_def: + "set base \ carrier (Rupt K f)" + "d.independent (rupture_surj K f ` poly_of_const ` K) base" + "length base = degree f" + "d.Span (rupture_surj K f ` poly_of_const ` K) base = + carrier (Rupt K f)" + using d.exists_base[OF b a] by auto + have "order (Rupt K f) = + card (d.Span (rupture_surj K f ` poly_of_const ` K) base)" + unfolding order_def base_def(4) by simp + also have "... = + card (rupture_surj K f ` poly_of_const ` K) ^ length base" + using d.card_span[OF b base_def(2,1)] by simp + also have "... + = card ((rupture_surj K f \ poly_of_const) ` K) ^ degree f" + using base_def(3) image_image unfolding comp_def by metis + also have "... = card K^degree f" + by (subst card_image[OF d], simp) + finally show "order (Rupt K f) = card K^degree f" by simp + + have "char (Rupt K f) = char (R \ carrier := K \)" + using h.char_consistent d by simp + also have "... = char R" + using char_consistent[OF subfieldE(1)[OF assms(1)]] by simp + finally show "char (Rupt K f) = char R" by simp +qed + +definition gauss_poly where + "gauss_poly K n = X\<^bsub>K\<^esub> [^]\<^bsub>poly_ring K\<^esub> (n::nat) \\<^bsub>poly_ring K\<^esub> X\<^bsub>K\<^esub>" + +context field +begin + +interpretation polynomial_ring "R" "carrier R" + unfolding polynomial_ring_def polynomial_ring_axioms_def + using field_axioms carrier_is_subfield by simp + +text \The following lemma can be found in Ireland and Rosen~\cite[\textsection 7.1, Lemma 2]{ireland1982}.\ + +lemma gauss_poly_div_gauss_poly_iff_1: + fixes l m :: nat + assumes "l > 0" + shows "(X [^]\<^bsub>P\<^esub> l \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>) pdivides (X [^]\<^bsub>P\<^esub> m \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>) \ l dvd m" + (is "?lhs \ ?rhs") +proof - + define q where "q = m div l" + define r where "r = m mod l" + have m_def: "m = q * l + r" and r_range: "r < l" + using assms by (auto simp add:q_def r_def) + + have pow_sum_carr:"(\\<^bsub>P\<^esub>i\{..P\<^esub> l)[^]\<^bsub>P\<^esub> i) \ carrier P" + using var_pow_closed + by (intro p.finsum_closed, simp) + + have "(X [^]\<^bsub>P\<^esub> (q*l) \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>) = ((X [^]\<^bsub>P\<^esub> l)[^]\<^bsub>P\<^esub> q) \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>" + using var_closed + by (subst p.nat_pow_pow, simp_all add:algebra_simps) + also have "... = + (X [^]\<^bsub>P\<^esub> l \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>) \\<^bsub>P\<^esub> (\\<^bsub>P\<^esub>i\{..P\<^esub> l) [^]\<^bsub>P\<^esub> i)" + using var_pow_closed + by (subst p.geom[symmetric], simp_all) + finally have pow_sum_fact: "(X [^]\<^bsub>P\<^esub> (q*l) \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>) = + (X [^]\<^bsub>P\<^esub> l \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>) \\<^bsub>P\<^esub> (\\<^bsub>P\<^esub>i\{..R\<^esub> [^]\<^bsub>P\<^esub> l) [^]\<^bsub>P\<^esub> i)" + by simp + + have "(X [^]\<^bsub>P\<^esub> l \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>) divides\<^bsub>P\<^esub> (X [^]\<^bsub>P\<^esub> (q*l) \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>)" + by (rule dividesI[OF pow_sum_carr pow_sum_fact]) + + hence c:"(X [^]\<^bsub>P\<^esub> l \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>) divides\<^bsub>P\<^esub> X [^]\<^bsub>P\<^esub> r \\<^bsub>P\<^esub> (X [^]\<^bsub>P\<^esub> (q * l) \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>)" + using var_pow_closed + by (intro p.divides_prod_l, auto) + + have "(X [^]\<^bsub>P\<^esub> m \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>) = X [^]\<^bsub>P\<^esub> (r + q * l) \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>" + unfolding m_def using add.commute by metis + also have "... = (X [^]\<^bsub>P\<^esub> r) \\<^bsub>P\<^esub> (X [^]\<^bsub>P\<^esub> (q*l)) \\<^bsub>P\<^esub> (\\<^bsub>P\<^esub> \\<^bsub>P\<^esub>)" + using var_closed + by (subst p.nat_pow_mult, auto simp add:a_minus_def) + also have "... = ((X [^]\<^bsub>P\<^esub> r) \\<^bsub>P\<^esub> (X [^]\<^bsub>P\<^esub> (q*l) \\<^bsub>P\<^esub> (\\<^bsub>P\<^esub> \\<^bsub>P\<^esub>)) + \\<^bsub>P\<^esub> (X [^]\<^bsub>P\<^esub> r)) \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>" + using var_pow_closed + by algebra + also have "... = (X [^]\<^bsub>P\<^esub> r) \\<^bsub>P\<^esub> (X [^]\<^bsub>P\<^esub> (q*l) \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>) + \\<^bsub>P\<^esub> (X [^]\<^bsub>P\<^esub> r) \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>" + by algebra + also have "... = (X [^]\<^bsub>P\<^esub> r) \\<^bsub>P\<^esub> (X [^]\<^bsub>P\<^esub> (q*l) \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>) + \\<^bsub>P\<^esub> ((X [^]\<^bsub>P\<^esub> r) \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>)" + unfolding a_minus_def using var_pow_closed + by (subst p.a_assoc, auto) + finally have a:"(X [^]\<^bsub>P\<^esub> m \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>) = + (X [^]\<^bsub>P\<^esub> r) \\<^bsub>P\<^esub> (X [^]\<^bsub>P\<^esub> (q*l) \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>) \\<^bsub>P\<^esub> (X [^]\<^bsub>P\<^esub> r \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>)" + (is "_ = ?x") + by simp + + have xn_m_1_deg': "degree (X [^]\<^bsub>P\<^esub> n \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>) = n" + if "n > 0" for n :: nat + proof - + have "degree (X [^]\<^bsub>P\<^esub> n \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>) = degree (X [^]\<^bsub>P\<^esub> n \\<^bsub>P\<^esub> \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>)" + by (simp add:a_minus_def) + also have "... = max (degree (X [^]\<^bsub>P\<^esub> n)) (degree (\\<^bsub>P\<^esub> \\<^bsub>P\<^esub>))" + using var_pow_closed var_pow_carr var_pow_degree + using univ_poly_a_inv_degree degree_one that + by (subst degree_add_distinct, auto) + also have "... = n" + using var_pow_degree degree_one univ_poly_a_inv_degree + by simp + finally show ?thesis by simp + qed + + have xn_m_1_deg: "degree (X [^]\<^bsub>P\<^esub> n \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>) = n" for n :: nat + proof (cases "n > 0") + case True + then show ?thesis using xn_m_1_deg' by auto + next + case False + hence "n = 0" by simp + hence "degree (X [^]\<^bsub>P\<^esub> n \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>) = degree (\\<^bsub>P\<^esub>)" + by (intro arg_cong[where f="degree"], simp) + then show ?thesis using False by (simp add:univ_poly_zero) + qed + + have b: "degree (X [^]\<^bsub>P\<^esub> l \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>) > degree (X\<^bsub>R\<^esub> [^]\<^bsub>P\<^esub> r \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>)" + using r_range unfolding xn_m_1_deg by simp + + have xn_m_1_carr: "X [^]\<^bsub>P\<^esub> n \\<^bsub>P\<^esub> \\<^bsub>P\<^esub> \ carrier P" for n :: nat + unfolding a_minus_def + by (intro p.a_closed var_pow_closed, simp) + + have "?lhs \ (X [^]\<^bsub>P\<^esub> l \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>) pdivides ?x" + by (subst a, simp) + also have "... \ (X [^]\<^bsub>P\<^esub> l \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>) pdivides (X [^]\<^bsub>P\<^esub> r \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>)" + unfolding pdivides_def + by (intro p.div_sum_iff c var_pow_closed + xn_m_1_carr p.a_closed p.m_closed) + also have "... \ r = 0" + proof (cases "r = 0") + case True + have "(X [^]\<^bsub>P\<^esub> l \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>) pdivides \\<^bsub>P\<^esub>" + unfolding univ_poly_zero + by (intro pdivides_zero xn_m_1_carr) + also have "... = (X [^]\<^bsub>P\<^esub> r \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>)" + by (simp add:a_minus_def True) algebra + finally show ?thesis using True by simp + next + case False + hence "degree (X [^]\<^bsub>P\<^esub> r \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>) > 0" using xn_m_1_deg by simp + hence "X [^]\<^bsub>P\<^esub> r \\<^bsub>P\<^esub> \\<^bsub>P\<^esub> \ []" by auto + hence "\(X [^]\<^bsub>P\<^esub> l \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>) pdivides (X [^]\<^bsub>P\<^esub> r \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>)" + using pdivides_imp_degree_le b xn_m_1_carr + by (metis le_antisym less_or_eq_imp_le nat_neq_iff) + thus ?thesis using False by simp + qed + also have "... \ l dvd m" + unfolding m_def using r_range assms by auto + finally show ?thesis + by simp +qed + +lemma gauss_poly_factor: + assumes "n > 0" + shows "gauss_poly R n = (X [^]\<^bsub>P\<^esub> (n-1) \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>) \\<^bsub>P\<^esub> X" (is "_ = ?rhs") +proof - + have a:"1 + (n - 1) = n" + using assms by simp + have "gauss_poly R n = X [^]\<^bsub>P\<^esub> (1+(n-1)) \\<^bsub>P\<^esub> X" + unfolding gauss_poly_def by (subst a, simp) + also have "... = (X [^]\<^bsub>P\<^esub> (n-1)) \\<^bsub>P\<^esub> X \\<^bsub>P\<^esub> \\<^bsub>P\<^esub> \\<^bsub>P\<^esub> X" + using var_closed by simp + also have "... = ?rhs" + unfolding a_minus_def using var_closed l_one + by (subst p.l_distr, auto, algebra) + finally show ?thesis by simp +qed + +lemma var_neq_zero: "X \ \\<^bsub>P\<^esub>" + by (simp add:var_def univ_poly_zero) + +lemma var_pow_eq_one_iff: "X [^]\<^bsub>P\<^esub> k = \\<^bsub>P\<^esub> \ k = (0::nat)" +proof (cases "k=0") + case True + then show ?thesis using var_closed(1) by simp +next + case False + have "degree (X\<^bsub>R\<^esub> [^]\<^bsub>P\<^esub> k) = k " + using var_pow_degree by simp + also have "... \ degree (\\<^bsub>P\<^esub>)" using False degree_one by simp + finally have "degree (X\<^bsub>R\<^esub> [^]\<^bsub>P\<^esub> k) \ degree \\<^bsub>P\<^esub>" by simp + then show ?thesis by auto +qed + +lemma gauss_poly_carr: "gauss_poly R n \ carrier P" + using var_closed(1) + unfolding gauss_poly_def by simp + +lemma gauss_poly_degree: + assumes "n > 1" + shows "degree (gauss_poly R n) = n" +proof - + have "degree (gauss_poly R n) = max n 1" + unfolding gauss_poly_def a_minus_def + using var_pow_carr var_carr degree_var + using var_pow_degree univ_poly_a_inv_degree + using assms by (subst degree_add_distinct, auto) + also have "... = n" using assms by simp + finally show ?thesis by simp +qed + +lemma gauss_poly_not_zero: + assumes "n > 1" + shows "gauss_poly R n \ \\<^bsub>P\<^esub>" +proof - + have "degree (gauss_poly R n) \ degree ( \\<^bsub>P\<^esub>)" + using assms by (subst gauss_poly_degree, simp_all add:univ_poly_zero) + thus ?thesis by auto +qed + +lemma gauss_poly_monic: + assumes "n > 1" + shows "monic_poly R (gauss_poly R n)" +proof - + have "monic_poly R (X [^]\<^bsub>P\<^esub> n)" + by (intro monic_poly_pow monic_poly_var) + moreover have "\\<^bsub>P\<^esub> X \ carrier P" + using var_closed by simp + moreover have "degree (\\<^bsub>P\<^esub> X) < degree (X [^]\<^bsub>P\<^esub> n)" + using assms univ_poly_a_inv_degree var_closed + using degree_var + unfolding var_pow_degree by (simp) + ultimately show ?thesis + unfolding gauss_poly_def a_minus_def + by (intro monic_poly_add_distinct, auto) +qed + +lemma geom_nat: + fixes q :: nat + fixes x :: "_ :: {comm_ring,monoid_mult}" + shows "(x-1) * (\i \ {..The following lemma can be found in Ireland and Rosen~\cite[\textsection 7.1, Lemma 3]{ireland1982}.\ + +lemma gauss_poly_div_gauss_poly_iff_2: + fixes a :: int + fixes l m :: nat + assumes "l > 0" "a > 1" + shows "(a ^ l - 1) dvd (a ^ m - 1) \ l dvd m" + (is "?lhs \ ?rhs") +proof - + define q where "q = m div l" + define r where "r = m mod l" + have m_def: "m = q * l + r" and r_range: "r < l" "r \ 0" + using assms by (auto simp add:q_def r_def) + + have "a ^ (l * q) - 1 = (a ^ l) ^ q - 1" + by (simp add: power_mult) + also have "... = (a^l - 1) * (\i \ {..i \ {.. (a^l -1) dvd ?x" + by (subst a, simp) + also have "... \ (a^l -1) dvd (a^r -1)" + using c dvd_add_right_iff by auto + also have "... \ r = 0" + proof + assume "a ^ l - 1 dvd a ^ r - 1" + hence "a ^ l - 1 \ a ^ r -1 \ r = 0 " + using assms r_range zdvd_not_zless by force + moreover have "a ^ r < a^l" using assms r_range by simp + ultimately show "r= 0"by simp + next + assume "r = 0" + thus "a ^ l - 1 dvd a ^ r - 1" by simp + qed + also have "... \ l dvd m" + using r_def by auto + finally show ?thesis by simp +qed + +lemma gauss_poly_div_gauss_poly_iff: + assumes "m > 0" "n > 0" "a > 1" + shows "gauss_poly R (a^n) pdivides\<^bsub>R\<^esub> gauss_poly R (a^m) + \ n dvd m" (is "?lhs=?rhs") +proof - + have a:"a^m > 1" using assms one_less_power by blast + hence a1: "a^m > 0" by linarith + have b:"a^n > 1" using assms one_less_power by blast + hence b1:"a^n > 0" by linarith + + have "?lhs \ + (X [^]\<^bsub>P\<^esub> (a^n-1) \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>) \\<^bsub>P\<^esub> X pdivides + (X [^]\<^bsub>P\<^esub> (a^m-1) \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>) \\<^bsub>P\<^esub> X" + using gauss_poly_factor a1 b1 by simp + also have "... \ + (X [^]\<^bsub>P\<^esub> (a^n-1) \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>) pdivides + (X [^]\<^bsub>P\<^esub> (a^m-1) \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>)" + using var_closed a b var_neq_zero + by (subst pdivides_mult_r, simp_all add:var_pow_eq_one_iff) + also have "... \ a^n-1 dvd a^m-1" + using b + by (subst gauss_poly_div_gauss_poly_iff_1) simp_all + also have "... \ int (a^n-1) dvd int (a^m-1)" + by (subst of_nat_dvd_iff, simp) + also have "... \ int a^n-1 dvd int a^m-1" + using a b by (simp add:of_nat_diff) + also have "... \ n dvd m" + using assms + by (subst gauss_poly_div_gauss_poly_iff_2) simp_all + finally show ?thesis by simp +qed + +end + +context finite_field +begin + +interpretation polynomial_ring "R" "carrier R" + unfolding polynomial_ring_def polynomial_ring_axioms_def + using field_axioms carrier_is_subfield by simp + +lemma div_gauss_poly_iff: + assumes "n > 0" + assumes "monic_irreducible_poly R f" + shows "f pdivides\<^bsub>R\<^esub> gauss_poly R (order R^n) \ degree f dvd n" +proof - + have f_carr: "f \ carrier P" + using assms(2) unfolding monic_irreducible_poly_def + unfolding monic_poly_def by simp + have f_deg: "degree f > 0" + using assms(2) monic_poly_min_degree by fastforce + + define K where "K = Rupt\<^bsub>R\<^esub> (carrier R) f" + have field_K: "field K" + using assms(2) unfolding K_def monic_irreducible_poly_def + unfolding monic_poly_def + by (subst rupture_is_field_iff_pirreducible) auto + have a: "order K = order R^degree f" + using rupture_order[OF carrier_is_subfield] f_carr f_deg + unfolding K_def order_def by simp + have char_K: "char K = char R" + using rupture_char[OF carrier_is_subfield] f_carr f_deg + unfolding K_def by simp + + have "card (carrier K) > 0" + using a f_deg finite_field_min_order unfolding order_def by simp + hence d: "finite (carrier K)" using card_ge_0_finite by auto + interpret f: finite_field "K" + using field_K d by (intro finite_fieldI, simp_all) + interpret fp: polynomial_ring "K" "(carrier K)" + unfolding polynomial_ring_def polynomial_ring_axioms_def + using f.field_axioms f.carrier_is_subfield by simp + + define \ where "\ = rupture_surj (carrier R) f" + interpret h:ring_hom_ring "P" "K" "\" + unfolding K_def \_def using f_carr rupture_surj_hom by simp + + have embed_inj: "inj_on (\ \ poly_of_const) (carrier R)" + unfolding \_def + using embed_inj[OF carrier_is_subfield f_carr f_deg] by simp + + interpret r:ring_hom_ring "R" "P" "poly_of_const" + using canonical_embedding_ring_hom by simp + + obtain rn where "order R = char K^rn" "rn > 0" + unfolding char_K using finite_field_order by auto + hence ord_rn: "order R ^n = char K^(rn * n)" using assms(1) + by (simp add: power_mult) + + interpret q:ring_hom_cring "K" "K" "\x. x [^]\<^bsub>K\<^esub> order R^n" + using ord_rn + by (intro f.frobenius_hom f.finite_carr_imp_char_ge_0 d, simp) + + have o1: "order R^degree f > 1" + using f_deg finite_field_min_order one_less_power + by blast + hence o11: "order R^degree f > 0" by linarith + have o2: "order R^n > 1" + using assms(1) finite_field_min_order one_less_power + by blast + hence o21: "order R^n > 0" by linarith + let ?g1 = "gauss_poly K (order R^degree f)" + let ?g2 = "gauss_poly K (order R^n)" + + have g1_monic: "monic_poly K ?g1" + using f.gauss_poly_monic[OF o1] by simp + + have c:"x [^]\<^bsub>K\<^esub> (order R^degree f) = x" if b:"x \ carrier K" for x + using b d order_pow_eq_self + unfolding a[symmetric] + by (intro f.order_pow_eq_self, auto) + + have k_cycle: + "\ (poly_of_const x) [^]\<^bsub>K\<^esub> (order R^n) = \(poly_of_const x)" + if k_cycle_1: "x \ carrier R" for x + proof - + have "\ (poly_of_const x) [^]\<^bsub>K\<^esub> (order R^n) = + \ (poly_of_const (x [^]\<^bsub>R\<^esub> (order R^n)))" + using k_cycle_1 by (simp add: h.hom_nat_pow r.hom_nat_pow) + also have "... = \ (poly_of_const x)" + using order_pow_eq_self' k_cycle_1 by simp + finally show ?thesis by simp + qed + + have roots_g1: "pmult\<^bsub>K\<^esub> d ?g1 \ 1" + if roots_g1_assms: "degree d = 1" "monic_irreducible_poly K d" for d + proof - + obtain x where x_def: "x \ carrier K" "d = [\\<^bsub>K\<^esub>, \\<^bsub>K\<^esub> x]" + using f.degree_one_monic_poly roots_g1_assms by auto + interpret x:ring_hom_cring "poly_ring K" "K" "(\p. f.eval p x)" + by (intro fp.eval_cring_hom x_def) + have "ring.eval K ?g1 x = \\<^bsub>K\<^esub>" + unfolding gauss_poly_def a_minus_def + using fp.var_closed f.eval_var x_def c + by (simp, algebra) + hence "f.is_root ?g1 x" + using x_def f.gauss_poly_not_zero[OF o1] + unfolding f.is_root_def univ_poly_zero by simp + hence "[\\<^bsub>K\<^esub>, \\<^bsub>K\<^esub> x] pdivides\<^bsub>K\<^esub> ?g1" + using f.is_root_imp_pdivides f.gauss_poly_carr by simp + hence "d pdivides\<^bsub>K\<^esub> ?g1" by (simp add:x_def) + thus "pmult\<^bsub>K\<^esub> d ?g1 \ 1" + using that f.gauss_poly_not_zero f.gauss_poly_carr o1 + by (subst f.multiplicity_ge_1_iff_pdivides, simp_all) + qed + + show ?thesis + proof + assume f:"f pdivides\<^bsub>R\<^esub> gauss_poly R (order R^n)" + have "(\ X) [^]\<^bsub>K\<^esub> (order R^n) \\<^bsub>K\<^esub> (\ X\<^bsub>R\<^esub>) = + \ (gauss_poly R (order R^n))" + unfolding gauss_poly_def a_minus_def using var_closed + by (simp add: h.hom_nat_pow) + also have "... = \\<^bsub>K\<^esub>" + unfolding K_def \_def using f_carr gauss_poly_carr f + by (subst rupture_eq_0_iff, simp_all) + finally have "(\ X\<^bsub>R\<^esub>) [^]\<^bsub>K\<^esub> (order R^n) \\<^bsub>K\<^esub> (\ X\<^bsub>R\<^esub>) = \\<^bsub>K\<^esub>" + by simp + hence g:"(\ X) [^]\<^bsub>K\<^esub> (order R^n) = (\ X)" + using var_closed by simp + + have roots_g2: "pmult\<^bsub>K\<^esub> d ?g2 \ 1" + if roots_g2_assms: "degree d = 1" "monic_irreducible_poly K d" for d + proof - + obtain y where y_def: "y \ carrier K" "d = [\\<^bsub>K\<^esub>, \\<^bsub>K\<^esub> y]" + using f.degree_one_monic_poly roots_g2_assms by auto + + interpret x:ring_hom_cring "poly_ring K" "K" "(\p. f.eval p y)" + by (intro fp.eval_cring_hom y_def) + obtain x where x_def: "x \ carrier P" "y = \ x" + using y_def unfolding \_def K_def rupture_def + unfolding FactRing_def A_RCOSETS_def' + by auto + let ?\ = "\i. poly_of_const (coeff x i)" + have test: "?\ i \ carrier P" for i + by (intro r.hom_closed coeff_range x_def) + have test_2: "coeff x i \ carrier R" for i + by (intro coeff_range x_def) + + have x_coeff_carr: "i \ set x \ i \ carrier R" for i + using x_def(1) + by (auto simp add:univ_poly_carrier[symmetric] polynomial_def) + + have a:"map (\ \ poly_of_const) x \ carrier (poly_ring K)" + using rupture_surj_norm_is_hom[OF f_carr] + using domain_axioms f.domain_axioms embed_inj + by (intro carrier_hom'[OF x_def(1)]) + (simp_all add:\_def K_def) + + have "(\ x) [^]\<^bsub>K\<^esub> (order R^n) = + f.eval (map (\ \ poly_of_const) x) (\ X) [^]\<^bsub>K\<^esub> (order R^n)" + unfolding \_def K_def + by (subst rupture_surj_as_eval[OF f_carr x_def(1)], simp) + also have "... = + f.eval (map (\x. \ (poly_of_const x) [^]\<^bsub>K\<^esub> order R ^ n) x) (\ X)" + using a h.hom_closed var_closed(1) + by (subst q.ring.eval_hom[OF f.carrier_is_subring]) + (simp_all add:comp_def g) + also have "... = f.eval (map (\x. \ (poly_of_const x)) x) (\ X)" + using k_cycle x_coeff_carr + by (intro arg_cong2[where f="f.eval"] map_cong, simp_all) + also have "... = (\ x)" + unfolding \_def K_def + by (subst rupture_surj_as_eval[OF f_carr x_def(1)], simp add:comp_def) + finally have "\ x [^]\<^bsub>K\<^esub> order R ^ n = \ x" by simp + + hence "y [^]\<^bsub>K\<^esub> (order R^n) = y" using x_def by simp + hence "ring.eval K ?g2 y = \\<^bsub>K\<^esub>" + unfolding gauss_poly_def a_minus_def + using fp.var_closed f.eval_var y_def + by (simp, algebra) + hence "f.is_root ?g2 y" + using y_def f.gauss_poly_not_zero[OF o2] + unfolding f.is_root_def univ_poly_zero by simp + hence "d pdivides\<^bsub>K\<^esub> ?g2" + unfolding y_def + by (intro f.is_root_imp_pdivides f.gauss_poly_carr, simp) + thus "pmult\<^bsub>K\<^esub> d ?g2 \ 1" + using that f.gauss_poly_carr f.gauss_poly_not_zero o2 + by (subst f.multiplicity_ge_1_iff_pdivides, auto) + qed + + have inv_k_inj: "inj_on (\x. \\<^bsub>K\<^esub> x) (carrier K)" + by (intro inj_onI, metis f.minus_minus) + let ?mip = "monic_irreducible_poly K" + + have "sum' (\d. pmult\<^bsub>K\<^esub> d ?g1 * degree d) {d. ?mip d} = degree ?g1" + using f.gauss_poly_monic o1 + by (subst f.degree_monic_poly', simp_all) + also have "... = order K" + using f.gauss_poly_degree o1 a by simp + also have "... = card ((\k. [\\<^bsub>K\<^esub>, \\<^bsub>K\<^esub> k]) ` carrier K)" + unfolding order_def using inj_onD[OF inv_k_inj] + by (intro card_image[symmetric] inj_onI) (simp_all) + also have "... = card {d. ?mip d \ degree d = 1}" + using f.degree_one_monic_poly + by (intro arg_cong[where f="card"], simp add:set_eq_iff image_iff) + also have "... = sum (\d. 1) {d. ?mip d \ degree d = 1}" + by simp + also have "... = sum' (\d. 1) {d. ?mip d \ degree d = 1}" + by (intro sum.eq_sum[symmetric] + finite_subset[OF _ fp.finite_poly(1)[OF d]]) + (auto simp:monic_irreducible_poly_def monic_poly_def) + also have "... = sum' (\d. of_bool (degree d = 1)) {d. ?mip d}" + by (intro sum.mono_neutral_cong_left' subsetI, simp_all) + also have "... \ sum' (\d. of_bool (degree d = 1)) {d. ?mip d}" + by simp + finally have "sum' (\d. pmult\<^bsub>K\<^esub> d ?g1 * degree d) {d. ?mip d} + \ sum' (\d. of_bool (degree d = 1)) {d. ?mip d}" + by simp + moreover have + "pmult\<^bsub>K\<^esub> d ?g1 * degree d \ of_bool (degree d = 1)" + if v:"monic_irreducible_poly K d" for d + proof (cases "degree d = 1") + case True + then obtain x where "x \ carrier K" "d = [\\<^bsub>K\<^esub>, \\<^bsub>K\<^esub> x]" + using f.degree_one_monic_poly v by auto + hence "pmult\<^bsub>K\<^esub> d ?g1 \ 1" + using roots_g1 v by simp + then show ?thesis using True by simp + next + case False + then show ?thesis by simp + qed + moreover have + "finite {d. ?mip d \ pmult\<^bsub>K\<^esub> d ?g1 * degree d > 0}" + by (intro finite_subset[OF _ f.factor_monic_poly_fin[OF g1_monic]] + subsetI) simp + ultimately have v2: + "\d \ {d. ?mip d}. pmult\<^bsub>K\<^esub> d ?g1 * degree d = + of_bool (degree d = 1)" + by (intro sum'_eq_iff, simp_all add:not_le) + have "pmult\<^bsub>K\<^esub> d ?g1 \ pmult\<^bsub>K\<^esub> d ?g2" if "?mip d" for d + proof (cases "degree d = 1") + case True + hence "pmult\<^bsub>K\<^esub> d ?g1 = 1" using v2 that by simp + also have "... \ pmult\<^bsub>K\<^esub> d ?g2" + by (intro roots_g2 True that) + finally show ?thesis by simp + next + case False + hence "degree d > 1" + using f.monic_poly_min_degree[OF that] by simp + hence "pmult\<^bsub>K\<^esub> d ?g1 = 0" using v2 that by auto + then show ?thesis by simp + qed + hence "?g1 pdivides\<^bsub>K\<^esub> ?g2" + using o1 o2 f.divides_monic_poly f.gauss_poly_monic by simp + thus "degree f dvd n" + by (subst (asm) f.gauss_poly_div_gauss_poly_iff + [OF assms(1) f_deg finite_field_min_order], simp) + next + have d:"\ X\<^bsub>R\<^esub> \ carrier K" + by (intro h.hom_closed var_closed) + + have "\ (gauss_poly R (order R^degree f)) = + (\ X\<^bsub>R\<^esub>) [^]\<^bsub>K\<^esub> (order R^degree f) \\<^bsub>K\<^esub> (\ X\<^bsub>R\<^esub>)" + unfolding gauss_poly_def a_minus_def using var_closed + by (simp add: h.hom_nat_pow) + also have "... = \\<^bsub>K\<^esub>" + using c d by simp + finally have "\ (gauss_poly R (order R^degree f)) = \\<^bsub>K\<^esub>" by simp + hence "f pdivides\<^bsub>R\<^esub> gauss_poly R (order R^degree f)" + unfolding K_def \_def using f_carr gauss_poly_carr + by (subst (asm) rupture_eq_0_iff, simp_all) + moreover assume "degree f dvd n" + + hence "gauss_poly R (order R^degree f) pdivides + (gauss_poly R (order R^n))" + using gauss_poly_div_gauss_poly_iff + [OF assms(1) f_deg finite_field_min_order] + by simp + ultimately show "f pdivides\<^bsub>R\<^esub> gauss_poly R (order R^n)" + using f_carr a p.divides_trans unfolding pdivides_def by blast + qed +qed + +lemma gauss_poly_splitted: + "splitted (gauss_poly R (order R))" +proof - + have "degree q \ 1" if + "q \ carrier P" + "pirreducible (carrier R) q" + "q pdivides gauss_poly R (order R)" for q + proof - + have q_carr: "q \ carrier (mult_of P)" + using that unfolding ring_irreducible_def by simp + moreover have "irreducible (mult_of P) q" + using that unfolding ring_irreducible_def + by (intro p.irreducible_imp_irreducible_mult that, simp_all) + ultimately obtain p where p_def: + "monic_irreducible_poly R p" "q \\<^bsub>mult_of P\<^esub> p" + using monic_poly_span by auto + have p_carr: "p \ carrier P" "p \ []" + using p_def(1) + unfolding monic_irreducible_poly_def monic_poly_def + by auto + moreover have "p divides\<^bsub>mult_of P\<^esub> q" + using associatedE[OF p_def(2)] by auto + hence "p pdivides q" + unfolding pdivides_def using divides_mult_imp_divides by simp + moreover have "q pdivides gauss_poly R (order R^1)" + using that by simp + ultimately have "p pdivides gauss_poly R (order R^1)" + unfolding pdivides_def using p.divides_trans by blast + hence "degree p dvd 1" + using div_gauss_poly_iff[where n="1"] p_def(1) by simp + hence "degree p = 1" by simp + moreover have "q divides\<^bsub>mult_of P\<^esub> p" + using associatedE[OF p_def(2)] by auto + hence "q pdivides p" + unfolding pdivides_def using divides_mult_imp_divides by simp + hence "degree q \ degree p" + using that p_carr + by (intro pdivides_imp_degree_le) auto + ultimately show ?thesis by simp + qed + + thus ?thesis + using gauss_poly_carr + by (intro trivial_factors_imp_splitted, auto) +qed + +text \The following lemma, for the case when @{term "R"} is a simple prime field, can be found in +Ireland and Rosen~\cite[\textsection 7.1, Theorem 2]{ireland1982}. Here the result is verified even +for arbitrary finite fields.\ + +lemma multiplicity_of_factor_of_gauss_poly: + assumes "n > 0" + assumes "monic_irreducible_poly R f" + shows + "pmult\<^bsub>R\<^esub> f (gauss_poly R (order R^n)) = of_bool (degree f dvd n)" +proof (cases "degree f dvd n") + case True + let ?g = "gauss_poly R (order R^n)" + have f_carr: "f \ carrier P" "f \ []" + using assms(2) + unfolding monic_irreducible_poly_def monic_poly_def + by auto + + have o2: "order R^n > 1" + using finite_field_min_order assms(1) one_less_power by blast + hence o21: "order R^n > 0" by linarith + + obtain d :: nat where order_dim: "order R = char R ^ d" "d > 0" + using finite_field_order by blast + have "d * n > 0" using order_dim assms by simp + hence char_dvd_order: "int (char R) dvd int (order R ^ n)" + unfolding order_dim + using finite_carr_imp_char_ge_0[OF finite_carrier] + by (simp add:power_mult[symmetric]) + + interpret h: ring_hom_ring "R" "P" "poly_of_const" + using canonical_embedding_ring_hom by simp + + have "f pdivides\<^bsub>R\<^esub> ?g" + using True div_gauss_poly_iff[OF assms] by simp + hence "pmult\<^bsub>R\<^esub> f ?g \ 1" + using multiplicity_ge_1_iff_pdivides[OF assms(2)] + using gauss_poly_carr gauss_poly_not_zero[OF o2] + by auto + moreover have "pmult\<^bsub>R\<^esub> f ?g < 2" + proof (rule ccontr) + assume "\ pmult\<^bsub>R\<^esub> f ?g < 2" + hence "pmult\<^bsub>R\<^esub> f ?g \ 2" by simp + hence "(f [^]\<^bsub>P\<^esub> (2::nat)) pdivides\<^bsub>R\<^esub> ?g" + using gauss_poly_carr gauss_poly_not_zero[OF o2] + by (subst (asm) multiplicity_ge_iff[OF assms(2)]) simp_all + hence "(f [^]\<^bsub>P\<^esub> (2::nat)) divides\<^bsub>mult_of P\<^esub> ?g" + unfolding pdivides_def + using f_carr gauss_poly_not_zero o2 gauss_poly_carr + by (intro p.divides_imp_divides_mult) simp_all + then obtain h where h_def: + "h \ carrier (mult_of P)" + "?g = f [^]\<^bsub>P\<^esub> (2::nat) \\<^bsub>P\<^esub> h" + using dividesD by auto + have "\\<^bsub>P\<^esub> \\<^bsub>P\<^esub> = int_embed P (order R ^ n) + \\<^bsub>P\<^esub> (X\<^bsub>R\<^esub> [^]\<^bsub>P\<^esub> (order R ^ n-1)) \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>" + using var_closed + apply (subst int_embed_consistent_with_poly_of_const) + apply (subst iffD2[OF embed_char_eq_0_iff char_dvd_order]) + by (simp add:a_minus_def) + also have "... = pderiv\<^bsub>R\<^esub> (X\<^bsub>R\<^esub> [^]\<^bsub>P\<^esub> order R ^ n) \\<^bsub>P\<^esub> pderiv\<^bsub>R\<^esub> X\<^bsub>R\<^esub>" + using pderiv_var + by (subst pderiv_var_pow[OF o21], simp) + also have "... = pderiv\<^bsub>R\<^esub> ?g" + unfolding gauss_poly_def a_minus_def using var_closed + by (subst pderiv_add, simp_all add:pderiv_inv) + also have "... = pderiv\<^bsub>R\<^esub> (f [^]\<^bsub>P\<^esub> (2::nat) \\<^bsub>P\<^esub> h)" + using h_def(2) by simp + also have "... = pderiv\<^bsub>R\<^esub> (f [^]\<^bsub>P\<^esub> (2::nat)) \\<^bsub>P\<^esub> h + \\<^bsub>P\<^esub> (f [^]\<^bsub>P\<^esub> (2::nat)) \\<^bsub>P\<^esub> pderiv\<^bsub>R\<^esub> h" + using f_carr h_def + by (intro pderiv_mult, simp_all) + also have "... = int_embed P 2 \\<^bsub>P\<^esub> f \\<^bsub>P\<^esub> pderiv\<^bsub>R\<^esub> f \\<^bsub>P\<^esub> h + \\<^bsub>P\<^esub> f \\<^bsub>P\<^esub> f \\<^bsub>P\<^esub> pderiv\<^bsub>R\<^esub> h" + using f_carr + by (subst pderiv_pow, simp_all add:numeral_eq_Suc) + also have "... = f \\<^bsub>P\<^esub> (int_embed P 2 \\<^bsub>P\<^esub> pderiv\<^bsub>R\<^esub> f \\<^bsub>P\<^esub> h) + \\<^bsub>P\<^esub> f \\<^bsub>P\<^esub> (f \\<^bsub>P\<^esub> pderiv\<^bsub>R\<^esub> h)" + using f_carr pderiv_carr h_def p.int_embed_closed + apply (intro arg_cong2[where f="(\\<^bsub>P\<^esub>)"]) + by (subst p.m_comm, simp_all add:p.m_assoc) + also have "... = f \\<^bsub>P\<^esub> + (int_embed P 2 \\<^bsub>P\<^esub> pderiv\<^bsub>R\<^esub> f \\<^bsub>P\<^esub> h \\<^bsub>P\<^esub> f \\<^bsub>P\<^esub> pderiv\<^bsub>R\<^esub> h)" + using f_carr pderiv_carr h_def p.int_embed_closed + by (subst p.r_distr, simp_all) + finally have "\\<^bsub>P\<^esub> \\<^bsub>P\<^esub> = f \\<^bsub>P\<^esub> + (int_embed P 2 \\<^bsub>P\<^esub> pderiv\<^bsub>R\<^esub> f \\<^bsub>P\<^esub> h \\<^bsub>P\<^esub> f \\<^bsub>P\<^esub> pderiv\<^bsub>R\<^esub> h)" + (is "_ = f \\<^bsub>P\<^esub> ?q") + by simp + + hence "f pdivides\<^bsub>R\<^esub> \\<^bsub>P\<^esub> \\<^bsub>P\<^esub>" + unfolding factor_def pdivides_def + using f_carr pderiv_carr h_def p.int_embed_closed + by auto + moreover have "\\<^bsub>P\<^esub> \\<^bsub>P\<^esub> \ \\<^bsub>P\<^esub>" by simp + ultimately have "degree f \ degree (\\<^bsub>P\<^esub> \\<^bsub>P\<^esub>)" + using f_carr + by (intro pdivides_imp_degree_le, simp_all add:univ_poly_zero) + also have "... = 0" + by (subst univ_poly_a_inv_degree, simp) + (simp add:univ_poly_one) + finally have "degree f = 0" by simp + + then show "False" + using pirreducible_degree assms(2) + unfolding monic_irreducible_poly_def monic_poly_def + by fastforce + qed + ultimately have "pmult\<^bsub>R\<^esub> f ?g = 1" by simp + then show ?thesis using True by simp +next + case False + have o2: "order R^n > 1" + using finite_field_min_order assms(1) one_less_power by blast + + have "\(f pdivides\<^bsub>R\<^esub> gauss_poly R (order R^n))" + using div_gauss_poly_iff[OF assms] False by simp + hence "pmult\<^bsub>R\<^esub> f (gauss_poly R (order R^n)) = 0" + using multiplicity_ge_1_iff_pdivides[OF assms(2)] + using gauss_poly_carr gauss_poly_not_zero[OF o2] leI less_one + by blast + then show ?thesis using False by simp +qed + +text \The following lemma, for the case when @{term "R"} is a simple prime field, can be found in Ireland +and Rosen~\cite[\textsection 7.1, Corollary 1]{ireland1982}. Here the result is verified even for +arbitrary finite fields.\ + +lemma card_irred_aux: + assumes "n > 0" + shows "order R^n = (\d | d dvd n. d * + card {f. monic_irreducible_poly R f \ degree f = d})" + (is "?lhs = ?rhs") +proof - + let ?G = "{f. monic_irreducible_poly R f \ degree f dvd n}" + + let ?D = "{f. monic_irreducible_poly R f}" + have a: "finite {d. d dvd n}" using finite_divisors_nat assms by simp + have b: "finite {f. monic_irreducible_poly R f \ degree f = k}" for k + proof - + have "{f. monic_irreducible_poly R f \ degree f = k} \ + {f. f \ carrier P \ degree f \ k}" + unfolding monic_irreducible_poly_def monic_poly_def by auto + moreover have "finite {f. f \ carrier P \ degree f \ k}" + using finite_poly[OF finite_carrier] by simp + ultimately show ?thesis using finite_subset by simp + qed + + have G_split: "?G = + \ {{f. monic_irreducible_poly R f \ degree f = d} | d. d dvd n}" + by auto + have c: "finite ?G" + using a b by (subst G_split, auto) + have d: "order R^n > 1" + using assms finite_field_min_order one_less_power by blast + + have "?lhs = degree (gauss_poly R (order R^n))" + using d + by (subst gauss_poly_degree, simp_all) + also have "... = + sum' (\d. pmult\<^bsub>R\<^esub> d (gauss_poly R (order R^n)) * degree d) ?D" + using d + by (intro degree_monic_poly'[symmetric] gauss_poly_monic) + also have "... = sum' (\d. of_bool (degree d dvd n) * degree d) ?D" + using multiplicity_of_factor_of_gauss_poly[OF assms] + by (intro sum.cong', auto) + also have "... = sum' (\d. degree d) ?G" + by (intro sum.mono_neutral_cong_right' subsetI, auto) + also have "... = (\ d \ ?G. degree d)" + using c by (intro sum.eq_sum, simp) + also have "... = + (\ f \ (\ d \ {d. d dvd n}. + {f. monic_irreducible_poly R f \ degree f = d}). degree f)" + by (intro sum.cong, auto simp add:set_eq_iff) + also have "... = (\d | d dvd n. sum degree + {f. monic_irreducible_poly R f \ degree f = d})" + using a b by (subst sum.UNION_disjoint, auto simp add:set_eq_iff) + also have "... = (\d | d dvd n. sum (\_. d) + {f. monic_irreducible_poly R f \ degree f = d})" + by (intro sum.cong, simp_all) + also have "... = ?rhs" + by (simp add:mult.commute) + finally show ?thesis + by simp +qed + +end + +end diff --git a/thys/Finite_Fields/Finite_Fields_Factorization_Ext.thy b/thys/Finite_Fields/Finite_Fields_Factorization_Ext.thy new file mode 100644 --- /dev/null +++ b/thys/Finite_Fields/Finite_Fields_Factorization_Ext.thy @@ -0,0 +1,516 @@ +subsection "Factorization" + +theory Finite_Fields_Factorization_Ext + imports Finite_Fields_Preliminary_Results +begin + +text \This section contains additional results building on top of the development in +@{theory "HOL-Algebra.Divisibility"} about factorization in a @{locale "factorial_monoid"}.\ + +definition factor_mset where "factor_mset G x = + (THE f. (\ as. f = fmset G as \ wfactors G as x \ set as \ carrier G))" + +text \In @{theory "HOL-Algebra.Divisibility"} it is already verified that the multiset representing +the factorization of an element of a factorial monoid into irreducible factors is well-defined. +With these results it is then possible to define @{term "factor_mset"} and show its properties, +without referring to a factorization in list form first.\ + +definition multiplicity where + "multiplicity G d g = Max {(n::nat). (d [^]\<^bsub>G\<^esub> n) divides\<^bsub>G\<^esub> g}" + +definition canonical_irreducibles where + "canonical_irreducibles G A = ( + A \ {a. a \ carrier G \ irreducible G a} \ + (\x y. x \ A \ y \ A \ x \\<^bsub>G\<^esub> y \ x = y) \ + (\x \ carrier G. irreducible G x \ (\y \ A. x \\<^bsub>G\<^esub> y)))" + +text \A set of irreducible elements that contains exactly one element from each equivalence class +of an irreducible element formed by association, is called a set of +@{term "canonical_irreducibles"}. An example is the set of monic irreducible polynomials as +representatives of all irreducible polynomials.\ + +context factorial_monoid +begin + +lemma assoc_as_fmset_eq: + assumes "wfactors G as a" + and "wfactors G bs b" + and "a \ carrier G" + and "b \ carrier G" + and "set as \ carrier G" + and "set bs \ carrier G" + shows "a \ b \ (fmset G as = fmset G bs)" +proof - + have "a \ b \ (a divides b \ b divides a)" + by (simp add:associated_def) + also have "... \ + (fmset G as \# fmset G bs \ fmset G bs \# fmset G as)" + using divides_as_fmsubset assms by blast + also have "... \ (fmset G as = fmset G bs)" by auto + finally show ?thesis by simp +qed + +lemma factor_mset_aux_1: + assumes "a \ carrier G" "set as \ carrier G" "wfactors G as a" + shows "factor_mset G a = fmset G as" +proof - + define H where "H = {as. wfactors G as a \ set as \ carrier G}" + have b:"as \ H" + using H_def assms by simp + + have c: "x \ H \ y \ H \ fmset G x = fmset G y" for x y + unfolding H_def using assoc_as_fmset_eq + using associated_refl assms by blast + + have "factor_mset G a = (THE f. \as \ H. f= fmset G as)" + by (simp add:factor_mset_def H_def, metis) + + also have "... = fmset G as" + using b c + by (intro the1_equality) blast+ + finally have "factor_mset G a = fmset G as" by simp + + thus ?thesis + using b unfolding H_def by auto +qed + +lemma factor_mset_aux: + assumes "a \ carrier G" + shows "\as. factor_mset G a = fmset G as \ wfactors G as a \ + set as \ carrier G" +proof - + obtain as where as_def: "wfactors G as a" "set as \ carrier G" + using wfactors_exist assms by blast + thus ?thesis using factor_mset_aux_1 assms by blast +qed + +lemma factor_mset_set: + assumes "a \ carrier G" + assumes "x \# factor_mset G a" + obtains y where + "y \ carrier G" + "irreducible G y" + "assocs G y = x" +proof - + obtain as where as_def: + "factor_mset G a = fmset G as" + "wfactors G as a" "set as \ carrier G" + using factor_mset_aux assms by blast + hence "x \# fmset G as" + using assms by simp + hence "x \ assocs G ` set as" + using assms as_def by (simp add:fmset_def) + hence "\y. y \ set as \ x = assocs G y" + by auto + moreover have "y \ carrier G \ irreducible G y" + if "y \ set as" for y + using as_def that wfactors_def + by (simp add: wfactors_def) auto + ultimately show ?thesis + using that by blast +qed + +lemma factor_mset_mult: + assumes "a \ carrier G" "b \ carrier G" + shows "factor_mset G (a \ b) = factor_mset G a + factor_mset G b" +proof - + obtain as where as_def: + "factor_mset G a = fmset G as" + "wfactors G as a" "set as \ carrier G" + using factor_mset_aux assms by blast + obtain bs where bs_def: + "factor_mset G b = fmset G bs" + "wfactors G bs b" "set bs \ carrier G" + using factor_mset_aux assms(2) by blast + have "a \ b \ carrier G" using assms by auto + then obtain cs where cs_def: + "factor_mset G (a \ b) = fmset G cs" + "wfactors G cs (a \ b)" + "set cs \ carrier G" + using factor_mset_aux assms by blast + have "fmset G cs = fmset G as + fmset G bs" + using as_def bs_def cs_def assms + by (intro mult_wfactors_fmset[where a="a" and b="b"]) auto + thus ?thesis + using as_def bs_def cs_def by auto +qed + +lemma factor_mset_unit: "factor_mset G \ = {#}" +proof - + have "factor_mset G \ = factor_mset G (\ \ \)" + by simp + also have "... = factor_mset G \ + factor_mset G \" + by (intro factor_mset_mult, auto) + finally show "factor_mset G \ = {#}" + by simp +qed + +lemma factor_mset_irred: + assumes "x \ carrier G" "irreducible G x" + shows "factor_mset G x = image_mset (assocs G) {#x#}" +proof - + have "wfactors G [x] x" + using assms by (simp add:wfactors_def) + hence "factor_mset G x = fmset G [x]" + using factor_mset_aux_1 assms by simp + also have "... = image_mset (assocs G) {#x#}" + by (simp add:fmset_def) + finally show ?thesis by simp +qed + +lemma factor_mset_divides: + assumes "a \ carrier G" "b \ carrier G" + shows "a divides b \ factor_mset G a \# factor_mset G b" +proof - + obtain as where as_def: + "factor_mset G a = fmset G as" + "wfactors G as a" "set as \ carrier G" + using factor_mset_aux assms by blast + obtain bs where bs_def: + "factor_mset G b = fmset G bs" + "wfactors G bs b" "set bs \ carrier G" + using factor_mset_aux assms(2) by blast + hence "a divides b \ fmset G as \# fmset G bs" + using as_def bs_def assms + by (intro divides_as_fmsubset) auto + also have "... \ factor_mset G a \# factor_mset G b" + using as_def bs_def by simp + finally show ?thesis by simp +qed + +lemma factor_mset_sim: + assumes "a \ carrier G" "b \ carrier G" + shows "a \ b \ factor_mset G a = factor_mset G b" + using factor_mset_divides assms + by (simp add:associated_def) auto + +lemma factor_mset_prod: + assumes "finite A" + assumes "f ` A \ carrier G" + shows "factor_mset G (\a \ A. f a) = + (\a \ A. factor_mset G (f a))" + using assms +proof (induction A rule:finite_induct) + case empty + then show ?case by (simp add:factor_mset_unit) +next + case (insert x F) + have "factor_mset G (finprod G f (insert x F)) = + factor_mset G (f x \ finprod G f F)" + using insert by (subst finprod_insert) auto + also have "... = factor_mset G (f x) + factor_mset G (finprod G f F)" + using insert by (intro factor_mset_mult finprod_closed) auto + also have + "... = factor_mset G (f x) + (\a \ F. factor_mset G (f a))" + using insert by simp + also have "... = (\a\insert x F. factor_mset G (f a))" + using insert by simp + finally show ?case by simp +qed + +lemma factor_mset_pow: + assumes "a \ carrier G" + shows "factor_mset G (a [^] n) = repeat_mset n (factor_mset G a)" +proof (induction n) + case 0 + then show ?case by (simp add:factor_mset_unit) +next + case (Suc n) + have "factor_mset G (a [^] Suc n) = factor_mset G (a [^] n \ a)" + by simp + also have "... = factor_mset G (a [^] n) + factor_mset G a" + using assms by (intro factor_mset_mult) auto + also have "... = repeat_mset n (factor_mset G a) + factor_mset G a" + using Suc by simp + also have "... = repeat_mset (Suc n) (factor_mset G a)" + by simp + finally show ?case by simp +qed + +lemma image_mset_sum: + assumes "finite F" + shows + "image_mset h (\x \ F. f x) = (\x \ F. image_mset h (f x))" + using assms + by (induction F rule:finite_induct, simp, simp) + +lemma decomp_mset: + "(\x\set_mset R. replicate_mset (count R x) x) = R" + by (rule multiset_eqI, simp add:count_sum count_eq_zero_iff) + +lemma factor_mset_count: + assumes "a \ carrier G" "d \ carrier G" "irreducible G d" + shows "count (factor_mset G a) (assocs G d) = multiplicity G d a" +proof - + have a: + "count (factor_mset G a) (assocs G d) \ m \ d [^] m divides a" + (is "?lhs \ ?rhs") for m + proof - + have "?lhs \ replicate_mset m (assocs G d) \# factor_mset G a" + by (simp add:count_le_replicate_mset_subset_eq) + also have "... \ factor_mset G (d [^] m) \# factor_mset G a" + using assms(2,3) by (simp add:factor_mset_pow factor_mset_irred) + also have "... \ ?rhs" + using assms(1,2) by (subst factor_mset_divides) auto + finally show ?thesis by simp + qed + + define M where "M = {(m::nat). d [^] m divides a}" + + have M_alt: "M = {m. m \ count (factor_mset G a) (assocs G d)}" + using a by (simp add:M_def) + + hence "Max M = count (factor_mset G a) (assocs G d)" + by (intro Max_eqI, auto) + thus ?thesis + unfolding multiplicity_def M_def by auto +qed + +lemma multiplicity_ge_iff: + assumes "d \ carrier G" "irreducible G d" "a \ carrier G" + shows "multiplicity G d a \ k \ d [^] k divides a" + (is "?lhs \ ?rhs") +proof - + have "?lhs \ count (factor_mset G a) (assocs G d) \ k" + using factor_mset_count[OF assms(3,1,2)] by simp + also have "... \ replicate_mset k (assocs G d) \# factor_mset G a" + by (subst count_le_replicate_mset_subset_eq, simp) + also have "... \ + repeat_mset k (factor_mset G d) \# factor_mset G a" + by (subst factor_mset_irred[OF assms(1,2)], simp) + also have "... \ factor_mset G (d [^]\<^bsub>G\<^esub> k) \# factor_mset G a" + by (subst factor_mset_pow[OF assms(1)], simp) + also have "... \ (d [^] k) divides\<^bsub>G\<^esub> a" + using assms(1) factor_mset_divides[OF _ assms(3)] by simp + finally show ?thesis by simp +qed + +lemma multiplicity_gt_0_iff: + assumes "d \ carrier G" "irreducible G d" "a \ carrier G" + shows "multiplicity G d a > 0 \ d divides a" + using multiplicity_ge_iff[OF assms(1,2,3), where k="1"] assms + by auto + +lemma factor_mset_count_2: + assumes "a \ carrier G" + assumes "\z. z \ carrier G \ irreducible G z \ y \ assocs G z" + shows "count (factor_mset G a) y = 0" + using factor_mset_set [OF assms(1)] assms(2) by (metis count_inI) + +lemma factor_mset_choose: + assumes "a \ carrier G" "set_mset R \ carrier G" + assumes "image_mset (assocs G) R = factor_mset G a" + shows "a \ (\x\set_mset R. x [^] count R x)" (is "a \ ?rhs") +proof - + have b:"irreducible G x" if a:"x \# R" for x + proof - + have x_carr: "x \ carrier G" + using a assms(2) by auto + have "assocs G x \ assocs G ` set_mset R" + using a by simp + hence "assocs G x \# factor_mset G a" + using assms(3) a in_image_mset by metis + then obtain z where z_def: + "z \ carrier G" "irreducible G z" "assocs G x = assocs G z" + using factor_mset_set assms(1) by metis + have "z \ x" using z_def(1,3) assocs_eqD x_carr by simp + thus ?thesis using z_def(1,2) x_carr irreducible_cong by simp + qed + + have "factor_mset G ?rhs = + (\x\set_mset R. factor_mset G (x [^] count R x))" + using assms(2) by (subst factor_mset_prod, auto) + also have "... = + (\x\set_mset R. repeat_mset (count R x) (factor_mset G x))" + using assms(2) by (intro sum.cong, auto simp add:factor_mset_pow) + also have "... = (\x\set_mset R. + repeat_mset (count R x) (image_mset (assocs G) {#x#}))" + using assms(2) b by (intro sum.cong, auto simp add:factor_mset_irred) + also have "... = (\x\set_mset R. + image_mset (assocs G) (replicate_mset (count R x) x))" + by simp + also have "... = image_mset (assocs G) + (\x\set_mset R. (replicate_mset (count R x) x))" + by (simp add: image_mset_sum) + also have "... = image_mset (assocs G) R" + by (simp add:decomp_mset) + also have "... = factor_mset G a" + using assms by simp + finally have "factor_mset G ?rhs = factor_mset G a" by simp + moreover have "(\x\set_mset R. x [^] count R x) \ carrier G" + using assms(2) by (intro finprod_closed, auto) + ultimately show ?thesis + using assms(1) by (subst factor_mset_sim) auto +qed + +lemma divides_iff_mult_mono: + assumes "a \ carrier G" "b \ carrier G" + assumes "canonical_irreducibles G R" + assumes "\d. d \ R \ multiplicity G d a \ multiplicity G d b" + shows "a divides b" +proof - + have "count (factor_mset G a) d \ count (factor_mset G b) d" for d + proof (cases "\y \ carrier G. irreducible G y \ d = assocs G y") + case True + then obtain y where y_def: + "irreducible G y" "y \ carrier G" "d = assocs G y" + by blast + then obtain z where z_def: "z \ R" "y \ z" + using assms(3) unfolding canonical_irreducibles_def by metis + have z_more: "irreducible G z" "z \ carrier G" + using z_def(1) assms(3) + unfolding canonical_irreducibles_def by auto + have "y \ assocs G z" using z_def(2) z_more(2) y_def(2) + by (simp add: closure_ofI2) + hence d_def: "d = assocs G z" + using y_def(2,3) z_more(2) assocs_repr_independence + by blast + have "count (factor_mset G a) d = multiplicity G z a" + unfolding d_def + by (intro factor_mset_count[OF assms(1) z_more(2,1)]) + also have "... \ multiplicity G z b" + using assms(4) z_def(1) by simp + also have "... = count (factor_mset G b) d" + unfolding d_def + by (intro factor_mset_count[symmetric, OF assms(2) z_more(2,1)]) + finally show ?thesis by simp + next + case False + have "count (factor_mset G a) d = 0" using False + by (intro factor_mset_count_2[OF assms(1)], simp) + moreover have "count (factor_mset G b) d = 0" using False + by (intro factor_mset_count_2[OF assms(2)], simp) + ultimately show ?thesis by simp + qed + + hence "factor_mset G a \# factor_mset G b" + unfolding subseteq_mset_def by simp + thus ?thesis using factor_mset_divides assms(1,2) by simp +qed + +lemma count_image_mset_inj: + assumes "inj_on f R" "x \ R" "set_mset A \ R" + shows "count (image_mset f A) (f x) = count A x" +proof (cases "x \# A") + case True + hence "(f y = f x \ y \# A) = (y = x)" for y + by (meson assms(1) assms(3) inj_onD subsetD) + hence "(f -` {f x} \ set_mset A) = {x}" + by (simp add:set_eq_iff) + thus ?thesis + by (subst count_image_mset, simp) +next + case False + hence "x \ set_mset A" by simp + hence "f x \ f ` set_mset A" using assms + by (simp add: inj_on_image_mem_iff) + hence "count (image_mset f A) (f x) = 0" + by (simp add:count_eq_zero_iff) + thus ?thesis by (metis count_inI False) +qed + +text \Factorization of an element from a @{locale "factorial_monoid"} using a selection of representatives +from each equivalence class formed by @{term "(\)"}.\ + +lemma split_factors: + assumes "canonical_irreducibles G R" + assumes "a \ carrier G" + shows + "finite {d. d \ R \ multiplicity G d a > 0}" + "a \ (\d\{d. d \ R \ multiplicity G d a > 0}. + d [^] multiplicity G d a)" (is "a \ ?rhs") +proof - + have r_1: "R \ {x. x \ carrier G \ irreducible G x}" + using assms(1) unfolding canonical_irreducibles_def by simp + have r_2: "\x y. x \ R \ y \ R \ x \ y \ x = y" + using assms(1) unfolding canonical_irreducibles_def by simp + + have assocs_inj: "inj_on (assocs G) R" + using r_1 r_2 assocs_eqD by (intro inj_onI, blast) + + define R' where + "R' = (\d\ {d. d \ R \ multiplicity G d a > 0}. + replicate_mset (multiplicity G d a) d)" + + have "count (factor_mset G a) (assocs G x) > 0" + if "x \ R" "0 < multiplicity G x a" for x + using assms r_1 r_2 that + by (subst factor_mset_count[OF assms(2)]) auto + hence "assocs G ` {d \ R. 0 < multiplicity G d a} + \ set_mset (factor_mset G a)" + by (intro image_subsetI, simp) + hence a:"finite (assocs G ` {d \ R. 0 < multiplicity G d a})" + using finite_subset by auto + + show "finite {d \ R. 0 < multiplicity G d a}" + using assocs_inj inj_on_subset[OF assocs_inj] + by (intro finite_imageD[OF a], simp) + + hence count_R': + "count R' d = (if d \ R then multiplicity G d a else 0)" + for d + by (auto simp add:R'_def count_sum) + + have set_R': "set_mset R' = {d \ R. 0 < multiplicity G d a}" + unfolding set_mset_def using count_R' by auto + + have "count (image_mset (assocs G) R') x = + count (factor_mset G a) x" for x + proof (cases "\x'. x' \ R \ x = assocs G x'") + case True + then obtain x' where x'_def: "x' \ R" "x = assocs G x'" + by blast + have "count (image_mset (assocs G) R') x = count R' x'" + using assocs_inj inj_on_subset[OF assocs_inj] x'_def + by (subst x'_def(2), subst count_image_mset_inj[OF assocs_inj]) + (auto simp:set_R') + also have "... = multiplicity G x' a" + using count_R' x'_def by simp + also have "... = count (factor_mset G a) (assocs G x')" + using x'_def(1) r_1 + by (subst factor_mset_count[OF assms(2)]) auto + also have "... = count (factor_mset G a) x" + using x'_def(2) by simp + finally show ?thesis by simp + next + case False + have a:"x \ assocs G z" + if a1: "z \ carrier G" and a2: "irreducible G z" for z + proof - + obtain v where v_def: "v \ R" "z \ v" + using a1 a2 assms(1) + unfolding canonical_irreducibles_def by auto + hence "z \ assocs G v" + using a1 r_1 v_def(1) by (simp add: closure_ofI2) + hence "assocs G z = assocs G v" + using a1 r_1 v_def(1) assocs_repr_independence + by auto + moreover have "x \ assocs G v" + using False v_def(1) by simp + ultimately show ?thesis by simp + qed + + have "count (image_mset (assocs G) R') x = 0" + using False count_R' by (simp add: count_image_mset) auto + also have "... = count (factor_mset G a) x" + using a + by (intro factor_mset_count_2[OF assms(2), symmetric]) auto + finally show ?thesis by simp + qed + + hence "image_mset (assocs G) R' = factor_mset G a" + by (rule multiset_eqI) + + moreover have "set_mset R' \ carrier G" + using r_1 by (auto simp add:set_R') + ultimately have "a \ (\x\set_mset R'. x [^] count R' x)" + using assms(2) by (intro factor_mset_choose, auto) + also have "... = ?rhs" + using set_R' assms r_1 r_2 + by (intro finprod_cong', auto simp add:count_R') + finally show "a \ ?rhs" by simp +qed + +end + +end \ No newline at end of file diff --git a/thys/Finite_Fields/Finite_Fields_Isomorphic.thy b/thys/Finite_Fields/Finite_Fields_Isomorphic.thy new file mode 100644 --- /dev/null +++ b/thys/Finite_Fields/Finite_Fields_Isomorphic.thy @@ -0,0 +1,367 @@ +section \Isomorphism between Finite Fields\label{sec:uniqueness}\ + +theory Finite_Fields_Isomorphic + imports + Card_Irreducible_Polynomials +begin + +lemma (in finite_field) eval_on_root_is_iso: + defines "p \ char R" + assumes "f \ carrier (poly_ring (ZFact p))" + assumes "pirreducible\<^bsub>(ZFact p)\<^esub> (carrier (ZFact p)) f" + assumes "order R = p^degree f" + assumes "x \ carrier R" + assumes "eval (map (char_iso R) f) x = \" + shows "ring_hom_ring (Rupt\<^bsub>(ZFact p)\<^esub> (carrier (ZFact p)) f) R + (\g. the_elem ((\g'. eval (map (char_iso R) g') x) ` g))" +proof - + let ?P = "poly_ring (ZFact p)" + + have char_pos: "char R > 0" + using finite_carr_imp_char_ge_0[OF finite_carrier] by simp + + have p_prime: "Factorial_Ring.prime p" + unfolding p_def + using characteristic_is_prime[OF char_pos] by simp + + interpret zf: finite_field "ZFact p" + using zfact_prime_is_finite_field p_prime by simp + interpret pzf: principal_domain "poly_ring (ZFact p)" + using zf.univ_poly_is_principal[OF zf.carrier_is_subfield] by simp + + interpret i: ideal "(PIdl\<^bsub>?P\<^esub> f)" "?P" + by (intro pzf.cgenideal_ideal assms(2)) + have rupt_carr: "y \ carrier (poly_ring (ZFact p))" + if "y \ carrier (Rupt\<^bsub>ZFact p\<^esub> (carrier (ZFact p)) f)" for y + using that pzf.quot_carr i.ideal_axioms by (simp add:rupture_def) + + have rupt_is_ring: "ring (Rupt\<^bsub>ZFact p\<^esub> (carrier (ZFact p)) f)" + unfolding rupture_def by (intro i.quotient_is_ring) + + have "map (char_iso R) \ + ring_iso ?P (poly_ring (R\carrier := char_subring R\))" + using lift_iso_to_poly_ring[OF char_iso] zf.domain_axioms + using char_ring_is_subdomain subdomain_is_domain + by (simp add:p_def) + moreover have "(char_subring R)[X] = + poly_ring (R \carrier := char_subring R\)" + using univ_poly_consistent[OF char_ring_is_subring] by simp + ultimately have + "map (char_iso R) \ ring_hom ?P ((char_subring R)[X])" + by (simp add:ring_iso_def) + moreover have "(\p. eval p x) \ ring_hom ((char_subring R)[X]) R" + using eval_is_hom char_ring_is_subring assms(5) by simp + ultimately have + "(\p. eval p x) \ map (char_iso R) \ ring_hom ?P R" + using ring_hom_trans by blast + hence a:"(\p. eval (map (char_iso R) p) x) \ ring_hom ?P R" + by (simp add:comp_def) + interpret h:ring_hom_ring "?P" "R" "(\p. eval (map (char_iso R) p) x)" + by (intro ring_hom_ringI2 pzf.is_ring a ring_axioms) + + let ?h = "(\p. eval (map (char_iso R) p) x)" + let ?J = "a_kernel (poly_ring (ZFact (int p))) R ?h" + + have "?h ` a_kernel (poly_ring (ZFact (int p))) R ?h \ {\}" + by auto + moreover have + "\\<^bsub>?P\<^esub> \ a_kernel (poly_ring (ZFact (int p))) R ?h" + "?h \\<^bsub>?P\<^esub> = \" + unfolding a_kernel_def' by simp_all + hence "{\} \ ?h ` a_kernel (poly_ring (ZFact (int p))) R ?h" + by simp + ultimately have c: + "?h ` a_kernel (poly_ring (ZFact (int p))) R ?h = {\}" + by auto + + have d: "PIdl\<^bsub>?P\<^esub> f \ a_kernel ?P R ?h" + proof (rule subsetI) + fix y assume "y \ PIdl\<^bsub>?P\<^esub> f" + then obtain y' where y'_def: "y' \ carrier ?P" "y = y' \\<^bsub>?P\<^esub> f" + unfolding cgenideal_def by auto + have "?h y = ?h (y' \\<^bsub>?P\<^esub> f)" by (simp add:y'_def) + also have "... = ?h y' \ ?h f" + using y'_def assms(2) by simp + also have "... = ?h y' \ \" + using assms(6) by simp + also have "... = \" + using y'_def by simp + finally have "?h y = \" by simp + moreover have "y \ carrier ?P" using y'_def assms(2) by simp + ultimately show "y \ a_kernel ?P R ?h" + unfolding a_kernel_def kernel_def by simp + qed + + have "(\y. the_elem ((\p. eval (map (char_iso R) p) x) ` y)) + \ ring_hom (?P Quot ?J) R" + using h.the_elem_hom by simp + moreover have "(\y. ?J <+>\<^bsub>?P\<^esub> y) + \ ring_hom (Rupt\<^bsub>(ZFact p)\<^esub> (carrier (ZFact p)) f) (?P Quot ?J)" + unfolding rupture_def using h.kernel_is_ideal d assms(2) + by (intro pzf.quot_quot_hom pzf.cgenideal_ideal) auto + ultimately have "(\y. the_elem (?h ` y)) \ (\y. ?J <+>\<^bsub>?P\<^esub> y) + \ ring_hom (Rupt\<^bsub>(ZFact p)\<^esub> (carrier (ZFact p)) f) R" + using ring_hom_trans by blast + hence b: "(\y. the_elem (?h ` (?J <+>\<^bsub>?P\<^esub> y))) \ + ring_hom (Rupt\<^bsub>(ZFact p)\<^esub> (carrier (ZFact p)) f) R" + by (simp add:comp_def) + have "?h ` y = ?h ` (?J <+>\<^bsub>?P\<^esub> y)" + if "y \ carrier (Rupt\<^bsub>ZFact p\<^esub> (carrier (ZFact p)) f)" + for y + proof - + have y_range: "y \ carrier ?P" + using rupt_carr that by simp + have "?h ` y = {\} <+>\<^bsub>R\<^esub> ?h ` y" + using y_range h.hom_closed by (subst set_add_zero, auto) + also have "... = ?h ` ?J <+>\<^bsub>R\<^esub> ?h ` y" + by (subst c, simp) + also have "... = ?h ` (?J <+>\<^bsub>?P\<^esub> y)" + by (subst set_add_hom[OF a _ y_range], subst a_kernel_def') auto + finally show ?thesis by simp + qed + hence "(\y. the_elem (?h ` y)) \ + ring_hom (Rupt\<^bsub>(ZFact p)\<^esub> (carrier (ZFact p)) f) R" + by (intro ring_hom_cong[OF _ rupt_is_ring b]) simp + thus ?thesis + by (intro ring_hom_ringI2 rupt_is_ring ring_axioms, simp) +qed + +lemma (in domain) pdivides_consistent: + assumes "subfield K R" "f \ carrier (K[X])" "g \ carrier (K[X])" + shows "f pdivides g \ f pdivides\<^bsub>R \ carrier := K \\<^esub> g" +proof - + have a:"subring K R" + using assms(1) subfieldE(1) by auto + let ?S = "R \ carrier := K \" + have "f pdivides g \ f divides\<^bsub>K[X]\<^esub> g" + using pdivides_iff_shell[OF assms] by simp + also have "... \ (\x \ carrier (K[X]). f \\<^bsub>K[X]\<^esub> x = g)" + unfolding pdivides_def factor_def by auto + also have "... \ + (\x \ carrier (poly_ring ?S). f \\<^bsub>poly_ring ?S\<^esub> x = g)" + using univ_poly_consistent[OF a] by simp + also have "... \ f divides\<^bsub>poly_ring ?S\<^esub> g" + unfolding pdivides_def factor_def by auto + also have "... \ f pdivides\<^bsub>?S\<^esub> g" + unfolding pdivides_def by simp + finally show ?thesis by simp +qed + +lemma (in finite_field) find_root: + assumes "subfield K R" + assumes "monic_irreducible_poly (R \ carrier := K \) f" + assumes "order R = card K^degree f" + obtains x where "eval f x = \" "x \ carrier R" +proof - + define \ :: "'a list \ 'a list" where "\ = id" + let ?K = "R \ carrier := K \" + have "finite K" + using assms(1) by (intro finite_subset[OF _ finite_carrier], simp) + hence fin_K: "finite (carrier (?K))" + by simp + interpret f: finite_field "?K" + using assms(1) subfield_iff fin_K finite_fieldI by blast + have b:"subring K R" + using assms(1) subfieldE(1) by blast + interpret e: ring_hom_ring "(K[X])" "(poly_ring R)" "\" + using embed_hom[OF b] by (simp add:\_def) + + have a: "card K^degree f > 1" + using assms(3) finite_field_min_order by simp + have "f \ carrier (poly_ring ?K)" + using f.monic_poly_carr assms(2) + unfolding monic_irreducible_poly_def by simp + hence f_carr_2: "f \ carrier (K[X])" + using univ_poly_consistent[OF b] by simp + have f_carr: "f \ carrier (poly_ring R)" + using e.hom_closed[OF f_carr_2] unfolding \_def by simp + + have gp_carr: "gauss_poly ?K (order ?K^degree f) \ carrier (K[X])" + using f.gauss_poly_carr univ_poly_consistent[OF b] by simp + + have "gauss_poly ?K (order ?K^degree f) = + gauss_poly ?K (card K^degree f)" + by (simp add:Coset.order_def) + also have "... = + X\<^bsub>?K\<^esub> [^]\<^bsub>poly_ring ?K\<^esub> card K ^ degree f \\<^bsub>poly_ring ?K\<^esub> X\<^bsub>?K\<^esub>" + unfolding gauss_poly_def by simp + also have "... = X\<^bsub>R\<^esub> [^]\<^bsub>K[X]\<^esub> card K ^ degree f \\<^bsub>K[X]\<^esub> X\<^bsub>R\<^esub>" + unfolding var_def using univ_poly_consistent[OF b] by simp + also have "... = \ (X\<^bsub>R\<^esub> [^]\<^bsub>K[X]\<^esub> card K ^ degree f \\<^bsub>K[X]\<^esub> X\<^bsub>R\<^esub>)" + unfolding \_def by simp + also have "... = gauss_poly R (card K^degree f)" + unfolding gauss_poly_def a_minus_def using var_closed[OF b] + by (simp add:e.hom_nat_pow, simp add:\_def) + finally have gp_consistent: "gauss_poly ?K (order ?K^degree f) = + gauss_poly R (card K^degree f)" + by simp + + have deg_f: "degree f > 0" + using f.monic_poly_min_degree[OF assms(2)] by simp + + have "splitted f" + proof (cases "degree f > 1") + case True + + have "f pdivides\<^bsub>?K\<^esub> gauss_poly ?K (order ?K^degree f)" + using f.div_gauss_poly_iff[OF deg_f assms(2)] by simp + hence "f pdivides gauss_poly ?K (order ?K^degree f)" + using pdivides_consistent[OF assms(1)] f_carr_2 gp_carr by simp + hence "f pdivides gauss_poly R (card K^degree f)" + using gp_consistent by simp + moreover have "splitted (gauss_poly R (card K^degree f))" + unfolding assms(3)[symmetric] using gauss_poly_splitted by simp + moreover have "gauss_poly R (card K^degree f) \ []" + using gauss_poly_not_zero a by (simp add: univ_poly_zero) + ultimately show "splitted f" + using pdivides_imp_splitted f_carr gauss_poly_carr by auto + next + case False + hence "degree f = 1" using deg_f by simp + thus ?thesis using f_carr degree_one_imp_splitted by auto + qed + hence "size (roots f) > 0" + using deg_f unfolding splitted_def by simp + then obtain x where x_def: "x \ carrier R" "is_root f x" + using roots_mem_iff_is_root[OF f_carr] + by (metis f_carr nonempty_has_size not_empty_rootsE) + have "eval f x = \" + using x_def is_root_def by blast + thus ?thesis using x_def using that by simp +qed + +lemma (in finite_field) find_iso_from_zfact: + defines "p \ int (char R)" + assumes "monic_irreducible_poly (ZFact p) f" + assumes "order R = char R^degree f" + shows "\\. \ \ ring_iso (Rupt\<^bsub>(ZFact p)\<^esub> (carrier (ZFact p)) f) R" +proof - + have char_pos: "char R > 0" + using finite_carr_imp_char_ge_0[OF finite_carrier] by simp + + interpret zf: finite_field "ZFact p" + unfolding p_def using zfact_prime_is_finite_field + using characteristic_is_prime[OF char_pos] by simp + + interpret zfp: polynomial_ring "ZFact p" "carrier (ZFact p)" + unfolding polynomial_ring_def polynomial_ring_axioms_def + using zf.field_axioms zf.carrier_is_subfield by simp + + let ?f' = "map (char_iso R) f" + let ?F = "Rupt\<^bsub>(ZFact p)\<^esub> (carrier (ZFact p)) f" + + have "domain (R\carrier := char_subring R\)" + using char_ring_is_subdomain subdomain_is_domain by simp + + hence "monic_irreducible_poly (R \ carrier := char_subring R \) ?f'" + using char_iso p_def zf.domain_axioms + by (intro monic_irreducible_poly_hom[OF assms(2)]) auto + moreover have "order R = card (char_subring R)^degree ?f'" + using assms(3) unfolding char_def by simp + ultimately obtain x where x_def: "eval ?f' x = \" "x \ carrier R" + using find_root[OF char_ring_is_subfield[OF char_pos]] by blast + let ?\ = "(\g. the_elem ((\g'. eval (map (char_iso R) g') x) ` g))" + interpret r: ring_hom_ring "?F" "R" "?\" + using assms(2,3) + unfolding monic_irreducible_poly_def monic_poly_def p_def + by (intro eval_on_root_is_iso x_def, auto) + have a:"?\ \ ring_hom ?F R" + using r.homh by auto + + have "field (Rupt\<^bsub>ZFact p\<^esub> (carrier (ZFact p)) f)" + using assms(2) + unfolding monic_irreducible_poly_def monic_poly_def + by (subst zfp.rupture_is_field_iff_pirreducible, simp_all) + hence b:"inj_on ?\ (carrier ?F)" + using non_trivial_field_hom_is_inj[OF a _ field_axioms] by simp + + have "card (?\ ` carrier ?F) = order ?F" + using card_image[OF b] unfolding Coset.order_def by simp + also have "... = card (carrier (ZFact p))^degree f" + using assms(2) zf.monic_poly_min_degree[OF assms(2)] + unfolding monic_irreducible_poly_def monic_poly_def + by (intro zf.rupture_order[OF zf.carrier_is_subfield]) auto + also have "... = char R ^degree f" + unfolding p_def by (subst card_zfact_carr[OF char_pos], simp) + also have "... = card (carrier R)" + using assms(3) unfolding Coset.order_def by simp + finally have "card (?\ ` carrier ?F) = card (carrier R)" by simp + moreover have "?\ ` carrier ?F \ carrier R" + by (intro image_subsetI, simp) + ultimately have "?\ ` carrier ?F = carrier R" + by (intro card_seteq finite_carrier, auto) + hence "bij_betw ?\ (carrier ?F) (carrier R)" + using b bij_betw_imageI by auto + + thus ?thesis + unfolding ring_iso_def using a b by auto +qed + +theorem uniqueness: + assumes "finite_field F\<^sub>1" + assumes "finite_field F\<^sub>2" + assumes "order F\<^sub>1 = order F\<^sub>2" + shows "F\<^sub>1 \ F\<^sub>2" +proof - + obtain n where o1: "order F\<^sub>1 = char F\<^sub>1^n" "n > 0" + using finite_field.finite_field_order[OF assms(1)] by auto + obtain m where o2: "order F\<^sub>2 = char F\<^sub>2^m" "m > 0" + using finite_field.finite_field_order[OF assms(2)] by auto + + interpret f1: "finite_field" F\<^sub>1 using assms(1) by simp + interpret f2: "finite_field" F\<^sub>2 using assms(2) by simp + + have char_pos: "char F\<^sub>1 > 0" "char F\<^sub>2 > 0" + using f1.finite_carrier f1.finite_carr_imp_char_ge_0 + using f2.finite_carrier f2.finite_carr_imp_char_ge_0 by auto + hence char_prime: + "Factorial_Ring.prime (char F\<^sub>1)" + "Factorial_Ring.prime (char F\<^sub>2)" + using f1.characteristic_is_prime f2.characteristic_is_prime + by auto + + have "char F\<^sub>1^n = char F\<^sub>2^m" + using o1 o2 assms(3) by simp + hence eq: "n = m" "char F\<^sub>1 = char F\<^sub>2" + using char_prime char_pos o1(2) o2(2) prime_power_inj' by auto + + obtain p where p_def: "p = char F\<^sub>1" "p = char F\<^sub>2" + using eq by simp + + have p_prime: "Factorial_Ring.prime p" + unfolding p_def(1) + using f1.characteristic_is_prime char_pos by simp + + interpret zf: finite_field "ZFact (int p)" + using zfact_prime_is_finite_field p_prime o1(2) + using prime_nat_int_transfer by blast + + interpret zfp: polynomial_ring "ZFact p" "carrier (ZFact p)" + unfolding polynomial_ring_def polynomial_ring_axioms_def + using zf.field_axioms zf.carrier_is_subfield by simp + + obtain f where f_def: + "monic_irreducible_poly (ZFact (int p)) f" "degree f = n" + using zf.exist_irred o1(2) by auto + + let ?F\<^sub>0 = "Rupt\<^bsub>(ZFact p)\<^esub> (carrier (ZFact p)) f" + + obtain \\<^sub>1 where \\<^sub>1_def: "\\<^sub>1 \ ring_iso ?F\<^sub>0 F\<^sub>1" + using f1.find_iso_from_zfact f_def o1 + unfolding p_def by auto + + obtain \\<^sub>2 where \\<^sub>2_def: "\\<^sub>2 \ ring_iso ?F\<^sub>0 F\<^sub>2" + using f2.find_iso_from_zfact f_def o2 + unfolding p_def(2) eq(1) by auto + + have "?F\<^sub>0 \ F\<^sub>1" using \\<^sub>1_def is_ring_iso_def by auto + moreover have "?F\<^sub>0 \ F\<^sub>2" using \\<^sub>2_def is_ring_iso_def by auto + moreover have "field ?F\<^sub>0" + using f_def(1) zf.monic_poly_carr monic_irreducible_poly_def + by (subst zfp.rupture_is_field_iff_pirreducible) auto + hence "ring ?F\<^sub>0" using field.is_ring by auto + ultimately show ?thesis + using ring_iso_trans ring_iso_sym by blast +qed + +end diff --git a/thys/Finite_Fields/Finite_Fields_Preliminary_Results.thy b/thys/Finite_Fields/Finite_Fields_Preliminary_Results.thy new file mode 100644 --- /dev/null +++ b/thys/Finite_Fields/Finite_Fields_Preliminary_Results.thy @@ -0,0 +1,1010 @@ +section \Introduction\ + +text \The following section starts with preliminary results. Section~\ref{sec:ring_char} introduces +the characteristic of rings with the Frobenius endomorphism. Whenever it makes sense, +the definitions and facts do not assume the finiteness of the fields or rings. For example the +characteristic is defined over arbitrary rings (and also fields). + +While formal derivatives do exist for type-class based structures in +\verb|HOL-Computational_Algebra|, as far as I can tell, they do not exist for the structure based +polynomials in \verb|HOL-Algebra|. These are introduced in Section~\ref{sec:pderiv}. + +A cornerstone of the proof is the derivation of Gauss' formula for the number of monic irreducible +polynomials over a finite field $R$ in Section~\ref{sec:card_irred}. The proof follows the +derivation by Ireland and Rosen~\cite[\textsection 7]{ireland1982} closely, with the caveat that it +does not assume that $R$ is a simple prime field, but that it is just a finite field. +This works by adjusting a proof step with the information that the order of a finite field must be +of the form $p^n$, where $p$ is the characteristic of the field, derived in Section~\ref{sec:ring_char}. +The final step relies on the M\"obius inversion theorem formalized by +Eberl~\cite{Dirichlet_Series-AFP}.\footnote{Thanks to Katharina Kreuzer for discovering that +formalization.} + +With Gauss' formula it is possible to show the existence of the finite fields of order $p^n$ +where $p$ is a prime and $n > 0$. During the proof the fact that the polynomial $X^n - X$ splits +in a field of order $n$ is also derived, which is necessary for the uniqueness result as well. + +The uniqueness proof is inspired by the derivation of the same result in +Lidl and Niederreiter~\cite{lidl1986}, but because of the already derived existence proof for +irreducible polynomials, it was possible to reduce its complexity. + +The classification consists of three theorems: +\begin{itemize} +\item \emph{Existence}: For each prime power $p^n$ there exists a finite field of that size. + This is shown at the conclusion of Section~\ref{sec:card_irred}. +\item \emph{Uniqueness}: Any two finite fields of the same size are isomorphic. + This is shown at the conclusion of Section~\ref{sec:uniqueness}. +\item \emph{Completeness}: Any finite fields' size must be a prime power. + This is shown at the conclusion of Section~\ref{sec:ring_char}. +\end{itemize} +\ + +section \Preliminary Results\ + +theory Finite_Fields_Preliminary_Results + imports "HOL-Algebra.Polynomial_Divisibility" +begin + +subsection \Summation in the discrete topology\ + +text \The following lemmas transfer the corresponding result from the summation over finite sets +to summation over functions which vanish outside of a finite set.\ + +lemma sum'_subtractf_nat: + fixes f :: "'a \ nat" + assumes "finite {i \ A. f i \ 0}" + assumes "\i. i \ A \ g i \ f i" + shows "sum' (\i. f i - g i) A = sum' f A - sum' g A" + (is "?lhs = ?rhs") +proof - + have c:"finite {i \ A. g i \ 0}" + using assms(2) + by (intro finite_subset[OF _ assms(1)] subsetI, force) + let ?B = "{i \ A. f i \ 0 \ g i \ 0}" + + have b:"?B = {i \ A. f i \ 0} \ {i \ A. g i \ 0}" + by (auto simp add:set_eq_iff) + have a:"finite ?B" + using assms(1) c by (subst b, simp) + have "?lhs = sum' (\i. f i - g i) ?B" + by (intro sum.mono_neutral_cong_right', simp_all) + also have "... = sum (\i. f i - g i) ?B" + by (intro sum.eq_sum a) + also have "... = sum f ?B - sum g ?B" + using assms(2) by (subst sum_subtractf_nat, auto) + also have "... = sum' f ?B - sum' g ?B" + by (intro arg_cong2[where f="(-)"] sum.eq_sum[symmetric] a) + also have "... = ?rhs" + by (intro arg_cong2[where f="(-)"] sum.mono_neutral_cong_left') + simp_all + finally show ?thesis + by simp +qed + +lemma sum'_nat_eq_0_iff: + fixes f :: "'a \ nat" + assumes "finite {i \ A. f i \ 0}" + assumes "sum' f A = 0" + shows "\i. i \ A \ f i = 0" +proof - + let ?B = "{i \ A. f i \ 0}" + + have "sum f ?B = sum' f ?B" + by (intro sum.eq_sum[symmetric] assms(1)) + also have "... = sum' f A" + by (intro sum.non_neutral') + also have "... = 0" using assms(2) by simp + finally have a:"sum f ?B = 0" by simp + have "\i. i \ ?B \ f i = 0" + using sum_nonneg_0[OF assms(1) _ a] by blast + thus "\i. i \ A \ f i = 0" + by blast +qed + +lemma sum'_eq_iff: + fixes f :: "'a \ nat" + assumes "finite {i \ A. f i \ 0}" + assumes "\i. i \ A \ f i \ g i" + assumes "sum' f A \ sum' g A" + shows "\i \ A. f i = g i" +proof - + have "{i \ A. g i \ 0} \ {i \ A. f i \ 0}" + using assms(2) order_less_le_trans + by (intro subsetI, auto) + hence a:"finite {i \ A. g i \ 0}" + by (rule finite_subset, intro assms(1)) + have " {i \ A. f i - g i \ 0} \ {i \ A. f i \ 0}" + by (intro subsetI, simp_all) + hence b: "finite {i \ A. f i - g i \ 0}" + by (rule finite_subset, intro assms(1)) + have "sum' (\i. f i - g i) A = sum' f A - sum' g A" + using assms(1,2) a by (subst sum'_subtractf_nat, auto) + also have "... = 0" + using assms(3) by simp + finally have "sum' (\i. f i - g i) A = 0" by simp + hence "\i. i \ A \ f i - g i = 0" + using sum'_nat_eq_0_iff[OF b] by simp + thus ?thesis + using assms(2) diff_is_0_eq' diffs0_imp_equal by blast +qed + +subsection \Polynomials\ + +text \The embedding of the constant polynomials into the polynomials is injective:\ + +lemma (in ring) poly_of_const_inj: + "inj poly_of_const" +proof - + have "coeff (poly_of_const x) 0 = x" for x + unfolding poly_of_const_def normalize_coeff[symmetric] + by simp + thus ?thesis by (metis injI) +qed + +lemma (in domain) embed_hom: + assumes "subring K R" + shows "ring_hom_ring (K[X]) (poly_ring R) id" +proof (rule ring_hom_ringI) + show "ring (K[X])" + using univ_poly_is_ring[OF assms(1)] by simp + show "ring (poly_ring R)" + using univ_poly_is_ring[OF carrier_is_subring] by simp + have "K \ carrier R" + using subringE(1)[OF assms(1)] by simp + thus "\x. x \ carrier (K [X]) \ id x \ carrier (poly_ring R)" + unfolding univ_poly_carrier[symmetric] polynomial_def by auto + show "id (x \\<^bsub>K [X]\<^esub> y) = id x \\<^bsub>poly_ring R\<^esub> id y" + if "x \ carrier (K [X])" "y \ carrier (K [X])" for x y + unfolding univ_poly_mult by simp + show "id (x \\<^bsub>K [X]\<^esub> y) = id x \\<^bsub>poly_ring R\<^esub> id y" + if "x \ carrier (K [X])" "y \ carrier (K [X])" for x y + unfolding univ_poly_add by simp + show "id \\<^bsub>K [X]\<^esub> = \\<^bsub>poly_ring R\<^esub>" + unfolding univ_poly_one by simp +qed + +text \The following are versions of the properties of the degrees of polynomials, that abstract +over the definition of the polynomial ring structure. In the theories +@{theory "HOL-Algebra.Polynomials"} and also @{theory "HOL-Algebra.Polynomial_Divisibility"} +these abstract version are usually indicated with the suffix ``shell'', consider for example: +@{thm [source] "domain.pdivides_iff_shell"}.\ + +lemma (in ring) degree_add_distinct: + assumes "subring K R" + assumes "f \ carrier (K[X]) - {\\<^bsub>K[X]\<^esub>}" + assumes "g \ carrier (K[X]) - {\\<^bsub>K[X]\<^esub>}" + assumes "degree f \ degree g" + shows "degree (f \\<^bsub>K[X]\<^esub> g) = max (degree f) (degree g)" + unfolding univ_poly_add using assms(2,3,4) + by (subst poly_add_degree_eq[OF assms(1)]) + (auto simp:univ_poly_carrier univ_poly_zero) + +lemma (in domain) degree_mult: + assumes "subring K R" + assumes "f \ carrier (K[X]) - {\\<^bsub>K[X]\<^esub>}" + assumes "g \ carrier (K[X]) - {\\<^bsub>K[X]\<^esub>}" + shows "degree (f \\<^bsub>K[X]\<^esub> g) = degree f + degree g" + unfolding univ_poly_mult using assms(2,3) + by (subst poly_mult_degree_eq[OF assms(1)]) + (auto simp:univ_poly_carrier univ_poly_zero) + +lemma (in ring) degree_one: + "degree (\\<^bsub>K[X]\<^esub>) = 0" + unfolding univ_poly_one by simp + +lemma (in domain) pow_non_zero: + "x \ carrier R \ x \ \ \ x [^] (n :: nat) \ \" + using integral by (induction n, auto) + +lemma (in domain) degree_pow: + assumes "subring K R" + assumes "f \ carrier (K[X]) - {\\<^bsub>K[X]\<^esub>}" + shows "degree (f [^]\<^bsub>K[X]\<^esub> n) = degree f * n" +proof - + interpret p:domain "K[X]" + using univ_poly_is_domain[OF assms(1)] by simp + + show ?thesis + proof (induction n) + case 0 + then show ?case by (simp add:univ_poly_one) + next + case (Suc n) + have "degree (f [^]\<^bsub>K [X]\<^esub> Suc n) = degree (f [^]\<^bsub>K [X]\<^esub> n \\<^bsub>K[X]\<^esub> f)" + by simp + also have "... = degree (f [^]\<^bsub>K [X]\<^esub> n) + degree f" + using p.pow_non_zero assms(2) + by (subst degree_mult[OF assms(1)], auto) + also have "... = degree f * Suc n" + by (subst Suc, simp) + finally show ?case by simp + qed +qed + +lemma (in ring) degree_var: + "degree (X\<^bsub>R\<^esub>) = 1" + unfolding var_def by simp + +lemma (in domain) var_carr: + fixes n :: nat + assumes "subring K R" + shows "X\<^bsub>R\<^esub> \ carrier (K[X]) - {\\<^bsub>K [X]\<^esub>}" +proof - + have "X\<^bsub>R\<^esub> \ carrier (K[X])" + using var_closed[OF assms(1)] by simp + moreover have "X \ \\<^bsub>K [X]\<^esub>" + unfolding var_def univ_poly_zero by simp + ultimately show ?thesis by simp +qed + +lemma (in domain) var_pow_carr: + fixes n :: nat + assumes "subring K R" + shows "X\<^bsub>R\<^esub> [^]\<^bsub>K [X]\<^esub> n \ carrier (K[X]) - {\\<^bsub>K [X]\<^esub>}" +proof - + interpret p:domain "K[X]" + using univ_poly_is_domain[OF assms(1)] by simp + + have "X\<^bsub>R\<^esub> [^]\<^bsub>K [X]\<^esub> n \ carrier (K[X])" + using var_pow_closed[OF assms(1)] by simp + moreover have "X \ \\<^bsub>K [X]\<^esub>" + unfolding var_def univ_poly_zero by simp + hence "X\<^bsub>R\<^esub> [^]\<^bsub>K [X]\<^esub> n \ \\<^bsub>K [X]\<^esub>" + using var_closed(1)[OF assms(1)] + by (intro p.pow_non_zero, auto) + ultimately show ?thesis by simp +qed + +lemma (in domain) var_pow_degree: + fixes n :: nat + assumes "subring K R" + shows "degree (X\<^bsub>R\<^esub> [^]\<^bsub>K [X]\<^esub> n) = n" + using var_carr[OF assms(1)] degree_var + by (subst degree_pow[OF assms(1)], auto) + +lemma (in domain) finprod_non_zero: + assumes "finite A" + assumes "f \ A \ carrier R - {\}" + shows "(\i \ A. f i) \ carrier R - {\}" + using assms +proof (induction A rule:finite_induct) + case empty + then show ?case by simp +next + case (insert x F) + have "finprod R f (insert x F) = f x \ finprod R f F" + using insert by (subst finprod_insert, simp_all add:Pi_def) + also have "... \ carrier R-{\}" + using integral insert by auto + finally show ?case by simp +qed + +lemma (in domain) degree_prod: + assumes "finite A" + assumes "subring K R" + assumes "f \ A \ carrier (K[X]) - {\\<^bsub>K[X]\<^esub>}" + shows "degree (\\<^bsub>K[X]\<^esub>i \ A. f i) = (\i \ A. degree (f i))" + using assms +proof - + interpret p:domain "K[X]" + using univ_poly_is_domain[OF assms(2)] by simp + + show ?thesis + using assms(1,3) + proof (induction A rule: finite_induct) + case empty + then show ?case by (simp add:univ_poly_one) + next + case (insert x F) + have "degree (finprod (K[X]) f (insert x F)) = + degree (f x \\<^bsub>K[X]\<^esub> finprod (K[X]) f F)" + using insert by (subst p.finprod_insert, auto) + also have "... = degree (f x) + degree (finprod (K[X]) f F)" + using insert p.finprod_non_zero[OF insert(1)] + by (subst degree_mult[OF assms(2)], simp_all) + also have "... = degree (f x) + (\i \ F. degree (f i))" + using insert by (subst insert(3), auto) + also have "... = (\i \ insert x F. degree (f i))" + using insert by simp + finally show ?case by simp + qed +qed + +lemma (in ring) coeff_add: + assumes "subring K R" + assumes "f \ carrier (K[X])" "g \ carrier (K[X])" + shows "coeff (f \\<^bsub>K[X]\<^esub> g) i = coeff f i \\<^bsub>R\<^esub> coeff g i" +proof - + have a:"set f \ carrier R" + using assms(1,2) univ_poly_carrier + using subringE(1)[OF assms(1)] polynomial_incl + by blast + have b:"set g \ carrier R" + using assms(1,3) univ_poly_carrier + using subringE(1)[OF assms(1)] polynomial_incl + by blast + show ?thesis + unfolding univ_poly_add poly_add_coeff[OF a b] by simp +qed + +text \This is a version of geometric sums for commutative rings:\ + +lemma (in cring) geom: + fixes q:: nat + assumes [simp]: "a \ carrier R" + shows "(a \ \) \ (\i\{.. \)" + (is "?lhs = ?rhs") +proof - + have [simp]: "a [^] i \ carrier R" for i :: nat + by (intro nat_pow_closed assms) + have [simp]: "\ \ \ x = \ x" if "x \ carrier R" for x + using l_minus l_one one_closed that by presburger + + let ?cterm = "(\i\{1.. (\i\{.. (\i\{..i\{.. a [^] i) \ (\i\{..i\{.. (\i\{..i\Suc ` {.. (\i\{..i\ insert q {1.. + (\i\ insert 0 {1.. 0") + case True + moreover have "Suc ` {.. ?cterm) \ (\ \ ?cterm)" + by simp + also have "... = a [^] q \ ?cterm \ (\ \ \ \ ?cterm)" + unfolding a_minus_def by (subst minus_add, simp_all) + also have "... = a [^] q \ (?cterm \ (\ \ \ \ ?cterm))" + by (subst a_assoc, simp_all) + also have "... = a [^] q \ (?cterm \ (\ ?cterm \ \ \))" + by (subst a_comm[where x="\ \"], simp_all) + also have "... = a [^] q \ ((?cterm \ (\ ?cterm)) \ \ \)" + by (subst a_assoc, simp_all) + also have "... = a [^] q \ (\ \ \ \)" + by (subst r_neg, simp_all) + also have "... = a [^] q \ \" + unfolding a_minus_def by simp + finally show ?thesis by simp +qed + +lemma (in domain) rupture_eq_0_iff: + assumes "subfield K R" "p \ carrier (K[X])" "q \ carrier (K[X])" + shows "rupture_surj K p q = \\<^bsub>Rupt K p\<^esub> \ p pdivides q" + (is "?lhs \ ?rhs") +proof - + interpret h:ring_hom_ring "K[X]" "(Rupt K p)" "(rupture_surj K p)" + using assms subfieldE by (intro rupture_surj_hom) auto + + have a: "q pmod p \ (\q. q pmod p) ` carrier (K [X])" + using assms(3) by simp + have "\\<^bsub>K[X]\<^esub> = \\<^bsub>K[X]\<^esub> pmod p" + using assms(1,2) long_division_zero(2) + by (simp add:univ_poly_zero) + hence b: "\\<^bsub>K[X]\<^esub> \ (\q. q pmod p) ` carrier (K[X])" + by (simp add:image_iff) auto + + have "?lhs \ rupture_surj K p (q pmod p) = + rupture_surj K p (\\<^bsub>K[X]\<^esub>)" + by (subst rupture_surj_composed_with_pmod[OF assms]) simp + also have "... \ q pmod p = \\<^bsub>K[X]\<^esub>" + using assms(3) + by (intro inj_on_eq_iff[OF rupture_surj_inj_on[OF assms(1,2)]] a b) + also have "... \ ?rhs" + unfolding univ_poly_zero + by (intro pmod_zero_iff_pdivides[OF assms(1)] assms(2,3)) + finally show "?thesis" by simp +qed + +subsection \Ring Isomorphisms\ + +text \The following lemma shows that an isomorphism between domains also induces an isomorphism +between the corresponding polynomial rings.\ + +lemma lift_iso_to_poly_ring: + assumes "h \ ring_iso R S" "domain R" "domain S" + shows "map h \ ring_iso (poly_ring R) (poly_ring S)" +proof (rule ring_iso_memI) + interpret dr: domain "R" using assms(2) by blast + interpret ds: domain "S" using assms(3) by blast + interpret pdr: domain "poly_ring R" + using dr.univ_poly_is_domain[OF dr.carrier_is_subring] by simp + interpret pds: domain "poly_ring S" + using ds.univ_poly_is_domain[OF ds.carrier_is_subring] by simp + interpret h: ring_hom_ring "R" "S" h + using dr.is_ring ds.is_ring assms(1) + by (intro ring_hom_ringI2, simp_all add:ring_iso_def) + let ?R = "poly_ring R" + let ?S = "poly_ring S" + + have h_img: "h ` (carrier R) = carrier S" + using assms(1) unfolding ring_iso_def bij_betw_def by auto + have h_inj: "inj_on h (carrier R)" + using assms(1) unfolding ring_iso_def bij_betw_def by auto + hence h_non_zero_iff: "h x \ \\<^bsub>S\<^esub>" + if "x \ \\<^bsub>R\<^esub>" "x \ carrier R" for x + using h.hom_zero dr.zero_closed inj_onD that by metis + + have norm_elim: "ds.normalize (map h x) = map h x" + if "x \ carrier (poly_ring R)" for x + proof (cases "x") + case Nil then show ?thesis by simp + next + case (Cons xh xt) + have "xh \ carrier R" "xh \ \\<^bsub>R\<^esub>" + using that unfolding Cons univ_poly_carrier[symmetric] + unfolding polynomial_def by auto + hence "h xh \ \\<^bsub>S\<^esub>" using h_non_zero_iff by simp + then show ?thesis unfolding Cons by simp + qed + + show t_1: "map h x \ carrier ?S" + if "x \ carrier ?R" for x + using that hd_in_set h_non_zero_iff hd_map + unfolding univ_poly_carrier[symmetric] polynomial_def + by (cases x, auto) + + show "map h (x \\<^bsub>?R\<^esub> y) = map h x \\<^bsub>?S\<^esub> map h y" + if "x \ carrier ?R" "y \ carrier ?R" for x y + proof - + have "map h (x \\<^bsub>?R\<^esub> y) = ds.normalize (map h (x \\<^bsub>?R\<^esub> y))" + using that by (intro norm_elim[symmetric],simp) + also have "... = map h x \\<^bsub>?S\<^esub> map h y" + using that unfolding univ_poly_mult univ_poly_carrier[symmetric] + unfolding polynomial_def + by (intro h.poly_mult_hom'[of x y] , auto) + finally show ?thesis by simp + qed + + show "map h (x \\<^bsub>?R\<^esub> y) = map h x \\<^bsub>?S\<^esub> map h y" + if "x \ carrier ?R" "y \ carrier ?R" for x y + proof - + have "map h (x \\<^bsub>?R\<^esub> y) = ds.normalize (map h (x \\<^bsub>?R\<^esub> y))" + using that by (intro norm_elim[symmetric],simp) + also have "... = map h x \\<^bsub>?S\<^esub> map h y" + using that + unfolding univ_poly_add univ_poly_carrier[symmetric] + unfolding polynomial_def + by (intro h.poly_add_hom'[of x y], auto) + finally show ?thesis by simp + qed + + show "map h \\<^bsub>?R\<^esub> = \\<^bsub>?S\<^esub>" + unfolding univ_poly_one by simp + + let ?hinv = "map (the_inv_into (carrier R) h)" + + have "map h \ carrier ?R \ carrier ?S" + using t_1 by simp + moreover have "?hinv x \ carrier ?R" + if "x \ carrier ?S" for x + proof (cases "x = []") + case True + then show ?thesis + by (simp add:univ_poly_carrier[symmetric] polynomial_def) + next + case False + have set_x: "set x \ h ` carrier R" + using that h_img unfolding univ_poly_carrier[symmetric] + unfolding polynomial_def by auto + have "lead_coeff x \ \\<^bsub>S\<^esub>" "lead_coeff x \ carrier S" + using that False unfolding univ_poly_carrier[symmetric] + unfolding polynomial_def by auto + hence "the_inv_into (carrier R) h (lead_coeff x) \ + the_inv_into (carrier R) h \\<^bsub>S\<^esub>" + using inj_on_the_inv_into[OF h_inj] inj_onD + using ds.zero_closed h_img by metis + hence "the_inv_into (carrier R) h (lead_coeff x) \ \\<^bsub>R\<^esub>" + unfolding h.hom_zero[symmetric] + unfolding the_inv_into_f_f[OF h_inj dr.zero_closed] by simp + hence "lead_coeff (?hinv x) \ \\<^bsub>R\<^esub>" + using False by (simp add:hd_map) + moreover have "the_inv_into (carrier R) h ` set x \ carrier R" + using the_inv_into_into[OF h_inj] set_x + by (intro image_subsetI) auto + hence "set (?hinv x) \ carrier R" by simp + ultimately show ?thesis + by (simp add:univ_poly_carrier[symmetric] polynomial_def) + qed + moreover have "?hinv (map h x) = x" if "x \ carrier ?R" for x + proof - + have set_x: "set x \ carrier R" + using that unfolding univ_poly_carrier[symmetric] + unfolding polynomial_def by auto + have "?hinv (map h x) = + map (\y. the_inv_into (carrier R) h (h y)) x" + by simp + also have "... = map id x" + using set_x by (intro map_cong) + (auto simp add:the_inv_into_f_f[OF h_inj]) + also have "... = x" by simp + finally show ?thesis by simp + qed + moreover have "map h (?hinv x) = x" + if "x \ carrier ?S" for x + proof - + have set_x: "set x \ h ` carrier R" + using that h_img unfolding univ_poly_carrier[symmetric] + unfolding polynomial_def by auto + have "map h (?hinv x) = + map (\y. h (the_inv_into (carrier R) h y)) x" + by simp + also have "... = map id x" + using set_x by (intro map_cong) + (auto simp add:f_the_inv_into_f[OF h_inj]) + also have "... = x" by simp + finally show ?thesis by simp + qed + ultimately show "bij_betw (map h) (carrier ?R) (carrier ?S)" + by (intro bij_betwI[where g="?hinv"], auto) +qed + +lemma carrier_hom: + assumes "f \ carrier (poly_ring R)" + assumes "h \ ring_iso R S" "domain R" "domain S" + shows "map h f \ carrier (poly_ring S)" +proof - + note poly_iso = lift_iso_to_poly_ring[OF assms(2,3,4)] + show ?thesis + using ring_iso_memE(1)[OF poly_iso assms(1)] by simp +qed + +lemma carrier_hom': + assumes "f \ carrier (poly_ring R)" + assumes "h \ ring_hom R S" + assumes "domain R" "domain S" + assumes "inj_on h (carrier R)" + shows "map h f \ carrier (poly_ring S)" +proof - + let ?S = "S \ carrier := h ` carrier R \" + + interpret dr: domain "R" using assms(3) by blast + interpret ds: domain "S" using assms(4) by blast + interpret h1: ring_hom_ring R S h + using assms(2) ring_hom_ringI2 dr.ring_axioms + using ds.ring_axioms by blast + have subr: "subring (h ` carrier R) S" + using h1.img_is_subring[OF dr.carrier_is_subring] by blast + interpret h: ring_hom_ring "((h ` carrier R)[X]\<^bsub>S\<^esub>)" "poly_ring S" "id" + using ds.embed_hom[OF subr] by simp + + let ?S = "S \ carrier := h ` carrier R \" + have "h \ ring_hom R ?S" + using assms(2) unfolding ring_hom_def by simp + moreover have "bij_betw h (carrier R) (carrier ?S)" + using assms(5) bij_betw_def by auto + ultimately have h_iso: "h \ ring_iso R ?S" + unfolding ring_iso_def by simp + + have dom_S: "domain ?S" + using ds.subring_is_domain[OF subr] by simp + + note poly_iso = lift_iso_to_poly_ring[OF h_iso assms(3) dom_S] + have "map h f \ carrier (poly_ring ?S)" + using ring_iso_memE(1)[OF poly_iso assms(1)] by simp + also have "carrier (poly_ring ?S) = + carrier (univ_poly S (h ` carrier R))" + using ds.univ_poly_consistent[OF subr] by simp + also have "... \ carrier (poly_ring S)" + using h.hom_closed by auto + finally show ?thesis by simp +qed + +text \The following lemmas transfer properties like divisibility, irreducibility etc. between +ring isomorphisms.\ + +lemma divides_hom: + assumes "h \ ring_iso R S" + assumes "domain R" "domain S" + assumes "x \ carrier R" "y \ carrier R" + shows "x divides\<^bsub>R\<^esub> y \ (h x) divides\<^bsub>S\<^esub> (h y)" (is "?lhs \ ?rhs") +proof - + interpret dr: domain "R" using assms(2) by blast + interpret ds: domain "S" using assms(3) by blast + interpret pdr: domain "poly_ring R" + using dr.univ_poly_is_domain[OF dr.carrier_is_subring] by simp + interpret pds: domain "poly_ring S" + using ds.univ_poly_is_domain[OF ds.carrier_is_subring] by simp + interpret h: ring_hom_ring "R" "S" h + using dr.is_ring ds.is_ring assms(1) + by (intro ring_hom_ringI2, simp_all add:ring_iso_def) + + have h_inj_on: "inj_on h (carrier R)" + using assms(1) unfolding ring_iso_def bij_betw_def by auto + have h_img: "h ` (carrier R) = carrier S" + using assms(1) unfolding ring_iso_def bij_betw_def by auto + + have "?lhs \ (\c \ carrier R. y = x \\<^bsub>R\<^esub> c)" + unfolding factor_def by simp + also have "... \ (\c \ carrier R. h y = h x \\<^bsub>S\<^esub> h c)" + using assms(4,5) inj_onD[OF h_inj_on] + by (intro bex_cong, auto simp flip:h.hom_mult) + also have "... \ (\c \ carrier S. h y = h x \\<^bsub>S\<^esub> c)" + unfolding h_img[symmetric] by simp + also have "... \ ?rhs" + unfolding factor_def by simp + finally show ?thesis by simp +qed + +lemma properfactor_hom: + assumes "h \ ring_iso R S" + assumes "domain R" "domain S" + assumes "x \ carrier R" "b \ carrier R" + shows "properfactor R b x \ properfactor S (h b) (h x)" + using divides_hom[OF assms(1,2,3)] assms(4,5) + unfolding properfactor_def by simp + +lemma Units_hom: + assumes "h \ ring_iso R S" + assumes "domain R" "domain S" + assumes "x \ carrier R" + shows "x \ Units R \ h x \ Units S" +proof - + + interpret dr: domain "R" using assms(2) by blast + interpret ds: domain "S" using assms(3) by blast + interpret pdr: domain "poly_ring R" + using dr.univ_poly_is_domain[OF dr.carrier_is_subring] by simp + interpret pds: domain "poly_ring S" + using ds.univ_poly_is_domain[OF ds.carrier_is_subring] by simp + interpret h: ring_hom_ring "R" "S" h + using dr.is_ring ds.is_ring assms(1) + by (intro ring_hom_ringI2, simp_all add:ring_iso_def) + + have h_img: "h ` (carrier R) = carrier S" + using assms(1) unfolding ring_iso_def bij_betw_def by auto + + have h_inj_on: "inj_on h (carrier R)" + using assms(1) unfolding ring_iso_def bij_betw_def by auto + + hence h_one_iff: "h x = \\<^bsub>S\<^esub> \ x = \\<^bsub>R\<^esub>" if "x \ carrier R" for x + using h.hom_one that by (metis dr.one_closed inj_onD) + + have "x \ Units R \ + (\y\carrier R. x \\<^bsub>R\<^esub> y = \\<^bsub>R\<^esub> \ y \\<^bsub>R\<^esub> x = \\<^bsub>R\<^esub>)" + using assms unfolding Units_def by auto + also have "... \ + (\y\carrier R. h x \\<^bsub>S\<^esub> h y = h \\<^bsub>R\<^esub> \ h y \\<^bsub>S\<^esub> h x = h \\<^bsub>R\<^esub>)" + using h_one_iff assms by (intro bex_cong, simp_all flip:h.hom_mult) + also have "... \ + (\y\carrier S. h x \\<^bsub>S\<^esub> y = h \\<^bsub>R\<^esub> \ y \\<^bsub>S\<^esub> h x = \\<^bsub>S\<^esub>)" + unfolding h_img[symmetric] by simp + also have "... \ h x \ Units S" + using assms h.hom_closed unfolding Units_def by auto + finally show ?thesis by simp +qed + +lemma irreducible_hom: + assumes "h \ ring_iso R S" + assumes "domain R" "domain S" + assumes "x \ carrier R" + shows "irreducible R x = irreducible S (h x)" +proof - + have h_img: "h ` (carrier R) = carrier S" + using assms(1) unfolding ring_iso_def bij_betw_def by auto + + have "irreducible R x \ (x \ Units R \ + (\b\carrier R. properfactor R b x \ b \ Units R))" + unfolding Divisibility.irreducible_def by simp + also have "... \ (x \ Units R \ + (\b\carrier R. properfactor S (h b) (h x) \ b \ Units R))" + using properfactor_hom[OF assms(1,2,3)] assms(4) by simp + also have "... \ (h x \ Units S \ + (\b\carrier R. properfactor S (h b) (h x) \ h b \ Units S))" + using assms(4) Units_hom[OF assms(1,2,3)] by simp + also have "...\ (h x \ Units S \ + (\b\h ` carrier R. properfactor S b (h x) \ b \ Units S))" + by simp + also have "... \ irreducible S (h x)" + unfolding h_img Divisibility.irreducible_def by simp + finally show ?thesis by simp +qed + +lemma pirreducible_hom: + assumes "h \ ring_iso R S" + assumes "domain R" "domain S" + assumes "f \ carrier (poly_ring R)" + shows "pirreducible\<^bsub>R\<^esub> (carrier R) f = + pirreducible\<^bsub>S\<^esub> (carrier S) (map h f)" + (is "?lhs = ?rhs") +proof - + note lift_iso = lift_iso_to_poly_ring[OF assms(1,2,3)] + interpret dr: domain "R" using assms(2) by blast + interpret ds: domain "S" using assms(3) by blast + interpret pdr: domain "poly_ring R" + using dr.univ_poly_is_domain[OF dr.carrier_is_subring] by simp + interpret pds: domain "poly_ring S" + using ds.univ_poly_is_domain[OF ds.carrier_is_subring] by simp + + have mh_inj_on: "inj_on (map h) (carrier (poly_ring R))" + using lift_iso unfolding ring_iso_def bij_betw_def by auto + moreover have "map h \\<^bsub>poly_ring R\<^esub> = \\<^bsub>poly_ring S\<^esub>" + by (simp add:univ_poly_zero) + ultimately have mh_zero_iff: + "map h f = \\<^bsub>poly_ring S\<^esub> \ f = \\<^bsub>poly_ring R\<^esub>" + using assms(4) by (metis pdr.zero_closed inj_onD) + + have "?lhs \ (f \ \\<^bsub>poly_ring R\<^esub> \ irreducible (poly_ring R) f)" + unfolding ring_irreducible_def by simp + also have "... \ + (f \ \\<^bsub>poly_ring R\<^esub> \ irreducible (poly_ring S) (map h f))" + using irreducible_hom[OF lift_iso] pdr.domain_axioms + using assms(4) pds.domain_axioms by simp + also have "... \ + (map h f \ \\<^bsub>poly_ring S\<^esub> \ irreducible (poly_ring S) (map h f))" + using mh_zero_iff by simp + also have "... \ ?rhs" + unfolding ring_irreducible_def by simp + finally show ?thesis by simp +qed + + +lemma ring_hom_cong: + assumes "\x. x \ carrier R \ f' x = f x" + assumes "ring R" + assumes "f \ ring_hom R S" + shows "f' \ ring_hom R S" +proof - + interpret ring "R" using assms(2) by simp + show ?thesis + using assms(1) ring_hom_memE[OF assms(3)] + by (intro ring_hom_memI, auto) +qed + +text \The natural homomorphism between factor rings, where one ideal is a subset of the other.\ + +lemma (in ring) quot_quot_hom: + assumes "ideal I R" + assumes "ideal J R" + assumes "I \ J" + shows "(\x. (J <+>\<^bsub>R\<^esub> x)) \ ring_hom (R Quot I) (R Quot J)" +proof (rule ring_hom_memI) + interpret ji: ideal J R + using assms(2) by simp + interpret ii: ideal I R + using assms(1) by simp + + have a:"J <+>\<^bsub>R\<^esub> I = J" + using assms(3) unfolding set_add_def set_mult_def by auto + + show "J <+>\<^bsub>R\<^esub> x \ carrier (R Quot J)" + if "x \ carrier (R Quot I)" for x + proof - + have " \y\carrier R. x = I +> y" + using that unfolding FactRing_def A_RCOSETS_def' by simp + then obtain y where y_def: "y \ carrier R" "x = I +> y" + by auto + have "J <+>\<^bsub>R\<^esub> (I +> y) = (J <+>\<^bsub>R\<^esub> I) +> y" + using y_def(1) by (subst a_setmult_rcos_assoc) auto + also have "... = J +> y" using a by simp + finally have "J <+>\<^bsub>R\<^esub> (I +> y) = J +> y" by simp + thus ?thesis + using y_def unfolding FactRing_def A_RCOSETS_def' by auto + qed + + show "J <+>\<^bsub>R\<^esub> x \\<^bsub>R Quot I\<^esub> y = + (J <+>\<^bsub>R\<^esub> x) \\<^bsub>R Quot J\<^esub> (J <+>\<^bsub>R\<^esub> y)" + if "x \ carrier (R Quot I)" "y \ carrier (R Quot I)" + for x y + proof - + have "\x1\carrier R. x = I +> x1" "\y1\carrier R. y = I +> y1" + using that unfolding FactRing_def A_RCOSETS_def' by auto + then obtain x1 y1 + where x1_def: "x1 \ carrier R" "x = I +> x1" + and y1_def: "y1 \ carrier R" "y = I +> y1" + by auto + have "J <+>\<^bsub>R\<^esub> x \\<^bsub>R Quot I\<^esub> y = J <+>\<^bsub>R\<^esub> (I +> x1 \ y1)" + using x1_def y1_def + by (simp add: FactRing_def ii.rcoset_mult_add) + also have "... = (J <+>\<^bsub>R\<^esub> I) +> x1 \ y1" + using x1_def(1) y1_def(1) + by (subst a_setmult_rcos_assoc) auto + also have "... = J +> x1 \ y1" + using a by simp + also have "... = [mod J:] (J +> x1) \ (J +> y1)" + using x1_def(1) y1_def(1) by (subst ji.rcoset_mult_add, auto) + also have "... = + [mod J:] ((J <+>\<^bsub>R\<^esub> I) +> x1) \ ((J <+>\<^bsub>R\<^esub> I) +> y1)" + using a by simp + also have "... = + [mod J:] (J <+>\<^bsub>R\<^esub> (I +> x1)) \ (J <+>\<^bsub>R\<^esub> (I +> y1))" + using x1_def(1) y1_def(1) + by (subst (1 2) a_setmult_rcos_assoc) auto + also have "... = (J <+>\<^bsub>R\<^esub> x) \\<^bsub>R Quot J\<^esub> (J <+>\<^bsub>R\<^esub> y)" + using x1_def y1_def by (simp add: FactRing_def) + finally show ?thesis by simp + qed + + show "J <+>\<^bsub>R\<^esub> x \\<^bsub>R Quot I\<^esub> y = + (J <+>\<^bsub>R\<^esub> x) \\<^bsub>R Quot J\<^esub> (J <+>\<^bsub>R\<^esub> y)" + if "x \ carrier (R Quot I)" "y \ carrier (R Quot I)" + for x y + proof - + have "\x1\carrier R. x = I +> x1" "\y1\carrier R. y = I +> y1" + using that unfolding FactRing_def A_RCOSETS_def' by auto + then obtain x1 y1 + where x1_def: "x1 \ carrier R" "x = I +> x1" + and y1_def: "y1 \ carrier R" "y = I +> y1" + by auto + have "J <+>\<^bsub>R\<^esub> x \\<^bsub>R Quot I\<^esub> y = + J <+>\<^bsub>R\<^esub> ((I +> x1) <+>\<^bsub>R\<^esub> (I +> y1))" + using x1_def y1_def by (simp add:FactRing_def) + also have "... = J <+>\<^bsub>R\<^esub> (I +> (x1 \ y1))" + using x1_def y1_def ii.a_rcos_sum by simp + also have "... = (J <+>\<^bsub>R\<^esub> I) +> (x1 \ y1)" + using x1_def y1_def by (subst a_setmult_rcos_assoc) auto + also have "... = J +> (x1 \ y1)" + using a by simp + also have "... = + ((J <+>\<^bsub>R\<^esub> I) +> x1) <+>\<^bsub>R\<^esub> ((J <+>\<^bsub>R\<^esub> I) +> y1)" + using x1_def y1_def ji.a_rcos_sum a by simp + also have "... = + J <+>\<^bsub>R\<^esub> (I +> x1) <+>\<^bsub>R\<^esub> (J <+>\<^bsub>R\<^esub> (I +> y1))" + using x1_def y1_def by (subst (1 2) a_setmult_rcos_assoc) auto + also have "... = (J <+>\<^bsub>R\<^esub> x) \\<^bsub>R Quot J\<^esub> (J <+>\<^bsub>R\<^esub> y)" + using x1_def y1_def by (simp add:FactRing_def) + finally show ?thesis by simp + qed + + have "J <+>\<^bsub>R\<^esub> \\<^bsub>R Quot I\<^esub> = J <+>\<^bsub>R\<^esub> (I +> \)" + unfolding FactRing_def by simp + also have "... = (J <+>\<^bsub>R\<^esub> I) +> \" + by (subst a_setmult_rcos_assoc) auto + also have "... = J +> \" using a by simp + also have "... = \\<^bsub>R Quot J\<^esub>" + unfolding FactRing_def by simp + finally show "J <+>\<^bsub>R\<^esub> \\<^bsub>R Quot I\<^esub> = \\<^bsub>R Quot J\<^esub>" + by simp +qed + +lemma (in ring) quot_carr: + assumes "ideal I R" + assumes "y \ carrier (R Quot I)" + shows "y \ carrier R" +proof - + interpret ideal I R using assms(1) by simp + have "y \ a_rcosets I" + using assms(2) unfolding FactRing_def by simp + then obtain v where y_def: "y = I +> v" "v \ carrier R" + unfolding A_RCOSETS_def' by auto + have "I +> v \ carrier R" + using y_def(2) a_r_coset_subset_G a_subset by presburger + thus "y \ carrier R" unfolding y_def by simp +qed + +lemma (in ring) set_add_zero: + assumes "A \ carrier R" + shows "{\} <+>\<^bsub>R\<^esub> A = A" +proof - + have "{\} <+>\<^bsub>R\<^esub> A = (\x\A. {\ \ x})" + using assms unfolding set_add_def set_mult_def by simp + also have "... = (\x\A. {x})" + using assms by (intro arg_cong[where f="Union"] image_cong, auto) + also have "... = A" by simp + finally show ?thesis by simp +qed + +text \Adapted from the proof of @{thm [source] domain.polynomial_rupture}\ + +lemma (in domain) rupture_surj_as_eval: + assumes "subring K R" + assumes "p \ carrier (K[X])" "q \ carrier (K[X])" + shows "rupture_surj K p q = + ring.eval (Rupt K p) (map ((rupture_surj K p) \ poly_of_const) q) + (rupture_surj K p X)" +proof - + let ?surj = "rupture_surj K p" + + interpret UP: domain "K[X]" + using univ_poly_is_domain[OF assms(1)] . + interpret h: ring_hom_ring "K[X]" "Rupt K p" ?surj + using rupture_surj_hom(2)[OF assms(1,2)] . + + have "(h.S.eval) (map (?surj \ poly_of_const) q) (?surj X) = + ?surj ((UP.eval) (map poly_of_const q) X)" + using h.eval_hom[OF UP.carrier_is_subring var_closed(1)[OF assms(1)] + map_norm_in_poly_ring_carrier[OF assms(1,3)]] by simp + also have " ... = ?surj q" + unfolding sym[OF eval_rewrite[OF assms(1,3)]] .. + finally show ?thesis by simp +qed + +subsection \Divisibility\ + +lemma (in field) f_comm_group_1: + assumes "x \ carrier R" "y \ carrier R" + assumes "x \ \" "y \ \" + assumes "x \ y = \" + shows "False" + using integral assms by auto + +lemma (in field) f_comm_group_2: + assumes "x \ carrier R" + assumes "x \ \" + shows " \y\carrier R - {\}. y \ x = \" +proof - + have x_unit: "x \ Units R" using field_Units assms by simp + thus ?thesis unfolding Units_def by auto +qed + +sublocale field < mult_of: comm_group "mult_of R" + rewrites "mult (mult_of R) = mult R" + and "one (mult_of R) = one R" + using f_comm_group_1 f_comm_group_2 + by (auto intro!:comm_groupI m_assoc m_comm) + +lemma (in domain) div_neg: + assumes "a \ carrier R" "b \ carrier R" + assumes "a divides b" + shows "a divides (\ b)" +proof - + obtain r1 where r1_def: "r1 \ carrier R" "a \ r1 = b" + using assms by (auto simp:factor_def) + + have "a \ (\ r1) = \ (a \ r1)" + using assms(1) r1_def(1) by algebra + also have "... = \ b" + using r1_def(2) by simp + finally have "\b = a \ (\ r1)" by simp + moreover have "\r1 \ carrier R" + using r1_def(1) by simp + ultimately show ?thesis + by (auto simp:factor_def) +qed + +lemma (in domain) div_sum: + assumes "a \ carrier R" "b \ carrier R" "c \ carrier R" + assumes "a divides b" + assumes "a divides c" + shows "a divides (b \ c)" +proof - + obtain r1 where r1_def: "r1 \ carrier R" "a \ r1 = b" + using assms by (auto simp:factor_def) + + obtain r2 where r2_def: "r2 \ carrier R" "a \ r2 = c" + using assms by (auto simp:factor_def) + + have "a \ (r1 \ r2) = (a \ r1) \ (a \ r2)" + using assms(1) r1_def(1) r2_def(1) by algebra + also have "... = b \ c" + using r1_def(2) r2_def(2) by simp + finally have "b \ c = a \ (r1 \ r2)" by simp + moreover have "r1 \ r2 \ carrier R" + using r1_def(1) r2_def(1) by simp + ultimately show ?thesis + by (auto simp:factor_def) +qed + +lemma (in domain) div_sum_iff: + assumes "a \ carrier R" "b \ carrier R" "c \ carrier R" + assumes "a divides b" + shows "a divides (b \ c) \ a divides c" +proof + assume "a divides (b \ c)" + moreover have "a divides (\ b)" + using div_neg assms(1,2,4) by simp + ultimately have "a divides ((b \ c) \ (\ b))" + using div_sum assms by simp + also have "... = c" using assms(1,2,3) by algebra + finally show "a divides c" by simp +next + assume "a divides c" + thus "a divides (b \ c)" + using assms by (intro div_sum) auto +qed + +end diff --git a/thys/Finite_Fields/Formal_Polynomial_Derivatives.thy b/thys/Finite_Fields/Formal_Polynomial_Derivatives.thy new file mode 100644 --- /dev/null +++ b/thys/Finite_Fields/Formal_Polynomial_Derivatives.thy @@ -0,0 +1,414 @@ +section \Formal Derivatives\label{sec:pderiv}\ + +theory Formal_Polynomial_Derivatives + imports "HOL-Algebra.Polynomial_Divisibility" "Ring_Characteristic" +begin + +definition pderiv ("pderiv\") where + "pderiv\<^bsub>R\<^esub> x = ring.normalize R ( + map (\i. int_embed R i \\<^bsub>R\<^esub> ring.coeff R x i) (rev [1.. carrier (K[X])" + shows "coeff f i \ K" +proof - + have "coeff f i \ set f \ {\}" + using coeff_img(3) by auto + also have "... \ K \ {\}" + using assms(2) univ_poly_carrier polynomial_incl by blast + also have "... \ K" + using subringE[OF assms(1)] by simp + finally show ?thesis by simp +qed + +lemma pderiv_carr: + assumes "subring K R" + assumes "f \ carrier (K[X])" + shows "pderiv f \ carrier (K[X])" +proof - + have "int_embed R i \ coeff f i \ K" for i + using coeff_range[OF assms] int_embed_range[OF assms(1)] + using subringE[OF assms(1)] by simp + hence "polynomial K (pderiv f)" + unfolding pderiv_def by (intro normalize_gives_polynomial, auto) + thus ?thesis + using univ_poly_carrier by auto +qed + +lemma pderiv_coeff: + assumes "subring K R" + assumes "f \ carrier (K[X])" + shows "coeff (pderiv f) k = int_embed R (Suc k) \ coeff f (Suc k)" + (is "?lhs = ?rhs") +proof (cases "k + 1 < length f") + case True + define j where "j = length f - k - 2" + define d where + "d = map (\i. int_embed R i \ coeff f i) (rev [1.. coeff f (length f - j - 1)" + using b e unfolding d_def by simp + also have "... = ?rhs" + using f by simp + finally show ?thesis by simp +next + case False + hence "Suc k \ length f" + by simp + hence a:"coeff f (Suc k) = \" + using coeff_img by blast + have b:"coeff (pderiv f) k = \" + unfolding pderiv_def normalize_coeff[symmetric] using False + by (intro coeff_length, simp) + show ?thesis + using int_embed_range[OF carrier_is_subring] by (simp add:a b) +qed + +lemma pderiv_const: + assumes "degree x = 0" + shows "pderiv x = \\<^bsub>K[X]\<^esub>" +proof (cases "length x = 0") + case True + then show ?thesis by (simp add:univ_poly_zero pderiv_def) +next + case False + hence "length x = 1" using assms by linarith + then obtain y where "x = [y]" by (cases x, auto) + then show ?thesis by (simp add:univ_poly_zero pderiv_def) +qed + +lemma pderiv_var: + shows "pderiv X = \\<^bsub>K[X]\<^esub>" + unfolding var_def pderiv_def + by (simp add:univ_poly_one int_embed_def) + +lemma pderiv_zero: + shows "pderiv \\<^bsub>K[X]\<^esub> = \\<^bsub>K[X]\<^esub>" + unfolding pderiv_def univ_poly_zero by simp + +lemma pderiv_add: + assumes "subring K R" + assumes [simp]: "f \ carrier (K[X])" "g \ carrier (K[X])" + shows "pderiv (f \\<^bsub>K[X]\<^esub> g) = pderiv f \\<^bsub>K[X]\<^esub> pderiv g" + (is "?lhs = ?rhs") +proof - + interpret p: ring "(K[X])" + using univ_poly_is_ring[OF assms(1)] by simp + + let ?n = "(\i. int_embed R i)" + + have a[simp]:"?n k \ carrier R" for k + using int_embed_range[OF carrier_is_subring] by auto + have b[simp]:"coeff f k \ carrier R" if "f \ carrier (K[X])" for k f + using coeff_range[OF assms(1)] that + using subringE(1)[OF assms(1)] by auto + + have "coeff ?lhs i = coeff ?rhs i" for i + proof - + have "coeff ?lhs i = ?n (i+1) \ coeff (f \\<^bsub>K [X]\<^esub> g) (i+1)" + by (simp add: pderiv_coeff[OF assms(1)]) + also have "... = ?n (i+1) \ (coeff f (i+1) \ coeff g (i+1))" + by (subst coeff_add[OF assms], simp) + also have "... = ?n (i+1) \ coeff f (i+1) + \ int_embed R (i+1) \ coeff g (i+1)" + by (subst r_distr, simp_all) + also have "... = coeff (pderiv f) i \ coeff (pderiv g) i" + by (simp add: pderiv_coeff[OF assms(1)]) + also have "... = coeff (pderiv f \\<^bsub>K [X]\<^esub> pderiv g) i" + using pderiv_carr[OF assms(1)] + by (subst coeff_add[OF assms(1)], auto) + finally show ?thesis by simp + qed + hence "coeff ?lhs = coeff ?rhs" by auto + thus "?lhs = ?rhs" + using pderiv_carr[OF assms(1)] + by (subst coeff_iff_polynomial_cond[where K="K"]) + (simp_all add:univ_poly_carrier)+ +qed + +lemma pderiv_inv: + assumes "subring K R" + assumes [simp]: "f \ carrier (K[X])" + shows "pderiv (\\<^bsub>K[X]\<^esub> f) = \\<^bsub>K[X]\<^esub> pderiv f" (is "?lhs = ?rhs") +proof - + interpret p: cring "(K[X])" + using univ_poly_is_cring[OF assms(1)] by simp + + have "pderiv (\\<^bsub>K[X]\<^esub> f) = pderiv (\\<^bsub>K[X]\<^esub> f) \\<^bsub>K[X]\<^esub> \\<^bsub>K[X]\<^esub>" + using pderiv_carr[OF assms(1)] + by (subst p.r_zero, simp_all) + also have "... = pderiv (\\<^bsub>K[X]\<^esub> f) \\<^bsub>K[X]\<^esub> (pderiv f \\<^bsub>K[X]\<^esub> pderiv f)" + using pderiv_carr[OF assms(1)] by simp + also have "... = pderiv (\\<^bsub>K[X]\<^esub> f) \\<^bsub>K[X]\<^esub> pderiv f \\<^bsub>K[X]\<^esub> pderiv f" + using pderiv_carr[OF assms(1)] + unfolding a_minus_def by (simp add:p.a_assoc) + also have "... = pderiv (\\<^bsub>K[X]\<^esub> f \\<^bsub>K[X]\<^esub> f) \\<^bsub>K[X]\<^esub> pderiv f" + by (subst pderiv_add[OF assms(1)], simp_all) + also have "... = pderiv \\<^bsub>K[X]\<^esub> \\<^bsub>K[X]\<^esub> pderiv f" + by (subst p.l_neg, simp_all) + also have "... = \\<^bsub>K[X]\<^esub> \\<^bsub>K[X]\<^esub> pderiv f" + by (subst pderiv_zero, simp) + also have "... = \\<^bsub>K[X]\<^esub> pderiv f" + unfolding a_minus_def using pderiv_carr[OF assms(1)] + by (subst p.l_zero, simp_all) + finally show "pderiv (\\<^bsub>K[X]\<^esub> f) = \\<^bsub>K[X]\<^esub> pderiv f" + by simp +qed + + +lemma coeff_mult: + assumes "subring K R" + assumes "f \ carrier (K[X])" "g \ carrier (K[X])" + shows "coeff (f \\<^bsub>K[X]\<^esub> g) i = + (\ k \ {..i}. (coeff f) k \ (coeff g) (i - k))" +proof - + have a:"set f \ carrier R" + using assms(1,2) univ_poly_carrier + using subringE(1)[OF assms(1)] polynomial_incl by blast + have b:"set g \ carrier R" + using assms(1,3) univ_poly_carrier + using subringE(1)[OF assms(1)] polynomial_incl by blast + show ?thesis + unfolding univ_poly_mult poly_mult_coeff[OF a b] by simp +qed + +lemma pderiv_mult: + assumes "subring K R" + assumes [simp]: "f \ carrier (K[X])" "g \ carrier (K[X])" + shows "pderiv (f \\<^bsub>K[X]\<^esub> g) = + pderiv f \\<^bsub>K[X]\<^esub> g \\<^bsub>K[X]\<^esub> f \\<^bsub>K[X]\<^esub> pderiv g" + (is "?lhs = ?rhs") +proof - + interpret p: cring "(K[X])" + using univ_poly_is_cring[OF assms(1)] by simp + + let ?n = "(\i. int_embed R i)" + + have a[simp]:"?n k \ carrier R" for k + using int_embed_range[OF carrier_is_subring] by auto + have b[simp]:"coeff f k \ carrier R" if "f \ carrier (K[X])" for k f + using coeff_range[OF assms(1)] + using subringE(1)[OF assms(1)] that by auto + + have "coeff ?lhs i = coeff ?rhs i" for i + proof - + have "coeff ?lhs i = ?n (i+1) \ coeff (f \\<^bsub>K [X]\<^esub> g) (i+1)" + using assms(2,3) by (simp add: pderiv_coeff[OF assms(1)]) + also have "... = ?n (i+1) \ + (\k \ {..i+1}. coeff f k \ (coeff g (i + 1 - k)))" + by (subst coeff_mult[OF assms], simp) + also have "... = + (\k \ {..i+1}. ?n (i+1) \ (coeff f k \ coeff g (i + 1 - k)))" + by (intro finsum_rdistr, simp_all add:Pi_def) + also have "... = + (\k \ {..i+1}. ?n k \ (coeff f k \ coeff g (i + 1 - k)) \ + ?n (i+1-k) \ (coeff f k \ coeff g (i + 1 - k)))" + using int_embed_add[symmetric] of_nat_diff + by (intro finsum_cong') + (simp_all add:l_distr[symmetric] of_nat_diff) + also have "... = + (\k \ {..i+1}. ?n k \ coeff f k \ coeff g (i + 1 - k) \ + coeff f k \ (?n (i+1-k) \ coeff g (i + 1 - k)))" + using Pi_def a b m_assoc m_comm + by (intro finsum_cong' arg_cong2[where f="(\)"], simp_all) + also have "... = + (\k \ {..i+1}. ?n k \ coeff f k \ coeff g (i+1-k)) \ + (\k \ {..i+1}. coeff f k \ (?n (i+1-k) \ coeff g (i+1-k)))" + by (subst finsum_addf[symmetric], simp_all add:Pi_def) + also have "... = + (\k\insert 0 {1..i+1}. ?n k \ coeff f k \ coeff g (i+1-k)) \ + (\k\insert (i+1) {..i}. coeff f k \ (?n (i+1-k) \ coeff g (i+1-k)))" + using subringE(1)[OF assms(1)] + by (intro arg_cong2[where f="(\)"] finsum_cong') + (auto simp:set_eq_iff) + also have "... = + (\k \ {1..i+1}. ?n k \ coeff f k \ coeff g (i+1-k)) \ + (\k \ {..i}. coeff f k \ (?n (i+1-k) \ coeff g (i+1-k)))" + by (subst (1 2) finsum_insert, auto simp add:int_embed_zero) + also have "... = + (\k \ Suc ` {..i}. ?n k \ coeff f (k) \ coeff g (i+1-k)) \ + (\k \ {..i}. coeff f k \ (?n (i+1-k) \ coeff g (i+1-k)))" + by (intro arg_cong2[where f="(\)"] finsum_cong') + (simp_all add:Pi_def atMost_atLeast0) + also have "... = + (\k \ {..i}. ?n (k+1) \ coeff f (k+1) \ coeff g (i-k)) \ + (\k \ {..i}. coeff f k \ (?n (i+1-k) \ coeff g (i+1-k)))" + by (subst finsum_reindex, auto) + also have "... = + (\k \ {..i}. coeff (pderiv f) k \ coeff g (i-k)) \ + (\k \ {..i}. coeff f k \ coeff (pderiv g) (i-k))" + using Suc_diff_le + by (subst (1 2) pderiv_coeff[OF assms(1)]) + (auto intro!: finsum_cong') + also have "... = + coeff (pderiv f \\<^bsub>K[X]\<^esub> g) i \ coeff (f \\<^bsub>K[X]\<^esub> pderiv g) i" + using pderiv_carr[OF assms(1)] + by (subst (1 2) coeff_mult[OF assms(1)], auto) + also have "... = coeff ?rhs i" + using pderiv_carr[OF assms(1)] + by (subst coeff_add[OF assms(1)], auto) + finally show ?thesis by simp + qed + + hence "coeff ?lhs = coeff ?rhs" by auto + thus "?lhs = ?rhs" + using pderiv_carr[OF assms(1)] + by (subst coeff_iff_polynomial_cond[where K="K"]) + (simp_all add:univ_poly_carrier) +qed + +lemma pderiv_pow: + assumes "n > (0 :: nat)" + assumes "subring K R" + assumes [simp]: "f \ carrier (K[X])" + shows "pderiv (f [^]\<^bsub>K[X]\<^esub> n) = + int_embed (K[X]) n \\<^bsub>K[X]\<^esub> f [^]\<^bsub>K[X]\<^esub> (n-1) \\<^bsub>K[X]\<^esub> pderiv f" + (is "?lhs = ?rhs") +proof - + interpret p: cring "(K[X])" + using univ_poly_is_cring[OF assms(2)] by simp + + let ?n = "\n. int_embed (K[X]) n" + + have [simp]: "?n i \ carrier (K[X])" for i + using p.int_embed_range[OF p.carrier_is_subring] by simp + + obtain m where n_def: "n = Suc m" using assms(1) lessE by blast + have "pderiv (f [^]\<^bsub>K[X]\<^esub> (m+1)) = + ?n (m+1) \\<^bsub>K[X]\<^esub> f [^]\<^bsub>K[X]\<^esub> m \\<^bsub>K[X]\<^esub> pderiv f" + proof (induction m) + case 0 + then show ?case + using pderiv_carr[OF assms(2)] assms(3) + using p.int_embed_one by simp + next + case (Suc m) + have "pderiv (f [^]\<^bsub>K [X]\<^esub> (Suc m + 1)) = + pderiv (f [^]\<^bsub>K [X]\<^esub> (m+1) \\<^bsub>K[X]\<^esub> f) " + by simp + also have "... = + pderiv (f [^]\<^bsub>K [X]\<^esub> (m+1)) \\<^bsub>K[X]\<^esub> f \\<^bsub>K[X]\<^esub> + f [^]\<^bsub>K [X]\<^esub> (m+1) \\<^bsub>K[X]\<^esub> pderiv f" + using assms(3) by (subst pderiv_mult[OF assms(2)], auto) + also have "... = + (?n (m+1) \\<^bsub>K [X]\<^esub> f [^]\<^bsub>K [X]\<^esub> m \\<^bsub>K [X]\<^esub> pderiv f) \\<^bsub>K[X]\<^esub> f + \\<^bsub>K[X]\<^esub> f [^]\<^bsub>K [X]\<^esub> (m+1) \\<^bsub>K[X]\<^esub> pderiv f" + by (subst Suc(1), simp) + also have + "... = ?n (m+1) \\<^bsub>K[X]\<^esub> (f [^]\<^bsub>K [X]\<^esub> (m+1) \\<^bsub>K[X]\<^esub> pderiv f) + \\<^bsub>K[X]\<^esub> \\<^bsub>K [X]\<^esub> \\<^bsub>K[X]\<^esub> (f [^]\<^bsub>K [X]\<^esub> (m+1) \\<^bsub>K[X]\<^esub> pderiv f)" + using assms(3) pderiv_carr[OF assms(2)] + apply (intro arg_cong2[where f="(\\<^bsub>K[X]\<^esub>)"]) + apply (simp add:p.m_assoc) + apply (simp add:p.m_comm) + by simp + also have + "... = (?n (m+1) \\<^bsub>K[X]\<^esub> \\<^bsub>K [X]\<^esub>) \\<^bsub>K [X]\<^esub> + (f [^]\<^bsub>K [X]\<^esub> (m+1) \\<^bsub>K [X]\<^esub> pderiv f)" + using assms(3) pderiv_carr[OF assms(2)] + by (subst p.l_distr[symmetric], simp_all) + also have "... = + (\\<^bsub>K [X]\<^esub> \\<^bsub>K[X]\<^esub> ?n (m+1)) \\<^bsub>K [X]\<^esub> + (f [^]\<^bsub>K [X]\<^esub> (m+1) \\<^bsub>K [X]\<^esub> pderiv f)" + using assms(3) pderiv_carr[OF assms(2)] + by (subst p.a_comm, simp_all) + also have "... = ?n (1+ Suc m) + \\<^bsub>K [X]\<^esub> f [^]\<^bsub>K [X]\<^esub> (Suc m) \\<^bsub>K [X]\<^esub> pderiv f" + using assms(3) pderiv_carr[OF assms(2)] of_nat_add + apply (subst (2) of_nat_add, subst p.int_embed_add) + by (simp add:p.m_assoc p.int_embed_one) + finally show ?case by simp + qed + thus "?thesis" using n_def by auto +qed + +lemma pderiv_var_pow: + assumes "n > (0::nat)" + assumes "subring K R" + shows "pderiv (X [^]\<^bsub>K[X]\<^esub> n) = + int_embed (K[X]) n \\<^bsub>K[X]\<^esub> X [^]\<^bsub>K[X]\<^esub> (n-1)" +proof - + interpret p: cring "(K[X])" + using univ_poly_is_cring[OF assms(2)] by simp + + have [simp]: "int_embed (K[X]) i \ carrier (K[X])" for i + using p.int_embed_range[OF p.carrier_is_subring] by simp + + show ?thesis + using var_closed[OF assms(2)] + using pderiv_var[where K="K"] pderiv_carr[OF assms(2)] + by (subst pderiv_pow[OF assms(1,2)], simp_all) +qed + +lemma int_embed_consistent_with_poly_of_const: + assumes "subring K R" + shows "int_embed (K[X]) m = poly_of_const (int_embed R m)" +proof - + define K' where "K' = R \ carrier := K \" + interpret p: cring "(K[X])" + using univ_poly_is_cring[OF assms] by simp + interpret d: domain "K'" + unfolding K'_def + using assms(1) subdomainI' subdomain_is_domain by simp + interpret h: ring_hom_ring "K'" "K[X]" "poly_of_const" + unfolding K'_def + using canonical_embedding_ring_hom[OF assms(1)] by simp + + define n where "n=nat (abs m)" + + have a1: "int_embed (K[X]) (int n) = poly_of_const (int_embed K' n)" + proof (induction n) + case 0 + then show ?case by (simp add:d.int_embed_zero p.int_embed_zero) + next + case (Suc n) + then show ?case + using d.int_embed_closed d.int_embed_add d.int_embed_one + by (simp add:p.int_embed_add p.int_embed_one) + qed + also have "... = poly_of_const (int_embed R n)" + unfolding K'_def using int_embed_consistent[OF assms] by simp + finally have a: + "int_embed (K[X]) (int n) = poly_of_const (int_embed R (int n))" + by simp + + have "int_embed (K[X]) (-(int n)) = + poly_of_const (int_embed K' (- (int n)))" + using d.int_embed_closed a1 by (simp add: p.int_embed_inv d.int_embed_inv) + also have "... = poly_of_const (int_embed R (- (int n)))" + unfolding K'_def using int_embed_consistent[OF assms] by simp + finally have b: + "int_embed (K[X]) (-int n) = poly_of_const (int_embed R (-int n))" + by simp + + show ?thesis + using a b n_def by (cases "m \ 0", simp, simp) +qed + +end + +end diff --git a/thys/Finite_Fields/Monic_Polynomial_Factorization.thy b/thys/Finite_Fields/Monic_Polynomial_Factorization.thy new file mode 100644 --- /dev/null +++ b/thys/Finite_Fields/Monic_Polynomial_Factorization.thy @@ -0,0 +1,658 @@ +section \Factorization into Monic Polynomials\label{sec:monic}\ + +theory Monic_Polynomial_Factorization +imports + Finite_Fields_Factorization_Ext + Formal_Polynomial_Derivatives +begin + +hide_const Factorial_Ring.multiplicity +hide_const Factorial_Ring.irreducible + +lemma (in domain) finprod_mult_of: + assumes "finite A" + assumes "\x. x \ A \ f x \ carrier (mult_of R)" + shows "finprod R f A = finprod (mult_of R) f A" + using assms by (induction A rule:finite_induct, auto) + +lemma (in ring) finite_poly: + assumes "subring K R" + assumes "finite K" + shows + "finite {f. f \ carrier (K[X]) \ degree f = n}" (is "finite ?A") + "finite {f. f \ carrier (K[X]) \ degree f \ n}" (is "finite ?B") +proof - + have "finite {f. set f \ K \ length f \ n + 1}" (is "finite ?C") + using assms(2) finite_lists_length_le by auto + moreover have "?B \ ?C" + by (intro subsetI) + (auto simp:univ_poly_carrier[symmetric] polynomial_def) + ultimately show a: "finite ?B" + using finite_subset by auto + moreover have "?A \ ?B" + by (intro subsetI, simp) + ultimately show "finite ?A" + using finite_subset by auto +qed + +definition pmult :: "_ \ 'a list \ 'a list \ nat" ("pmult\") + where "pmult\<^bsub>R\<^esub> d p = multiplicity (mult_of (poly_ring R)) d p" + +definition monic_poly :: "_ \ 'a list \ bool" + where "monic_poly R f = + (f \ [] \ lead_coeff f = \\<^bsub>R\<^esub> \ f \ carrier (poly_ring R))" + +definition monic_irreducible_poly where + "monic_irreducible_poly R f = + (monic_poly R f \ pirreducible\<^bsub>R\<^esub> (carrier R) f)" + +abbreviation "m_i_p \ monic_irreducible_poly" + +locale polynomial_ring = field + + fixes K + assumes polynomial_ring_assms: "subfield K R" +begin + +lemma K_subring: "subring K R" + using polynomial_ring_assms subfieldE(1) by auto + +abbreviation P where "P \ K[X]" + +text \This locale is used to specialize the following lemmas for a fixed coefficient ring. +It can be introduced in a context as an intepretation to be able to use the following specialized +lemmas. Because it is not (and should not) introduced as a sublocale it has no lasting effect +for the field locale itself.\ + +lemmas + poly_mult_lead_coeff = poly_mult_lead_coeff[OF K_subring] +and degree_add_distinct = degree_add_distinct[OF K_subring] +and coeff_add = coeff_add[OF K_subring] +and var_closed = var_closed[OF K_subring] +and degree_prod = degree_prod[OF _ K_subring] +and degree_pow = degree_pow[OF K_subring] +and pirreducible_degree = pirreducible_degree[OF polynomial_ring_assms] +and degree_one_imp_pirreducible = + degree_one_imp_pirreducible[OF polynomial_ring_assms] +and var_pow_closed = var_pow_closed[OF K_subring] +and var_pow_carr = var_pow_carr[OF K_subring] +and univ_poly_a_inv_degree = univ_poly_a_inv_degree[OF K_subring] +and var_pow_degree = var_pow_degree[OF K_subring] +and pdivides_zero = pdivides_zero[OF K_subring] +and pdivides_imp_degree_le = pdivides_imp_degree_le[OF K_subring] +and var_carr = var_carr[OF K_subring] +and rupture_eq_0_iff = rupture_eq_0_iff[OF polynomial_ring_assms] +and rupture_is_field_iff_pirreducible = + rupture_is_field_iff_pirreducible[OF polynomial_ring_assms] +and rupture_surj_hom = rupture_surj_hom[OF K_subring] +and canonical_embedding_ring_hom = + canonical_embedding_ring_hom[OF K_subring] +and rupture_surj_norm_is_hom = rupture_surj_norm_is_hom[OF K_subring] +and rupture_surj_as_eval = rupture_surj_as_eval[OF K_subring] +and eval_cring_hom = eval_cring_hom[OF K_subring] +and coeff_range = coeff_range[OF K_subring] +and finite_poly = finite_poly[OF K_subring] +and int_embed_consistent_with_poly_of_const = + int_embed_consistent_with_poly_of_const[OF K_subring] +and pderiv_var_pow = pderiv_var_pow[OF _ K_subring] +and pderiv_add = pderiv_add[OF K_subring] +and pderiv_inv = pderiv_inv[OF K_subring] +and pderiv_mult = pderiv_mult[OF K_subring] +and pderiv_pow = pderiv_pow[OF _ K_subring] +and pderiv_carr = pderiv_carr[OF K_subring] + +sublocale p:principal_domain "poly_ring R" + by (simp add: carrier_is_subfield univ_poly_is_principal) + +end + +context field +begin + +interpretation polynomial_ring "R" "carrier R" + using carrier_is_subfield field_axioms + by (simp add:polynomial_ring_def polynomial_ring_axioms_def) + +lemma pdivides_mult_r: + assumes "a \ carrier (mult_of P)" + assumes "b \ carrier (mult_of P)" + assumes "c \ carrier (mult_of P)" + shows "a \\<^bsub>P\<^esub> c pdivides b \\<^bsub>P\<^esub> c \ a pdivides b" + (is "?lhs \ ?rhs") +proof - + have a:"b \\<^bsub>P\<^esub> c \ carrier P - {\\<^bsub>P\<^esub>}" + using assms p.mult_of.m_closed by force + have b:"a \\<^bsub>P\<^esub> c \ carrier P" + using assms by simp + have c:"b \ carrier P - {\\<^bsub>P\<^esub>}" + using assms p.mult_of.m_closed by force + have d:"a \ carrier P" using assms by simp + have "?lhs \ a \\<^bsub>P\<^esub> c divides\<^bsub>mult_of P\<^esub> b \\<^bsub>P\<^esub> c" + unfolding pdivides_def using p.divides_imp_divides_mult a b + by (meson divides_mult_imp_divides) + also have "... \ a divides\<^bsub>mult_of P\<^esub> b" + using p.mult_of.divides_mult_r[OF assms] by simp + also have "... \ ?rhs" + unfolding pdivides_def using p.divides_imp_divides_mult c d + by (meson divides_mult_imp_divides) + finally show ?thesis by simp +qed + +lemma lead_coeff_carr: + assumes "x \ carrier (mult_of P)" + shows "lead_coeff x \ carrier R - {\}" +proof (cases x) + case Nil + then show ?thesis using assms by (simp add:univ_poly_zero) +next + case (Cons a list) + hence a: "polynomial (carrier R) (a # list)" + using assms univ_poly_carrier by auto + have "lead_coeff x = a" + using Cons by simp + also have "a \ carrier R - {\}" + using lead_coeff_not_zero a by simp + finally show ?thesis by simp +qed + +lemma lead_coeff_poly_of_const: + assumes "r \ \" + shows "lead_coeff (poly_of_const r) = r" + using assms + by (simp add:poly_of_const_def) + +lemma lead_coeff_mult: + assumes "f \ carrier (mult_of P)" + assumes "g \ carrier (mult_of P)" + shows "lead_coeff (f \\<^bsub>P\<^esub> g) = lead_coeff f \ lead_coeff g" + unfolding univ_poly_mult using assms + using univ_poly_carrier[where R="R" and K="carrier R"] + by (subst poly_mult_lead_coeff) (simp_all add:univ_poly_zero) + +lemma monic_poly_carr: + assumes "monic_poly R f" + shows "f \ carrier P" + using assms unfolding monic_poly_def by simp + +lemma monic_poly_add_distinct: + assumes "monic_poly R f" + assumes "g \ carrier P" "degree g < degree f" + shows "monic_poly R (f \\<^bsub>P\<^esub> g)" +proof (cases "g \ \\<^bsub>P\<^esub>") + case True + define n where "n = degree f" + have "f \ carrier P - {\\<^bsub>P\<^esub>}" + using assms(1) univ_poly_zero + unfolding monic_poly_def by auto + hence "degree (f \\<^bsub>P\<^esub> g) = max (degree f) (degree g)" + using assms(2,3) True + by (subst degree_add_distinct, simp_all) + also have "... = degree f" + using assms(3) by simp + finally have b: "degree (f \\<^bsub>P\<^esub> g) = n" + unfolding n_def by simp + moreover have "n > 0" + using assms(3) unfolding n_def by simp + ultimately have "degree (f \\<^bsub>P\<^esub> g) \ degree ([])" + by simp + hence a:"f \\<^bsub>P\<^esub> g \ []" by auto + + have "degree [] = 0" by simp + also have "... < degree f" + using assms(3) by simp + finally have "degree f \ degree []" by simp + hence c: "f \ []" by auto + + have d: "length g \ n" + using assms(3) unfolding n_def by simp + + have "lead_coeff (f \\<^bsub>P\<^esub> g) = coeff (f \\<^bsub>P\<^esub> g) n" + using a b by (cases "f \\<^bsub>P\<^esub> g", auto) + also have "... = coeff f n \ coeff g n" + using monic_poly_carr assms + by (subst coeff_add, auto) + also have "... = lead_coeff f \ coeff g n" + using c unfolding n_def by (cases "f", auto) + also have "... = \ \ \" + using assms(1) unfolding monic_poly_def + unfolding subst coeff_length[OF d] by simp + also have "... = \" + by simp + finally have "lead_coeff (f \\<^bsub>P\<^esub> g) = \" by simp + moreover have "f \\<^bsub>P\<^esub> g \ carrier P" + using monic_poly_carr assms by simp + ultimately show ?thesis + using a unfolding monic_poly_def by auto +next + case False + then show ?thesis using assms monic_poly_carr by simp +qed + +lemma monic_poly_one: "monic_poly R \\<^bsub>P\<^esub>" +proof - + have "\\<^bsub>P\<^esub> \ carrier P" + by simp + thus ?thesis + by (simp add:univ_poly_one monic_poly_def) +qed + +lemma monic_poly_var: "monic_poly R X" +proof - + have "X \ carrier P" + using var_closed by simp + thus ?thesis + by (simp add:var_def monic_poly_def) +qed + +lemma monic_poly_carr_2: + assumes "monic_poly R f" + shows "f \ carrier (mult_of P)" + using assms unfolding monic_poly_def + by (simp add:univ_poly_zero) + +lemma monic_poly_mult: + assumes "monic_poly R f" + assumes "monic_poly R g" + shows "monic_poly R (f \\<^bsub>P\<^esub> g)" +proof - + have "lead_coeff (f \\<^bsub>P\<^esub> g) = lead_coeff f \\<^bsub>R\<^esub> lead_coeff g" + using assms monic_poly_carr_2 + by (subst lead_coeff_mult) auto + also have "... = \" + using assms unfolding monic_poly_def by simp + finally have "lead_coeff (f \\<^bsub>P\<^esub> g) = \\<^bsub>R\<^esub>" by simp + moreover have "(f \\<^bsub>P\<^esub> g) \ carrier (mult_of P)" + using monic_poly_carr_2 assms by blast + ultimately show ?thesis + by (simp add:monic_poly_def univ_poly_zero) +qed + +lemma monic_poly_pow: + assumes "monic_poly R f" + shows "monic_poly R (f [^]\<^bsub>P\<^esub> (n::nat))" + using assms monic_poly_one monic_poly_mult + by (induction n, auto) + +lemma monic_poly_prod: + assumes "finite A" + assumes "\x. x \ A \ monic_poly R (f x)" + shows "monic_poly R (finprod P f A)" + using assms +proof (induction A rule:finite_induct) + case empty + then show ?case by (simp add:monic_poly_one) +next + case (insert x F) + have a: "f \ F \ carrier P" + using insert monic_poly_carr by simp + have b: "f x \ carrier P" + using insert monic_poly_carr by simp + have "monic_poly R (f x \\<^bsub>P\<^esub> finprod P f F)" + using insert by (intro monic_poly_mult) auto + thus ?case + using insert a b by (subst p.finprod_insert, auto) +qed + +lemma monic_poly_not_assoc: + assumes "monic_poly R f" + assumes "monic_poly R g" + assumes "f \\<^bsub>(mult_of P)\<^esub> g" + shows "f = g" +proof - + obtain u where u_def: "f = g \\<^bsub>P\<^esub> u" "u \ Units (mult_of P)" + using p.mult_of.associatedD2 assms monic_poly_carr_2 + by blast + + hence "u \ Units P" by simp + then obtain v where v_def: "u = [v]" "v \ \\<^bsub>R\<^esub>" "v \ carrier R" + using univ_poly_carrier_units by auto + + have "\ = lead_coeff f" + using assms(1) by (simp add:monic_poly_def) + also have "... = lead_coeff (g \\<^bsub>P\<^esub> u)" + by (simp add:u_def) + also have "... = lead_coeff g \ lead_coeff u" + using assms(2) monic_poly_carr_2 v_def u_def(2) + by (subst lead_coeff_mult, auto simp add:univ_poly_zero) + also have "... = lead_coeff g \ v" + using v_def by simp + also have "... = v" + using assms(2) v_def(3) by (simp add:monic_poly_def) + finally have "\ = v" by simp + hence "u = \\<^bsub>P\<^esub>" + using v_def by (simp add:univ_poly_one) + thus "f = g" + using u_def assms monic_poly_carr by simp +qed + +lemma monic_poly_span: + assumes "x \ carrier (mult_of P)" "irreducible (mult_of P) x" + shows "\y. monic_irreducible_poly R y \ x \\<^bsub>(mult_of P)\<^esub> y" +proof - + define z where "z = poly_of_const (inv (lead_coeff x))" + define y where "y = x \\<^bsub>P\<^esub> z" + + have x_carr: "x \ carrier (mult_of P)" using assms by simp + + hence lx_ne_0: "lead_coeff x \ \" + and lx_unit: "lead_coeff x \ Units R" + using lead_coeff_carr[OF x_carr] by (auto simp add:field_Units) + have lx_inv_ne_0: "inv (lead_coeff x) \ \" + using lx_unit + by (metis Units_closed Units_r_inv r_null zero_not_one) + have lx_inv_carr: "inv (lead_coeff x) \ carrier R" + using lx_unit by simp + + have "z \ carrier P" + using lx_inv_carr poly_of_const_over_carrier + unfolding z_def by auto + moreover have "z \ \\<^bsub>P\<^esub>" + using lx_inv_ne_0 + by (simp add:z_def poly_of_const_def univ_poly_zero) + ultimately have z_carr: "z \ carrier (mult_of P)" by simp + have z_unit: "z \ Units (mult_of P)" + using lx_inv_ne_0 lx_inv_carr + by (simp add:univ_poly_carrier_units z_def poly_of_const_def) + have y_exp: "y = x \\<^bsub>(mult_of P)\<^esub> z" + by (simp add:y_def) + hence y_carr: "y \ carrier (mult_of P)" + using x_carr z_carr p.mult_of.m_closed by simp + + have "irreducible (mult_of P) y" + unfolding y_def using assms z_unit z_carr + by (intro p.mult_of.irreducible_prod_rI, auto) + moreover have "lead_coeff y = \\<^bsub>R\<^esub>" + unfolding y_def using x_carr z_carr lx_inv_ne_0 lx_unit + by (simp add: lead_coeff_mult z_def lead_coeff_poly_of_const) + hence "monic_poly R y" + using y_carr unfolding monic_poly_def + by (simp add:univ_poly_zero) + ultimately have "monic_irreducible_poly R y" + using p.irreducible_mult_imp_irreducible y_carr + by (simp add:monic_irreducible_poly_def ring_irreducible_def) + moreover have "y \\<^bsub>(mult_of P)\<^esub> x" + by (intro p.mult_of.associatedI2[OF z_unit] y_def x_carr) + hence "x \\<^bsub>(mult_of P)\<^esub> y" + using x_carr y_carr by (simp add:p.mult_of.associated_sym) + ultimately show ?thesis by auto +qed + +lemma monic_polys_are_canonical_irreducibles: + "canonical_irreducibles (mult_of P) {d. monic_irreducible_poly R d}" + (is "canonical_irreducibles (mult_of P) ?S") +proof - + have sp_1: + "?S \ {x \ carrier (mult_of P). irreducible (mult_of P) x}" + unfolding monic_irreducible_poly_def ring_irreducible_def + using monic_poly_carr + by (intro subsetI, simp add: p.irreducible_imp_irreducible_mult) + have sp_2: "x = y" + if "x \ ?S" "y \ ?S" "x \\<^bsub>(mult_of P)\<^esub> y" for x y + using that monic_poly_not_assoc + by (simp add:monic_irreducible_poly_def) + + have sp_3: "\y \ ?S. x \\<^bsub>(mult_of P)\<^esub> y" + if "x \ carrier (mult_of P)" "irreducible (mult_of P) x" for x + using that monic_poly_span by simp + + thus ?thesis using sp_1 sp_2 sp_3 + unfolding canonical_irreducibles_def by simp +qed + +lemma + assumes "monic_poly R a" + shows factor_monic_poly: + "a = (\\<^bsub>P\<^esub>d\{d. monic_irreducible_poly R d \ pmult d a > 0}. + d [^]\<^bsub>P\<^esub> pmult d a)" (is "?lhs = ?rhs") + and factor_monic_poly_fin: + "finite {d. monic_irreducible_poly R d \ pmult d a > 0}" +proof - + let ?S = "{d. monic_irreducible_poly R d}" + let ?T = "{d. monic_irreducible_poly R d \ pmult d a > 0}" + let ?mip = "monic_irreducible_poly R" + + have sp_4: "a \ carrier (mult_of P)" + using assms monic_poly_carr_2 + unfolding monic_irreducible_poly_def by simp + + have b_1: "x \ carrier (mult_of P)" if "?mip x" for x + using that monic_poly_carr_2 + unfolding monic_irreducible_poly_def by simp + have b_2:"irreducible (mult_of P) x" if "?mip x" for x + using that + unfolding monic_irreducible_poly_def ring_irreducible_def + by (simp add: monic_poly_carr p.irreducible_imp_irreducible_mult) + have b_3:"x \ carrier P" if "?mip x" for x + using that monic_poly_carr + unfolding monic_irreducible_poly_def + by simp + + have a_carr: "a \ carrier P - {\\<^bsub>P\<^esub>}" + using sp_4 by simp + + have "?T = {d. ?mip d \ multiplicity (mult_of P) d a > 0}" + by (simp add:pmult_def) + also have "... = {d \ ?S. multiplicity (mult_of P) d a > 0}" + using p.mult_of.multiplicity_gt_0_iff[OF b_1 b_2 sp_4] + by (intro order_antisym subsetI, auto) + finally have t:"?T = {d \ ?S. multiplicity (mult_of P) d a > 0}" + by simp + + show fin_T: "finite ?T" + unfolding t + using p.mult_of.split_factors(1) + [OF monic_polys_are_canonical_irreducibles] + using sp_4 by auto + + have a:"x [^]\<^bsub>P\<^esub> (n::nat) \ carrier (mult_of P)" if "?mip x" for x n + proof - + have "monic_poly R (x [^]\<^bsub>P\<^esub> n)" + using that monic_poly_pow + unfolding monic_irreducible_poly_def by auto + thus ?thesis + using monic_poly_carr_2 by simp + qed + + have "?lhs \\<^bsub>(mult_of P)\<^esub> + finprod (mult_of P) + (\d. d [^]\<^bsub>(mult_of P)\<^esub> (multiplicity (mult_of P) d a)) ?T" + unfolding t + by (intro p.mult_of.split_factors(2) + [OF monic_polys_are_canonical_irreducibles sp_4]) + also have "... = + finprod (mult_of P) (\d. d [^]\<^bsub>P\<^esub> (multiplicity (mult_of P) d a)) ?T" + by (simp add:nat_pow_mult_of) + also have "... = ?rhs" + using fin_T a + by (subst p.finprod_mult_of, simp_all add:pmult_def) + finally have "?lhs \\<^bsub>(mult_of P)\<^esub> ?rhs" by simp + moreover have "monic_poly R ?rhs" + using fin_T + by (intro monic_poly_prod monic_poly_pow) + (auto simp:monic_irreducible_poly_def) + ultimately show "?lhs = ?rhs" + using monic_poly_not_assoc assms monic_irreducible_poly_def + by blast +qed + +lemma degree_monic_poly': + assumes "monic_poly R f" + shows + "sum' (\d. pmult d f * degree d) {d. monic_irreducible_poly R d} = + degree f" +proof - + let ?mip = "monic_irreducible_poly R" + + have b: "d \ carrier P - {\\<^bsub>P\<^esub>}" if "?mip d" for d + using that monic_poly_carr_2 + unfolding monic_irreducible_poly_def by simp + have a: "d [^]\<^bsub>P\<^esub> n \ carrier P - {\\<^bsub>P\<^esub>}" if "?mip d" for d and n :: "nat" + using b that monic_poly_pow + unfolding monic_irreducible_poly_def + by (simp add: p.pow_non_zero) + + have "degree f = + degree (\\<^bsub>P\<^esub>d\{d. ?mip d \ pmult d f > 0}. d [^]\<^bsub>P\<^esub> pmult d f)" + using factor_monic_poly[OF assms(1)] by simp + also have "... = + (\i\{d. ?mip d \ 0 < pmult d f}. degree (i [^]\<^bsub>P\<^esub> pmult i f))" + using a assms(1) + by (subst degree_prod[OF factor_monic_poly_fin]) + (simp_all add:Pi_def) + also have "... = + (\i\{d. ?mip d \ 0 < pmult d f}. degree i * pmult i f)" + using b degree_pow by (intro sum.cong, auto) + also have "... = + (\d\{d. ?mip d \ 0 < pmult d f}. pmult d f * degree d)" + by (simp add:mult.commute) + also have "... = + sum' (\d. pmult d f * degree d) {d. ?mip d \ 0 < pmult d f}" + using sum.eq_sum factor_monic_poly_fin[OF assms(1)] by simp + also have "... = sum' (\d. pmult d f * degree d) {d. ?mip d}" + by (intro sum.mono_neutral_cong_left' subsetI, auto) + finally show ?thesis by simp +qed + +lemma monic_poly_min_degree: + assumes "monic_irreducible_poly R f" + shows "degree f \ 1" + using assms unfolding monic_irreducible_poly_def monic_poly_def + by (intro pirreducible_degree) auto + +lemma degree_one_monic_poly: + "monic_irreducible_poly R f \ degree f = 1 \ + (\x \ carrier R. f = [\, \x])" +proof + assume "monic_irreducible_poly R f \ degree f = 1" + hence a:"monic_poly R f" "length f = 2" + unfolding monic_irreducible_poly_def by auto + then obtain u v where f_def: "f = [u,v]" + by (cases f, simp, cases "tl f", auto) + + have "u = \" using a unfolding monic_poly_def f_def by simp + moreover have "v \ carrier R" + using a unfolding monic_poly_def univ_poly_carrier[symmetric] + unfolding polynomial_def f_def by simp + ultimately have "f = [\, \(\v)]" "(\v) \ carrier R" + using a_inv_closed f_def by auto + thus "(\x \ carrier R. f = [\\<^bsub>R\<^esub>, \\<^bsub>R\<^esub>x])" by auto +next + assume "(\x \ carrier R. f = [\, \x])" + then obtain x where f_def: "f = [\,\x]" "x \ carrier R" by auto + have a:"degree f = 1" using f_def(2) unfolding f_def by simp + have b:"f \ carrier P" + using f_def(2) unfolding univ_poly_carrier[symmetric] + unfolding f_def polynomial_def by simp + have c: "pirreducible (carrier R) f" + by (intro degree_one_imp_pirreducible a b) + have d: "lead_coeff f = \" unfolding f_def by simp + show "monic_irreducible_poly R f \ degree f = 1" + using a b c d + unfolding monic_irreducible_poly_def monic_poly_def + by auto +qed + +lemma multiplicity_ge_iff: + assumes "monic_irreducible_poly R d" + assumes "f \ carrier P - {\\<^bsub>P\<^esub>}" + shows "pmult d f \ k \ d [^]\<^bsub>P\<^esub> k pdivides f" +proof - + have a:"f \ carrier (mult_of P)" + using assms(2) by simp + have b: "d \ carrier (mult_of P)" + using assms(1) monic_poly_carr_2 + unfolding monic_irreducible_poly_def by simp + have c: "irreducible (mult_of P) d" + using assms(1) monic_poly_carr_2 + using p.irreducible_imp_irreducible_mult + unfolding monic_irreducible_poly_def + unfolding ring_irreducible_def monic_poly_def + by simp + have d: "d [^]\<^bsub>P\<^esub> k \ carrier P" using b by simp + + have "pmult d f \ k \ d [^]\<^bsub>(mult_of P)\<^esub> k divides\<^bsub>(mult_of P)\<^esub> f" + unfolding pmult_def + by (intro p.mult_of.multiplicity_ge_iff a b c) + also have "... \ d [^]\<^bsub>P\<^esub> k pdivides\<^bsub>R\<^esub> f" + using p.divides_imp_divides_mult[OF d assms(2)] + using divides_mult_imp_divides + unfolding pdivides_def nat_pow_mult_of + by auto + finally show ?thesis by simp +qed + +lemma multiplicity_ge_1_iff_pdivides: + assumes "monic_irreducible_poly R d" "f \ carrier P - {\\<^bsub>P\<^esub>}" + shows "pmult d f \ 1 \ d pdivides f" +proof - + have "d \ carrier P" + using assms(1) monic_poly_carr + unfolding monic_irreducible_poly_def + by simp + thus ?thesis + using multiplicity_ge_iff[OF assms, where k="1"] + by simp +qed + +lemma divides_monic_poly: + assumes "monic_poly R f" "monic_poly R g" + assumes "\d. monic_irreducible_poly R d + \ pmult d f \ pmult d g" + shows "f pdivides g" +proof - + have a:"f \ carrier (mult_of P)" "g \ carrier (mult_of P)" + using monic_poly_carr_2 assms(1,2) by auto + + have "f divides\<^bsub>(mult_of P)\<^esub> g" + using assms(3) unfolding pmult_def + by (intro p.mult_of.divides_iff_mult_mono + [OF a monic_polys_are_canonical_irreducibles]) simp + thus ?thesis + unfolding pdivides_def using divides_mult_imp_divides by simp +qed + +end + +lemma monic_poly_hom: + assumes "monic_poly R f" + assumes "h \ ring_iso R S" "domain R" "domain S" + shows "monic_poly S (map h f)" +proof - + have c: "h \ ring_hom R S" + using assms(2) ring_iso_def by auto + have e: "f \ carrier (poly_ring R)" + using assms(1) unfolding monic_poly_def by simp + + have a:"f \ []" + using assms(1) unfolding monic_poly_def by simp + hence "map h f \ []" by simp + moreover have "lead_coeff f = \\<^bsub>R\<^esub>" + using assms(1) unfolding monic_poly_def by simp + hence "lead_coeff (map h f) = \\<^bsub>S\<^esub>" + using ring_hom_one[OF c] by (simp add: hd_map[OF a]) + ultimately show ?thesis + using carrier_hom[OF e assms(2-4)] + unfolding monic_poly_def by simp +qed + +lemma monic_irreducible_poly_hom: + assumes "monic_irreducible_poly R f" + assumes "h \ ring_iso R S" "domain R" "domain S" + shows "monic_irreducible_poly S (map h f)" +proof - + have a: + "pirreducible\<^bsub>R\<^esub> (carrier R) f" + "f \ carrier (poly_ring R)" + "monic_poly R f" + using assms(1) + unfolding monic_poly_def monic_irreducible_poly_def + by auto + + have "pirreducible\<^bsub>S\<^esub> (carrier S) (map h f)" + using a pirreducible_hom assms by auto + moreover have "monic_poly S (map h f)" + using a monic_poly_hom[OF _ assms(2,3,4)] by simp + ultimately show ?thesis + unfolding monic_irreducible_poly_def by simp +qed + +end diff --git a/thys/Finite_Fields/ROOT b/thys/Finite_Fields/ROOT new file mode 100644 --- /dev/null +++ b/thys/Finite_Fields/ROOT @@ -0,0 +1,18 @@ +chapter AFP + +session Finite_Fields (AFP) = "HOL-Algebra" + + options [timeout = 600] + sessions + Dirichlet_Series + theories + Card_Irreducible_Polynomials + Card_Irreducible_Polynomials_Aux + Finite_Fields_Factorization_Ext + Finite_Fields_Isomorphic + Finite_Fields_Preliminary_Results + Formal_Polynomial_Derivatives + Monic_Polynomial_Factorization + Ring_Characteristic + document_files + "root.tex" + "root.bib" diff --git a/thys/Finite_Fields/Ring_Characteristic.thy b/thys/Finite_Fields/Ring_Characteristic.thy new file mode 100644 --- /dev/null +++ b/thys/Finite_Fields/Ring_Characteristic.thy @@ -0,0 +1,1017 @@ +section \Characteristic of Rings\label{sec:ring_char}\ + +theory Ring_Characteristic + imports + "Finite_Fields_Factorization_Ext" + "HOL-Algebra.IntRing" + "HOL-Algebra.Embedded_Algebras" +begin + +locale finite_field = field + + assumes finite_carrier: "finite (carrier R)" +begin + +lemma finite_field_min_order: + "order R > 1" +proof (rule ccontr) + assume a:"\(1 < order R)" + have "{\\<^bsub>R\<^esub>,\\<^bsub>R\<^esub>} \ carrier R" by auto + hence "card {\\<^bsub>R\<^esub>,\\<^bsub>R\<^esub>} \ card (carrier R)" + using card_mono finite_carrier by blast + also have "... \ 1" using a by (simp add:order_def) + finally have "card {\\<^bsub>R\<^esub>,\\<^bsub>R\<^esub>} \ 1" by blast + thus "False" by simp +qed + +lemma (in finite_field) order_pow_eq_self: + assumes "x \ carrier R" + shows "x [^] (order R) = x" +proof (cases "x = \") + case True + have "order R > 0" + using assms(1) order_gt_0_iff_finite finite_carrier by simp + then obtain n where n_def:"order R = Suc n" + using lessE by blast + have "x [^] (order R) = \" + unfolding n_def using True by (subst nat_pow_Suc, simp) + thus ?thesis using True by simp +next + case False + have x_carr:"x \ carrier (mult_of R)" + using False assms by simp + + have carr_non_empty: "card (carrier R) > 0" + using order_gt_0_iff_finite finite_carrier + unfolding order_def by simp + have "x [^] (order R) = x [^]\<^bsub>mult_of R\<^esub> (order R)" + by (simp add:nat_pow_mult_of) + also have "... = x [^]\<^bsub>mult_of R\<^esub> (order (mult_of R)+1)" + using carr_non_empty unfolding order_def + by (intro arg_cong[where f="\t. x [^]\<^bsub>mult_of R\<^esub> t"]) (simp) + also have "... = x" + using x_carr + by (simp add:mult_of.pow_order_eq_1) + finally show "x [^] (order R) = x" + by simp +qed + +lemma (in finite_field) order_pow_eq_self': + assumes "x \ carrier R" + shows "x [^] (order R ^ d) = x" +proof (induction d) + case 0 + then show ?case using assms by simp +next + case (Suc d) + have "x [^] order R ^ (Suc d) = x [^] (order R ^ d * order R)" + by (simp add:mult.commute) + also have "... = (x [^] (order R ^ d)) [^] order R" + using assms by (simp add: nat_pow_pow) + also have "... = (x [^] (order R ^ d))" + using order_pow_eq_self assms by simp + also have "... = x" + using Suc by simp + finally show ?case by simp +qed + +end + +lemma finite_fieldI: + assumes "field R" + assumes "finite (carrier R)" + shows "finite_field R" + using assms + unfolding finite_field_def finite_field_axioms_def + by auto + +lemma (in domain) finite_domain_units: + assumes "finite (carrier R)" + shows "Units R = carrier R - {\}" (is "?lhs = ?rhs") +proof + have "Units R \ carrier R" by (simp add:Units_def) + moreover have "\ \ Units R" + by (meson zero_is_prime(1) primeE) + ultimately show "Units R \ carrier R - {\}" by blast +next + have "x \ Units R" if a: "x \ carrier R - {\}" for x + proof - + have x_carr: "x \ carrier R" using a by blast + define f where "f = (\y. y \\<^bsub>R\<^esub> x)" + have "inj_on f (carrier R)" unfolding f_def + by (rule inj_onI, metis DiffD1 DiffD2 a m_rcancel insertI1) + hence "card (carrier R) = card (f ` carrier R)" + by (metis card_image) + moreover have "f ` carrier R \ carrier R" unfolding f_def + by (rule image_subsetI, simp add: ring.ring_simprules x_carr) + ultimately have "f ` carrier R = carrier R" + using card_subset_eq assms by metis + moreover have "\\<^bsub>R\<^esub> \ carrier R" by simp + ultimately have "\y \ carrier R. f y = \\<^bsub>R\<^esub>" + by (metis image_iff) + then obtain y + where y_carrier: "y \ carrier R" + and y_left_inv: "y \\<^bsub>R\<^esub> x = \\<^bsub>R\<^esub>" + using f_def by blast + hence y_right_inv: "x \\<^bsub>R\<^esub> y = \\<^bsub>R\<^esub>" + by (metis DiffD1 a cring_simprules(14)) + show "x \ Units R" + using y_carrier y_left_inv y_right_inv + by (metis DiffD1 a divides_one factor_def) + qed + thus "?rhs \ ?lhs" by auto +qed + +text \The following theorem can be found in Lidl and Niederreiter~\cite[Theorem 1.31]{lidl1986}.\ + +theorem finite_domains_are_fields: + assumes "domain R" + assumes "finite (carrier R)" + shows "finite_field R" +proof - + interpret domain R using assms by auto + have "Units R = carrier R - {\\<^bsub>R\<^esub>}" + using finite_domain_units[OF assms(2)] by simp + then have "field R" + by (simp add: assms(1) field.intro field_axioms.intro) + thus ?thesis + using assms(2) finite_fieldI by auto +qed + +definition zfact_iso :: "nat \ nat \ int set" where + "zfact_iso p k = Idl\<^bsub>\\<^esub> {int p} +>\<^bsub>\\<^esub> (int k)" + +context + fixes n :: nat + assumes n_gt_0: "n > 0" +begin + +private abbreviation I where "I \ Idl\<^bsub>\\<^esub> {int n}" + +private lemma ideal_I: "ideal I \" + by (simp add: int.genideal_ideal) + +lemma int_cosetI: + assumes "u mod (int n) = v mod (int n)" + shows "Idl\<^bsub>\\<^esub> {int n} +>\<^bsub>\\<^esub> u = Idl\<^bsub>\\<^esub> {int n} +>\<^bsub>\\<^esub> v" +proof - + have "u - v \ I" + by (metis Idl_subset_eq_dvd assms int_Idl_subset_ideal mod_eq_dvd_iff) + thus ?thesis + using ideal_I int.quotient_eq_iff_same_a_r_cos by simp +qed + +lemma zfact_iso_inj: + "inj_on (zfact_iso n) {.. {.. {..\<^bsub>\\<^esub> (int x) = I +>\<^bsub>\\<^esub> (int y)" + by (simp add:zfact_iso_def) + hence "int x - int y \ I" + by (subst int.quotient_eq_iff_same_a_r_cos[OF ideal_I], auto) + hence "int x mod int n = int y mod int n" + by (meson Idl_subset_eq_dvd int_Idl_subset_ideal mod_eq_dvd_iff) + thus "x = y" + using a by simp +qed + +lemma zfact_iso_ran: + "zfact_iso n ` {.. carrier (ZFact (int n))" + unfolding zfact_iso_def ZFact_def FactRing_simps + using int.a_rcosetsI by auto + moreover have "x \ zfact_iso n ` {.. carrier (ZFact (int n))" for x + proof - + obtain y where y_def: "x = I +>\<^bsub>\\<^esub> y" + using a unfolding ZFact_def FactRing_simps by auto + obtain z where z_def: "(int z) mod (int n) = y mod (int n)" "z < n" + by (metis Euclidean_Division.pos_mod_sign mod_mod_trivial + nonneg_int_cases of_nat_0_less_iff of_nat_mod n_gt_0 + unique_euclidean_semiring_numeral_class.pos_mod_bound) + have "x = I +>\<^bsub>\\<^esub> y" + by (simp add:y_def) + also have "... = I +>\<^bsub>\\<^esub> (int z)" + by (intro int_cosetI, simp add:z_def) + also have "... = zfact_iso n z" + by (simp add:zfact_iso_def) + finally have "x = zfact_iso n z" + by simp + thus "x \ zfact_iso n ` {.. 0" using assms(1) prime_gt_0_nat by simp + have "Factorial_Ring.prime (int p)" + using assms by simp + moreover have "finite (carrier (ZFact (int p)))" + using fin_zfact[OF p_gt_0] by simp + ultimately show ?thesis + by (intro finite_domains_are_fields ZFact_prime_is_domain, auto) +qed + +definition int_embed :: "_ \ int \ _" where + "int_embed R k = add_pow R k \\<^bsub>R\<^esub>" + +lemma (in ring) add_pow_consistent: + fixes i :: "int" + assumes "subring K R" + assumes "k \ K" + shows "add_pow R i k = add_pow (R \ carrier := K \) i k" + (is "?lhs = ?rhs") +proof - + have a:"subgroup K (add_monoid R)" + using assms(1) subring.axioms by auto + have "add_pow R i k = k [^]\<^bsub>add_monoid R\carrier := K\\<^esub> i" + using add.int_pow_consistent[OF a assms(2)] by simp + also have "... = ?rhs" + unfolding add_pow_def by simp + finally show ?thesis by simp +qed + +lemma (in ring) int_embed_consistent: + assumes "subring K R" + shows "int_embed R i = int_embed (R \ carrier := K \) i" +proof - + have a:"\ = \\<^bsub>R \ carrier := K \\<^esub>" by simp + have b:"\\<^bsub>R\carrier := K\\<^esub> \ K" + using assms subringE(3) by auto + show ?thesis + unfolding int_embed_def a using b add_pow_consistent[OF assms(1)] by simp +qed + +lemma (in ring) int_embed_closed: + "int_embed R k \ carrier R" + unfolding int_embed_def using add.int_pow_closed by simp + +lemma (in ring) int_embed_range: + assumes "subring K R" + shows "int_embed R k \ K" +proof - + let ?R' = "R \ carrier := K \" + interpret x:ring ?R' + using subring_is_ring[OF assms] by simp + have "int_embed R k = int_embed ?R' k" + using int_embed_consistent[OF assms] by simp + also have "... \ K" + using x.int_embed_closed by simp + finally show ?thesis by simp +qed + +lemma (in ring) int_embed_zero: + "int_embed R 0 = \\<^bsub>R\<^esub>" + by (simp add:int_embed_def add_pow_def) + +lemma (in ring) int_embed_one: + "int_embed R 1 = \\<^bsub>R\<^esub>" + by (simp add:int_embed_def) + +lemma (in ring) int_embed_add: + "int_embed R (x+y) = int_embed R x \\<^bsub>R\<^esub> int_embed R y" + by (simp add:int_embed_def add.int_pow_mult) + +lemma (in ring) int_embed_inv: + "int_embed R (-x) = \\<^bsub>R\<^esub> int_embed R x" (is "?lhs = ?rhs") +proof - + have "?lhs = int_embed R (-x) \ (int_embed R x \ int_embed R x)" + using int_embed_closed by simp + also have + "... = int_embed R (-x) \ int_embed R x \ (\ int_embed R x)" + using int_embed_closed by (subst a_minus_def, subst a_assoc, auto) + also have "... = int_embed R (-x +x) \ (\ int_embed R x)" + by (subst int_embed_add, simp) + also have "... = ?rhs" + using int_embed_closed + by (simp add:int_embed_zero) + finally show ?thesis by simp +qed + +lemma (in ring) int_embed_diff: + "int_embed R (x-y) = int_embed R x \\<^bsub>R\<^esub> int_embed R y" + (is "?lhs = ?rhs") +proof - + have "?lhs = int_embed R (x + (-y))" by simp + also have "... = ?rhs" + by (subst int_embed_add, simp add:a_minus_def int_embed_inv) + finally show ?thesis by simp +qed + +lemma (in ring) int_embed_mult_aux: + "int_embed R (x*int y) = int_embed R x \ int_embed R y" +proof (induction y) + case 0 + then show ?case by (simp add:int_embed_closed int_embed_zero) +next + case (Suc y) + have "int_embed R (x * int (Suc y)) = int_embed R (x + x * int y)" + by (simp add:algebra_simps) + also have "... = int_embed R x \ int_embed R (x * int y)" + by (subst int_embed_add, simp) + also have + "... = int_embed R x \ \ \ int_embed R x \ int_embed R y" + using int_embed_closed + by (subst Suc, simp) + also have "... = int_embed R x \ (int_embed R 1 \ int_embed R y)" + using int_embed_closed by (subst r_distr, simp_all add:int_embed_one) + also have "... = int_embed R x \ int_embed R (1+int y)" + by (subst int_embed_add, simp) + also have "... = int_embed R x \ int_embed R (Suc y)" + by simp + finally show ?case by simp +qed + +lemma (in ring) int_embed_mult: + "int_embed R (x*y) = int_embed R x \\<^bsub>R\<^esub> int_embed R y" +proof (cases "y \ 0") + case True + then obtain y' where y_def: "y = int y'" + using nonneg_int_cases by auto + have "int_embed R (x * y) = int_embed R (x * int y')" + unfolding y_def by simp + also have "... = int_embed R x \ int_embed R y'" + by (subst int_embed_mult_aux, simp) + also have "... = int_embed R x \ int_embed R y" + unfolding y_def by simp + finally show ?thesis by simp +next + case False + then obtain y' where y_def: "y = - int y'" + by (meson nle_le nonpos_int_cases) + have "int_embed R (x * y) = int_embed R (-(x * int y'))" + unfolding y_def by simp + also have "... = \ (int_embed R (x * int y'))" + by (subst int_embed_inv, simp) + also have "... = \ (int_embed R x \ int_embed R y')" + by (subst int_embed_mult_aux, simp) + also have "... = int_embed R x \ \ int_embed R y'" + using int_embed_closed by algebra + also have "... = int_embed R x \ int_embed R (-y')" + by (subst int_embed_inv, simp) + also have "... = int_embed R x \ int_embed R y" + unfolding y_def by simp + finally show ?thesis by simp +qed + +lemma (in ring) int_embed_ring_hom: + "ring_hom_ring int_ring R (int_embed R)" +proof (rule ring_hom_ringI) + show "ring int_ring" using int.is_ring by simp + show "ring R" using ring_axioms by simp + show "int_embed R x \ carrier R" if "x \ carrier \" for x + using int_embed_closed by simp + show "int_embed R (x\\<^bsub>\\<^esub>y) = int_embed R x \ int_embed R y" + if "x \ carrier \" "y \ carrier \" for x y + using int_embed_mult by simp + show "int_embed R (x\\<^bsub>\\<^esub>y) = int_embed R x \ int_embed R y" + if "x \ carrier \" "y \ carrier \" for x y + using int_embed_add by simp + show "int_embed R \\<^bsub>\\<^esub> = \" + by (simp add:int_embed_one) +qed + +abbreviation char_subring where + "char_subring R \ int_embed R ` UNIV" + +definition char where + "char R = card (char_subring R)" + +text \This is a non-standard definition for the characteristic of a ring. + +Commonly~\cite[Definition 1.43]{lidl1986} it is defined to be the smallest natural number $n$ such +that n-times repeated addition of any number is zero. If no such number exists then it is defined +to be $0$. In the case of rings with unit elements --- not that the locale @{locale "ring"} requires +unit elements --- the above definition can be simplified to the number of times the unit elements +needs to be repeatedly added to reach $0$. + +The following three lemmas imply that the definition of the characteristic here coincides with the +latter definition.\ + +lemma (in ring) char_bound: + assumes "x > 0" + assumes "int_embed R (int x) = \" + shows "char R \ x" "char R > 0" +proof - + have "char_subring R \ int_embed R ` ({0.. UNIV" + define u where "u = y div (int x)" + define v where "v = y mod (int x)" + have "int x > 0" using assms by simp + hence y_exp: "y = u * int x + v" "v \ 0" "v < int x" + unfolding u_def v_def by simp_all + have "int_embed R y = int_embed R v" + using int_embed_closed unfolding y_exp + by (simp add:int_embed_mult int_embed_add assms(2)) + also have "... \ int_embed R ` ({0.. int_embed R ` {0.. card {0.. x" by simp + have "1 = card {int_embed R 0}" by simp + also have "... \ card (int_embed R ` {0.. 0" by simp +qed + +lemma (in ring) embed_char_eq_0: + "int_embed R (int (char R)) = \" +proof (cases "finite (char_subring R)") + case True + interpret h: ring_hom_ring "int_ring" R "(int_embed R)" + using int_embed_ring_hom by simp + + define A where "A = {0..int (char R)}" + have "card (int_embed R ` A) \ card (char_subring R)" + by (intro card_mono[OF True] image_subsetI, simp) + also have "... = char R" + unfolding char_def by simp + also have "... < card A" + unfolding A_def by simp + finally have "card (int_embed R ` A) < card A" by simp + hence "\inj_on (int_embed R) A" + using pigeonhole by simp + then obtain x y where xy: + "x \ A" "y \ A" "x \ y" "int_embed R x = int_embed R y" + unfolding inj_on_def by auto + define v where "v = nat (max x y - min x y)" + have a:"int_embed R v = \" + using xy int_embed_closed + by (cases "x < y", simp_all add:int_embed_diff v_def) + moreover have "v > 0" + using xy by (cases "x < y", simp_all add:v_def) + ultimately have "char R \ v" using char_bound by simp + moreover have "v \ char R" + using xy v_def A_def by (cases "x < y", simp_all) + ultimately have "char R = v" by simp + then show ?thesis using a by simp +next + case False + hence "char R = 0" + unfolding char_def by simp + then show ?thesis by (simp add:int_embed_zero) +qed + +lemma (in ring) embed_char_eq_0_iff: + fixes n :: int + shows "int_embed R n = \ \ char R dvd n" +proof (cases "char R > 0") + case True + define r where "r = n mod char R" + define s where "s = n div char R" + have rs: "r < char R" "r \ 0" "n = r + s * char R" + using True by (simp_all add:r_def s_def) + + have "int_embed R n = int_embed R r" + using int_embed_closed unfolding rs(3) + by (simp add: int_embed_add int_embed_mult embed_char_eq_0) + + moreover have "nat r < char R" using rs by simp + hence "int_embed R (nat r) \ \ \ nat r = 0" + using True char_bound not_less by blast + hence "int_embed R r \ \ \ r = 0" + using rs by simp + + ultimately have "int_embed R n = \ \ r = 0" + using int_embed_zero by auto + also have "r = 0 \ char R dvd n" + using r_def by auto + finally show ?thesis by simp +next + case False + hence "char R = 0" by simp + hence a:"x > 0 \ int_embed R (int x) \ \" for x + using char_bound by auto + + have c:"int_embed R (abs x) \ \ \ int_embed R x \ \" for x + using int_embed_closed + by (cases "x > 0", simp, simp add:int_embed_inv) + + have "int_embed R x \ \" if b:"x \ 0" for x + proof - + have "nat (abs x) > 0" using b by simp + hence "int_embed R (nat (abs x)) \ \" + using a by blast + hence "int_embed R (abs x) \ \" by simp + thus ?thesis using c by simp + qed + hence "int_embed R n = \ \ n = 0" + using int_embed_zero by auto + also have "n = 0 \ char R dvd n" using False by simp + finally show ?thesis by simp +qed + +text \This result can be found in \cite[Theorem 1.44]{lidl1986}.\ + +lemma (in domain) characteristic_is_prime: + assumes "char R > 0" + shows "prime (char R)" +proof (rule ccontr) + have "\(char R = 1)" + using embed_char_eq_0 int_embed_one by auto + hence "\(char R dvd 1)" using assms(1) by simp + moreover assume "\(prime (char R))" + hence "\(irreducible (char R))" + using irreducible_imp_prime_elem_gcd prime_elem_nat_iff by blast + ultimately obtain p q where pq_def: "p * q = char R" "p > 1" "q > 1" + using assms + unfolding Factorial_Ring.irreducible_def by auto + have "int_embed R p \ int_embed R q = \" + using embed_char_eq_0 pq_def + by (subst int_embed_mult[symmetric]) (metis of_nat_mult) + hence "int_embed R p = \ \ int_embed R q = \" + using integral int_embed_closed by simp + hence "p*q \ p \ p*q \ q" + using char_bound pq_def by auto + thus "False" + using pq_def(2,3) by simp +qed + +lemma (in ring) char_ring_is_subring: + "subring (char_subring R) R" +proof - + have "subring (int_embed R ` carrier int_ring) R" + by (intro ring.carrier_is_subring int.is_ring + ring_hom_ring.img_is_subring[OF int_embed_ring_hom]) + thus ?thesis by simp +qed + +lemma (in cring) char_ring_is_subcring: + "subcring (char_subring R) R" + using subcringI'[OF char_ring_is_subring] by auto + +lemma (in domain) char_ring_is_subdomain: + "subdomain (char_subring R) R" + using subdomainI'[OF char_ring_is_subring] by auto + +lemma image_set_eqI: + assumes "\x. x \ A \ f x \ B" + assumes "\x. x \ B \ g x \ A \ f (g x) = x" + shows "f ` A = B" + using assms by force + +text \This is the binomial expansion theorem for commutative rings.\ + +lemma (in cring) binomial_expansion: + fixes n :: nat + assumes [simp]: "x \ carrier R" "y \ carrier R" + shows "(x \ y) [^] n = + (\k \ {..n}. int_embed R (n choose k) \ x [^] k \ y [^] (n-k))" +proof - + define A where "A = (\k. {A. A \ {.. card A = k})" + + have fin_A: "finite (A i)" for i + unfolding A_def by simp + have disj_A: "pairwise (\i j. disjnt (A i) (A j)) {..n}" + unfolding pairwise_def disjnt_def A_def by auto + have card_A: "B \ A i \ card B = i" if " i \ {..n}" for i B + unfolding A_def by simp + have card_A2: "card (A i) = (n choose i)" if "i \ {..n}" for i + unfolding A_def using n_subsets[where A="{.. n" + if "A \ {.. {..<(n::nat)}" for n A + using finite_subset that by (subst card_insert_disjoint, auto) + + have embed_distr: "[m] \ y = int_embed R (int m) \ y" + if "y \ carrier R" for m y + unfolding int_embed_def add_pow_def using that + by (simp add:add_pow_def[symmetric] int_pow_int add_pow_ldistr) + + have "(x \ y) [^] n = + (\A \ Pow {.. y [^] (n-card A))" + proof (induction n) + case 0 + then show ?case by simp + next + case (Suc n) + have s1: + "insert n ` Pow {.. {.. n \ A}" + by (intro image_set_eqI[where g="\x. x \ {.. {.. n \ A}" + using lessThan_Suc by auto + + have "(x \ y) [^] Suc n = (x \ y) [^] n \ (x \ y)" by simp + also have "... = + (\A \ Pow {.. y [^] (n-card A)) \ + (x \ y)" + by (subst Suc, simp) + also have "... = + (\A \ Pow {.. y [^] (n-card A)) \ x \ + (\A \ Pow {.. y [^] (n-card A)) \ y" + by (subst r_distr, auto) + also have "... = + (\A \ Pow {.. y [^] (n-card A) \ x) \ + (\A \ Pow {.. y [^] (n-card A) \ y)" + by (simp add:finsum_ldistr) + also have "... = + (\A \ Pow {.. y [^] (n-card A)) \ + (\A \ Pow {.. y [^] (n-card A+1))" + using m_assoc m_comm + by (intro arg_cong2[where f="(\)"] finsum_cong', auto) + also have "... = + (\A \ Pow {.. y [^] (n+1-card (insert n A))) \ + (\A \ Pow {.. y [^] (n+1-card A))" + using finite_subset card_bound card_insert Suc_diff_le + by (intro arg_cong2[where f="(\)"] finsum_cong', simp_all) + also have "... = + (\A \ insert n ` Pow {.. y [^] (n+1-card A)) \ + (\A \ Pow {.. y [^] (n+1-card A))" + by (subst finsum_reindex, auto simp add:inj_on_def) + also have "... = + (\A \ {A. A \ {.. n \ A}. + x [^] (card A) \ y [^] (n+1-card A)) \ + (\A \ {A. A \ {.. n \ A}. + x [^] (card A) \ y [^] (n+1-card A))" + by (intro arg_cong2[where f="(\)"] finsum_cong' s1 s2, simp_all) + also have "... = (\A \ + {A. A \ {.. n \ A} \ {A. A \ {.. n \ A}. + x [^] (card A) \ y [^] (n+1-card A))" + by (subst finsum_Un_disjoint, auto) + also have "... = + (\A \ Pow {.. y [^] (n+1-card A))" + by (intro finsum_cong', auto) + finally show ?case by simp + qed + also have "... = + (\A \ (\ (A ` {..n})). x [^] (card A) \ y [^] (n-card A))" + using card_bound by (intro finsum_cong', auto simp add:A_def) + also have "... = + (\ k \ {..n}. (\ A \ A k. x [^] (card A) \ y [^] (n-card A)))" + using fin_A disj_A by (subst add.finprod_UN_disjoint, auto) + also have "... = (\ k \ {..n}. (\ A \ A k. x [^] k \ y [^] (n-k)))" + using card_A by (intro finsum_cong', auto) + also have "... = + (\ k \ {..n}. int_embed R (card (A k)) \ x [^] k \ y [^] (n-k))" + using int_embed_closed + by (subst add.finprod_const, simp_all add:embed_distr m_assoc) + also have "... = + (\ k \ {..n}. int_embed R (n choose k) \ x [^] k \ y [^] (n-k))" + using int_embed_closed card_A2 by (intro finsum_cong', simp_all) + finally show ?thesis by simp +qed + +lemma bin_prime_factor: + assumes "prime p" + assumes "k > 0" "k < p" + shows "p dvd (p choose k)" +proof - + have "p dvd fact p" + using assms(1) prime_dvd_fact_iff by auto + hence "p dvd fact k * fact (p - k) * (p choose k)" + using binomial_fact_lemma assms by simp + hence "p dvd fact k \ p dvd fact (p-k) \ p dvd (p choose k)" + by (simp add: assms(1) prime_dvd_mult_eq_nat) + thus "p dvd (p choose k)" + using assms(1,2,3) prime_dvd_fact_iff by auto +qed + +theorem (in domain) freshmans_dream: + assumes "char R > 0" + assumes [simp]: "x \ carrier R" "y \ carrier R" + shows "(x \ y) [^] (char R) = x [^] char R \ y [^] char R" + (is "?lhs = ?rhs") +proof - + have c:"prime (char R)" + using assms(1) characteristic_is_prime by auto + have a:"int_embed R (char R choose i) = \" + if "i \ {..char R} - {0, char R}" for i + proof - + have "i > 0" "i < char R" using that by auto + hence "char R dvd char R choose i" + using c bin_prime_factor by simp + thus ?thesis using embed_char_eq_0_iff by simp + qed + + have "?lhs = (\k \ {..char R}. int_embed R (char R choose k) + \ x [^] k \ y [^] (char R-k))" + using binomial_expansion[OF assms(2,3)] by simp + also have "... = (\k \ {0,char R}.int_embed R (char R choose k) + \ x [^] k \ y [^] (char R-k))" + using a int_embed_closed + by (intro add.finprod_mono_neutral_cong_right, simp, simp_all) + also have "... = ?rhs" + using int_embed_closed assms(1) by (simp add:int_embed_one a_comm) + finally show ?thesis by simp +qed + +text \The following theorem is somtimes called Freshman's dream for obvious reasons, +it can be found in Lidl and Niederreiter~\cite[Theorem 1.46]{lidl1986}.\ + +lemma (in domain) freshmans_dream_ext: + fixes m + assumes "char R > 0" + assumes [simp]: "x \ carrier R" "y \ carrier R" + defines "n \ char R^m" + shows "(x \ y) [^] n = x [^] n \ y [^] n" + (is "?lhs = ?rhs") + unfolding n_def +proof (induction m) + case 0 + then show ?case by simp +next + case (Suc m) + have "(x \ y) [^] (char R^(m+1)) = + (x \ y) [^] (char R^m * char R)" + by (simp add:mult.commute) + also have "... = ((x \ y) [^] (char R^m)) [^] char R" + using nat_pow_pow by simp + also have "... = (x [^] (char R^m) \ y [^] (char R^m)) [^] char R" + by (subst Suc, simp) + also have "... = + (x [^] (char R^m)) [^] char R \ (y [^] (char R^m)) [^] char R" + by (subst freshmans_dream[OF assms(1), symmetric], simp_all) + also have "... = + x [^] (char R^m * char R) \ y [^] (char R^m * char R)" + by (simp add:nat_pow_pow) + also have "... = x [^] (char R^Suc m) \ y [^] (char R^Suc m)" + by (simp add:mult.commute) + finally show ?case by simp +qed + +text \The following is a generalized version of the Frobenius homomorphism. The classic version +of the theorem is the case where @{term "(k::nat) = 1"}.\ + +theorem (in domain) frobenius_hom: + assumes "char R > 0" + assumes "m = char R ^ k" + shows "ring_hom_cring R R (\x. x [^] m)" +proof - + have a:"(x \ y) [^] m = x [^] m \ y [^] m" + if b:"x \ carrier R" "y \ carrier R" for x y + using b nat_pow_distrib by simp + have b:"(x \ y) [^] m = x [^] m \ y [^] m" + if b:"x \ carrier R" "y \ carrier R" for x y + unfolding assms(2) freshmans_dream_ext[OF assms(1) b] + by simp + + have "ring_hom_ring R R (\x. x [^] m)" + by (intro ring_hom_ringI a b is_ring, simp_all) + + thus "?thesis" + using RingHom.ring_hom_cringI is_cring by blast +qed + +lemma (in domain) char_ring_is_subfield: + assumes "char R > 0" + shows "subfield (char_subring R) R" +proof - + interpret d:domain "R \ carrier := char_subring R \" + using char_ring_is_subdomain subdomain_is_domain by simp + + have "finite (char_subring R)" + using char_def assms by (metis card_ge_0_finite) + hence "Units (R \ carrier := char_subring R \) + = char_subring R - {\}" + using d.finite_domain_units by simp + + thus ?thesis + using subfieldI[OF char_ring_is_subcring] by simp +qed + +lemma card_lists_length_eq': + fixes A :: "'a set" + shows "card {xs. set xs \ A \ length xs = n} = card A ^ n" +proof (cases "finite A") + case True + then show ?thesis using card_lists_length_eq by auto +next + case False + hence inf_A: "infinite A" by simp + show ?thesis + proof (cases "n = 0") + case True + hence "card {xs. set xs \ A \ length xs = n} = card {([] :: 'a list)}" + by (intro arg_cong[where f="card"], auto simp add:set_eq_iff) + also have "... = 1" by simp + also have "... = card A^n" using True inf_A by simp + finally show ?thesis by simp + next + case False + hence "inj (replicate n)" + by (meson inj_onI replicate_eq_replicate) + hence "inj_on (replicate n) A" using inj_on_subset + by (metis subset_UNIV) + hence "infinite (replicate n ` A)" + using inf_A finite_image_iff by auto + moreover have + "replicate n ` A \ {xs. set xs \ A \ length xs = n}" + by (intro image_subsetI, auto) + ultimately have "infinite {xs. set xs \ A \ length xs = n}" + using infinite_super by auto + hence "card {xs. set xs \ A \ length xs = n} = 0" by simp + then show ?thesis using inf_A False by simp + qed +qed + +lemma (in ring) card_span: + assumes "subfield K R" + assumes "independent K w" + assumes "set w \ carrier R" + shows "card (Span K w) = card K^(length w)" +proof - + define A where "A = {x. set x \ K \ length x = length w}" + define f where "f = (\x. combine x w)" + + have "x \ f ` A" if a:"x \ Span K w" for x + proof - + obtain y where "y \ A" "x = f y" + unfolding A_def f_def + using unique_decomposition[OF assms(1,2) a] by auto + thus ?thesis by simp + qed + moreover have "f x \ Span K w" if a: "x \ A" for x + using Span_eq_combine_set[OF assms(1,3)] a + unfolding A_def f_def by auto + ultimately have b:"Span K w = f ` A" by auto + + have "False" if a: "x \ A" "y \ A" "f x = f y" "x \ y" for x y + proof - + have "f x \ Span K w" using b a by simp + thus "False" + using a unique_decomposition[OF assms(1,2)] + unfolding f_def A_def by blast + qed + hence f_inj: "inj_on f A" + unfolding inj_on_def by auto + + have "card (Span K w) = card (f ` A)" using b by simp + also have "... = card A" by (intro card_image f_inj) + also have "... = card K^length w" + unfolding A_def by (intro card_lists_length_eq') + finally show ?thesis by simp +qed + +lemma (in ring) finite_carr_imp_char_ge_0: + assumes "finite (carrier R)" + shows "char R > 0" +proof - + have "char_subring R \ carrier R" + using int_embed_closed by auto + hence "finite (char_subring R)" + using finite_subset assms by auto + hence "card (char_subring R) > 0" + using card_range_greater_zero by simp + thus "char R > 0" + unfolding char_def by simp +qed + +lemma (in ring) char_consistent: + assumes "subring H R" + shows "char (R \ carrier := H \) = char R" +proof - + show ?thesis + using int_embed_consistent[OF assms(1)] + unfolding char_def by simp +qed + +lemma (in ring_hom_ring) char_consistent: + assumes "inj_on h (carrier R)" + shows "char R = char S" +proof - + have a:"h (int_embed R (int n)) = int_embed S (int n)" for n + using R.int_embed_range[OF R.carrier_is_subring] + using R.int_embed_range[OF R.carrier_is_subring] + using S.int_embed_one R.int_embed_one + using S.int_embed_zero R.int_embed_zero + using S.int_embed_add R.int_embed_add + by (induction n, simp_all) + + have b:"h (int_embed R (-(int n))) = int_embed S (-(int n))" for n + using R.int_embed_range[OF R.carrier_is_subring] + using S.int_embed_range[OF S.carrier_is_subring] a + by (simp add:R.int_embed_inv S.int_embed_inv) + + have c:"h (int_embed R n) = int_embed S n" for n + proof (cases "n \ 0") + case True + then obtain m where "n = int m" + using nonneg_int_cases by auto + then show ?thesis + by (simp add:a) + next + case False + hence "n \ 0" by simp + then obtain m where "n = -int m" + using nonpos_int_cases by auto + then show ?thesis by (simp add:b) + qed + + have "char S = card (h ` char_subring R)" + unfolding char_def image_image c by simp + also have "... = card (char_subring R)" + using R.int_embed_range[OF R.carrier_is_subring] + by (intro card_image inj_on_subset[OF assms(1)]) auto + also have "... = char R" unfolding char_def by simp + finally show ?thesis + by simp +qed + +definition char_iso :: "_ \ int set \ 'a" + where "char_iso R x = the_elem (int_embed R ` x)" + +text \The function @{term "char_iso R"} denotes the isomorphism between @{term "ZFact (char R)"} and +the characteristic subring.\ + +lemma (in ring) char_iso: "char_iso R \ + ring_iso (ZFact (char R)) (R\carrier := char_subring R\)" +proof - + interpret h: ring_hom_ring "int_ring" "R" "int_embed R" + using int_embed_ring_hom by simp + + have "a_kernel \ R (int_embed R) = {x. int_embed R x = \}" + unfolding a_kernel_def kernel_def by simp + also have "... = {x. char R dvd x}" + using embed_char_eq_0_iff by simp + also have "... = PIdl\<^bsub>\\<^esub> (int (char R))" + unfolding cgenideal_def by auto + also have "... = Idl\<^bsub>\\<^esub> {int (char R)}" + using int.cgenideal_eq_genideal by simp + finally have a:"a_kernel \ R (int_embed R) = Idl\<^bsub>\\<^esub> {int (char R)}" + by simp + show "?thesis" + unfolding char_iso_def ZFact_def a[symmetric] + by (intro h.FactRing_iso_set_aux) +qed + +text \The size of a finite field must be a prime power. +This can be found in Ireland and Rosen~\cite[Proposition 7.1.3]{ireland1982}.\ + +theorem (in finite_field) finite_field_order: + "\n. order R = char R ^ n \ n > 0" +proof - + have a:"char R > 0" + using finite_carr_imp_char_ge_0[OF finite_carrier] + by simp + let ?CR = "char_subring R" + + obtain v where v_def: "set v = carrier R" + using finite_carrier finite_list by auto + hence b:"set v \ carrier R" by auto + + have "carrier R = set v" using v_def by simp + also have "... \ Span ?CR v" + using Span_base_incl[OF char_ring_is_subfield[OF a] b] by simp + finally have "carrier R \ Span ?CR v" by simp + moreover have "Span ?CR v \ carrier R" + using int_embed_closed v_def by (intro Span_in_carrier, auto) + ultimately have Span_v: "Span ?CR v = carrier R" by simp + + obtain w where w_def: + "set w \ carrier R" + "independent ?CR w" + "Span ?CR v = Span ?CR w" + using b filter_base[OF char_ring_is_subfield[OF a]] + by metis + + have Span_w: "Span ?CR w = carrier R" + using w_def(3) Span_v by simp + + hence "order R = card (Span ?CR w)" by (simp add:order_def) + also have "... = card ?CR^length w" + by (intro card_span char_ring_is_subfield[OF a] w_def(1,2)) + finally have c: + "order R = char R^(length w)" + by (simp add:char_def) + have "length w > 0" + using finite_field_min_order c by auto + thus ?thesis using c by auto +qed + +end diff --git a/thys/Finite_Fields/document/root.bib b/thys/Finite_Fields/document/root.bib new file mode 100644 --- /dev/null +++ b/thys/Finite_Fields/document/root.bib @@ -0,0 +1,42 @@ +@book{ireland1982, + author = {Kenneth Ireland and + Michael Rosen}, + title = {A classical introduction to modern number theory}, + series = {Graduate texts in mathematics}, + volume = {84}, + publisher = {Springer}, + year = {1982}, + isbn = {978-0-387-90625-6}, + timestamp = {Fri, 28 Jun 2019 12:45:52 +0200}, + biburl = {https://dblp.org/rec/books/daglib/0068082.bib}, + bibsource = {dblp computer science bibliography, https://dblp.org} +} + +@book{lidl1986, +author = {Lidl, Rudolf and Niederreiter, Harald}, +title = {Introduction to Finite Fields and Their Applications}, +year = {1986}, +isbn = {0521307066}, +publisher = {Cambridge University Press}, +address = {USA} +} + +@article{chebolu2010, + title={Counting Irreducible Polynomials over Finite Fields Using the Inclusion-Exclusion Principle}, + author={Sunil K. Chebolu and J{\'a}n Min{\'a}{\v{c}}}, + journal={Mathematics Magazine}, + year={2010}, + volume={84}, + pages={369 - 371} +} + +@article{Dirichlet_Series-AFP, + author = {Manuel Eberl}, + title = {Dirichlet Series}, + journal = {Archive of Formal Proofs}, + month = oct, + year = 2017, + note = {\url{https://isa-afp.org/entries/Dirichlet_Series.html}, + Formal proof development}, + ISSN = {2150-914x}, +} \ No newline at end of file diff --git a/thys/Finite_Fields/document/root.tex b/thys/Finite_Fields/document/root.tex new file mode 100644 --- /dev/null +++ b/thys/Finite_Fields/document/root.tex @@ -0,0 +1,37 @@ +\documentclass[11pt,a4paper]{article} +\usepackage[T1]{fontenc} +\usepackage{isabelle,isabellesym} +\usepackage{amssymb} +\usepackage{pdfsetup} +\urlstyle{rm} +\isabellestyle{it} + +\begin{document} + +\title{Finite Fields} +\author{Emin Karayel} +\maketitle + +\abstract{This entry formalizes the classification of the finite fields (also called Galois fields): +For each prime power $p^n$ there exists exactly one (up to isomorphisms) finite field of that size +and there are no other finite fields. +The derivation includes a formalization of the characteristic of rings, the Frobenius endomorphism, +formal differentiation for polynomials in HOL-Algebra and Gauss' formula for the number of +monic irreducible polynomials over finite fields: +\[ +\frac{1}{n} \sum_{d | n} \mu(d) p^{n/d} \textrm{.} +\] +The proofs are based on the books from Ireland and Rosen~\cite{ireland1982}, as well as, +Lidl and Niederreiter~\cite{lidl1986}. +} + +\parindent 0pt\parskip 0.5ex + +\tableofcontents + +\input{session} + +\bibliographystyle{abbrv} +\bibliography{root} + +\end{document} \ No newline at end of file diff --git a/thys/Fishers_Inequality/document/root.tex b/thys/Fishers_Inequality/document/root.tex --- a/thys/Fishers_Inequality/document/root.tex +++ b/thys/Fishers_Inequality/document/root.tex @@ -1,30 +1,35 @@ \documentclass[11pt,a4paper]{article} \usepackage{isabelle,isabellesym} % 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{Fisher's Inequality: Linear Algebraic Proof Techniques for Combinatorics} \author{Chelsea Edmonds and Lawrence C. Paulson} \maketitle \begin{abstract} Linear algebraic techniques are powerful, yet often underrated tools in combinatorial proofs. This formalisation provides a library including matrix representations of incidence set systems, general formal proof techniques for the rank argument and linear bound argument, and finally a formalisation of a number of variations of the well-known Fisher's inequality. We build on our prior work formalising combinatorial design theory using a locale-centric approach, including extensions such as constant intersect designs and dual incidence systems. In addition to Fisher's inequality, we also formalise proofs on other incidence system properties using the incidence matrix representation, such as design existence, dual system relationships and incidence system isomorphisms. This formalisation is presented in the paper "Formalising Fisher's Inequality: Formal Linear Algebraic Techniques in Combinatorics", accepted to ITP 2022. \end{abstract} \tableofcontents +\paragraph*{Acknowledgements} +The authors were supported by the ERC Advanced Grant ALEXANDRIA (Project 742178) funded by the European Research Council. + +\newpage + % include generated text of all theories \input{session} \bibliographystyle{abbrv} \bibliography{root} \end{document} diff --git a/thys/Package_logic/PackageLogic.thy b/thys/Package_logic/PackageLogic.thy new file mode 100755 --- /dev/null +++ b/thys/Package_logic/PackageLogic.thy @@ -0,0 +1,1420 @@ +section \Package Logic\ + +text \In this section, we define our package logic, as described in \cite{Dardinier22}, +and then prove that this logic is sound and complete for packaging magic wands.\ + +theory PackageLogic + imports Main SepAlgebra +begin + +subsection Definitions + +type_synonym 'a abool = "'a \ bool" + +datatype 'a aassertion = + AStar "'a aassertion" "'a aassertion" +| AImp "'a abool" "'a aassertion" +| ASem "'a abool" + +locale package_logic = sep_algebra + + + fixes unit :: "'a" + fixes stable :: "'a \ bool" + + assumes unit_neutral: "Some a = a \ unit" + and stable_sum: "stable a \ stable b \ Some x = a \ b \ stable x" + and stable_unit: "stable unit" + +begin + +fun sat :: "'a aassertion \ 'a \ bool" where + "sat (AStar A B) \ \ (\a b. Some \ = a \ b \ sat A a \ sat B b)" +| "sat (AImp b A) \ \ (b \ \ sat A \)" +| "sat (ASem A) \ \ A \" + +definition mono_pure_cond where + "mono_pure_cond b \ (\\. b \ \ b |\| ) \ (\\' \ r. pure r \ Some \' = \ \ r \ \ b \ \ \ b \')" + +definition bool_conj where + "bool_conj a b x \ a x \ b x" + +type_synonym 'c pruner = "'c \ bool" + +(* Only positively, so not-well defined = false *) +definition mono_pruner :: "'a pruner \ bool" where + "mono_pruner p \ (\\' \ r. pure r \ p \ \ Some \' = \ \ r \ p \')" +(* opposite of mono_cond *) + +fun wf_assertion where + "wf_assertion (AStar A B) \ wf_assertion A \ wf_assertion B" +| "wf_assertion (AImp b A) \ mono_pure_cond b \ wf_assertion A" +| "wf_assertion (ASem A) \ mono_pruner A" + +type_synonym 'c transformer = "'c \ 'c" + +type_synonym 'c ext_state = "'c \ 'c \ 'c transformer" + +inductive package_rhs :: + "'a \ 'a \ 'a ext_state set \ 'a abool \ 'a aassertion \ 'a \ 'a \ 'a ext_state set \ bool" where + + AStar: "\ package_rhs \ f S pc A \' f' S' ; package_rhs \' f' S' pc B \'' f'' S'' \ \ package_rhs \ f S pc (AStar A B) \'' f'' S''" +| AImp: "package_rhs \ f S (bool_conj pc b) A \' f' S' \ package_rhs \ f S pc (AImp b A) \' f' S'" +(* witness means we *choose* how we satisfy B *) +| ASem: "\ \a u T b. (a, u, T) \ S \ pc a \ b = witness (a, u, T) \ a \ b \ B b ; + S' = { (a, u, T) |a u T. (a, u, T) \ S \ \ pc a } + \ { (a \ b, the (u \ b), T) |a u T b. (a, u, T) \ S \ pc a \ b = witness (a, u, T) } \ + \ package_rhs \ f S pc (ASem B) \ f S'" + +| AddFromOutside: "\ Some \ = \' \ m ; package_rhs \' f' S' pc A \'' f'' S'' ; stable m ; Some f' = f \ m ; + S' = { (r, u, T) |a u T r. (a, u, T) \ S \ Some r = a \ (T f' \ T f) \ r ## u } \ + \ package_rhs \ f S pc A \'' f'' S''" + + +definition package_sat where + "package_sat pc A a' u' u \ (pc |a'| \ (\x. Some x = |a'| \ (u' \ u ) \ sat A x))" + +definition package_rhs_connection :: "'a \ 'a \ 'a ext_state set \ 'a abool \ 'a aassertion \ 'a \ 'a \ 'a ext_state set \ bool" where + "package_rhs_connection \ f S pc A \' f' S' \ f' \ f \ \ ## f \ \ \ f = \' \ f' \ stable f' \ + (\(a, u, T) \ S. \au. Some au = a \ u \ (au ## (T f' \ T f) \ + (\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u)))" + +definition mono_transformer :: "'a transformer \ bool" where + "mono_transformer T \ (\\ \'. \' \ \ \ T \' \ T \) \ T unit = unit" + +definition valid_package_set where + "valid_package_set S f \ (\(a, u, T) \ S. a ## u \ |a| \ |u| \ mono_transformer T \ a \ |T f| )" + +definition intuitionistic where + "intuitionistic A \ (\\' \. \' \ \ \ A \ \ A \')" + +definition pure_remains where + "pure_remains S \ (\(a, u, p) \ S. pure a)" + +definition is_footprint_general :: "'a \ ('a \ 'a \ 'a) \ 'a aassertion \ 'a aassertion \ bool" where + "is_footprint_general w R A B \ (\a b. sat A a \ Some b = a \ R a w \ sat B b)" + +definition is_footprint_standard :: "'a \ 'a aassertion \ 'a aassertion \ bool" where + "is_footprint_standard w A B \ (\a b. sat A a \ Some b = a \ w \ sat B b)" + + + +subsection Lemmas + +lemma is_footprint_generalI: + assumes "\a b. sat A a \ Some b = a \ R a w \ sat B b" + shows "is_footprint_general w R A B" + using assms is_footprint_general_def by blast + +lemma is_footprint_standardI: + assumes "\a b. sat A a \ Some b = a \ w \ sat B b" + shows "is_footprint_standard w A B" + using assms is_footprint_standard_def by blast + + +lemma mono_pure_condI: + assumes "\\. b \ \ b |\|" + and "\\ \' r. pure r \ Some \' = \ \ r \ \ b \ \ \ b \'" + shows "mono_pure_cond b" + using assms(1) assms(2) mono_pure_cond_def by blast + +lemma mono_pure_cond_conj: + assumes "mono_pure_cond pc" + and "mono_pure_cond b" + shows "mono_pure_cond (bool_conj pc b)" +proof (rule mono_pure_condI) + show "\\. bool_conj pc b \ = bool_conj pc b |\|" + by (metis assms(1) assms(2) bool_conj_def mono_pure_cond_def) + show "\\ \' r. pure r \ Some \' = \ \ r \ \ bool_conj pc b \ \ \ bool_conj pc b \'" + by (metis assms(1) assms(2) bool_conj_def mono_pure_cond_def) +qed + +lemma bigger_sum: + assumes "Some \ = a \ b" + and "\' \ \" + shows "\b'. b' \ b \ Some \' = a \ b'" +proof - + obtain r where "Some \' = \ \ r" + using assms(2) greater_def by blast + then obtain b' where "Some b' = b \ r" + by (metis assms(1) asso2 domD domI domIff) + then show ?thesis + by (metis \Some \' = \ \ r\ assms(1) asso1 commutative sep_algebra.greater_equiv sep_algebra_axioms) +qed + +lemma wf_assertion_sat_larger_pure: + assumes "wf_assertion A" + and "sat A \" + and "Some \' = \ \ r" + and "pure r" + shows "sat A \'" + using assms +proof (induct arbitrary: \ \' r rule: wf_assertion.induct) + case (1 A B) + then obtain a b where "Some \ = a \ b" "sat A a" "sat B b" by (meson sat.simps(1)) + then obtain b' where "Some b' = b \ r" + by (metis "1.prems"(3) asso2 option.collapse) + moreover obtain a' where "Some a' = a \ r" + by (metis "1.prems"(3) \Some \ = a \ b\ asso2 commutative option.collapse) + ultimately show ?case + using 1 + by (metis \Some \ = a \ b\ \sat A a\ \sat B b\ asso1 sat.simps(1) wf_assertion.simps(1)) +next + case (2 b A) + then show ?case + by (metis mono_pure_cond_def sat.simps(2) wf_assertion.simps(2)) +next + case (3 A) + then show ?case + by (metis mono_pruner_def sat.simps(3) wf_assertion.simps(3)) +qed + + +lemma package_satI: + assumes "pc |a'| \ (\x. Some x = |a'| \ (u' \ u ) \ sat A x)" + shows "package_sat pc A a' u' u" + by (simp add: assms package_sat_def) + + +lemma package_rhs_connection_instantiate: + assumes "package_rhs_connection \ f S pc A \' f' S'" + and "(a, u, T) \ S" + obtains au where "Some au = a \ u" + and "au ## (T f' \ T f) \ \a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u" + using assms(1) assms(2) package_rhs_connection_def by fastforce + +lemma package_rhs_connectionI: + assumes "\ \ f = \' \ f'" + and "stable f'" + and "\ ## f" + and "f' \ f" + and "\a u T. (a, u, T) \ S \ (\au. Some au = a \ u \ (au ## (T f' \ T f) \ + (\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u'\ u' \ u \ package_sat pc A a' u' u)))" + shows "package_rhs_connection \ f S pc A \' f' S'" + using package_rhs_connection_def assms by auto + +lemma valid_package_setI: + assumes "\a u T. (a, u, T) \ S \ a ## u \ |a| \ |u| \ mono_transformer T \ a \ |T f| " + shows "valid_package_set S f" + using assms valid_package_set_def by auto + +lemma defined_sum_move: + assumes "a ## b" + and "Some b = x \ y" + and "Some a' = a \ x" + shows "a' ## y" + by (metis assms defined_def sep_algebra.asso1 sep_algebra_axioms) + +lemma bigger_core_sum_defined: + assumes "|a| \ b" + shows "Some a = a \ b" + by (metis (no_types, lifting) assms asso1 core_is_smaller greater_equiv max_projection_prop_pure_core mpp_prop pure_def pure_smaller) + + +lemma package_rhs_proof: + assumes "package_rhs \ f S pc A \' f' S'" + and "valid_package_set S f" + and "wf_assertion A" + and "mono_pure_cond pc" + and "stable f" + and "\ ## f" + shows "package_rhs_connection \ f S pc A \' f' S' \ valid_package_set S' f'" + using assms +proof (induct rule: package_rhs.induct) + case (AImp \ f S pc b A \' f' S') + then have asm0: "package_rhs_connection \ f S (bool_conj pc b) A \' f' S' \ valid_package_set S' f'" + using mono_pure_cond_conj wf_assertion.simps(2) by blast + let ?pc = "bool_conj pc b" + obtain "\ \ f = \' \ f'" "stable f'" "\ ## f" "f' \ f" + and \
: "\a u T. (a, u, T) \ S \ (\au. Some au = a \ u \ (au ## (T f' \ T f) \ + (\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat ?pc A a' u' u)))" + using asm0 package_rhs_connection_def by force + + + have "package_rhs_connection \ f S pc (AImp b A) \' f' S'" + proof (rule package_rhs_connectionI) + show "\ ## f" + by (simp add: \\ ## f\) + show "\ \ f = \' \ f'" by (simp add: \\ \ f = \' \ f'\) + show "stable f'" using \stable f'\ by simp + show "f' \ f" by (simp add: \f' \ f\) + fix a u T assume asm1: "(a, u, T) \ S" + then obtain au where asm2: "Some au = a \ u \ (au ## (T f' \ T f) \ + (\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat ?pc A a' u' u))" + using \
by presburger + + then have "au ## (T f' \ T f) \ + (\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc (AImp b A) a' u' u)" + proof - + assume asm3: "au ## (T f' \ T f)" + then obtain a' u' where au': "(a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat ?pc A a' u' u" + using asm2 by blast + have "(the ( |a'| \ (u' \ u))) \ |a'|" + proof - + have "u' \ u' \ u" + by (metis minus_default minus_smaller succ_refl) + then have "a' ## (u' \ u)" + by (metis au' asm3 asso3 defined_def minus_exists) + then show ?thesis + by (metis core_is_smaller defined_def greater_def option.exhaust_sel sep_algebra.asso2 sep_algebra_axioms) + qed + have "package_sat pc (AImp b A) a' u' u" + proof (rule package_satI) + assume "pc |a'|" + then show "\x. Some x = |a'| \ (u' \ u) \ sat (AImp b A) x" + proof (cases "b |a'|") + case True + then have "?pc |a'|" + by (simp add: \pc |a'|\ bool_conj_def) + then show ?thesis + by (metis au' package_logic.package_sat_def package_logic_axioms sat.simps(2)) + next + case False + then have "\ b (the ( |a'| \ (u' \ u)))" + using AImp.prems(2) \the ( |a'| \ (u' \ u)) \ |a'|\ core_sum max_projection_prop_def max_projection_prop_pure_core minus_exists mono_pure_cond_def wf_assertion.simps(2) + by metis + moreover obtain x where "Some x = |a'| \ (u' \ u)" + by (metis au' asm3 asso2 commutative core_is_smaller defined_def minus_and_plus option.collapse) + ultimately show ?thesis by (metis option.sel sat.simps(2)) + qed + qed + then show "\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc (AImp b A) a' u' u" + using au' by blast + qed + then show "\au. Some au = a \ u \ (au ## (T f' \ T f) \ (\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc (AImp b A) a' u' u))" + using asm2 by auto + qed + then show ?case + using \package_rhs_connection \ f S (bool_conj pc b) A \' f' S' \ valid_package_set S' f'\ by blast +next + case (AStar \ f S pc A \' f' S' B \'' f'' S'') + then have r1: "package_rhs_connection \ f S pc A \' f' S' \ valid_package_set S' f'" + using wf_assertion.simps(1) by blast + moreover have "\' ## f'" using r1 package_rhs_connection_def[of \ f S pc A \' f' S'] defined_def + by fastforce + ultimately have r2: "package_rhs_connection \' f' S' pc B \'' f'' S'' \ valid_package_set S'' f''" + using AStar.hyps(4) AStar.prems(2) AStar.prems(3) package_rhs_connection_def by force + + moreover obtain fa_def: "\ \ f = \' \ f'" "stable f'" "\ ## f" "f' \ f" + and **: "\a u T. (a, u, T) \ S \ (\au. Some au = a \ u \ (au ## (T f' \ T f) \ + (\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u)))" + using r1 package_rhs_connection_def by fastforce + then obtain fb_def: "\' \ f' = \'' \ f''" "stable f''" "\' ## f'" "f'' \ f'" + and "\a u T. (a, u, T) \ S' \ (\au. Some au = a \ u \ (au ## (T f'' \ T f') \ + (\a' u'. (a', u', T) \ S'' \ |a'| \ |a| \ au \ (T f'' \ T f') = a' \ u' \ u' \ u \ package_sat pc B a' u' u)))" + using r2 package_rhs_connection_def by fastforce + + + moreover have "package_rhs_connection \ f S pc (AStar A B) \'' f'' S''" + proof (rule package_rhs_connectionI) + show "\ \ f = \'' \ f''" by (simp add: fa_def(1) fb_def(1)) + show "stable f''" by (simp add: fb_def(2)) + show "\ ## f" using fa_def(3) by auto + show "f'' \ f" using fa_def(4) fb_def(4) succ_trans by blast + + + fix a u T assume asm0: "(a, u, T) \ S" + then have f_def: "Some (T f'' \ T f) = (T f'' \ T f') \ (T f' \ T f)" + proof - + have "mono_transformer T" using valid_package_set_def asm0 \valid_package_set S f\ by fastforce + then have "T f'' \ T f'" + by (simp add: fb_def(4) mono_transformer_def) + moreover have "T f' \ T f" + using \mono_transformer T\ fa_def(4) mono_transformer_def by blast + ultimately show ?thesis + using commutative minus_and_plus minus_equiv_def by presburger + qed + + then obtain au where au_def: "Some au = a \ u" + "au ## (T f' \ T f) \ (\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u)" + using \\u a T. (a, u, T) \ S \ \au. Some au = a \ u \ (au ## T f' \ T f \ (\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u))\ asm0 by blast + then show "\au. Some au = a \ u \ (au ## (T f'' \ T f) \ (\a' u'. (a', u', T) \ S'' \ |a'| \ |a| \ au \ (T f'' \ T f) = a' \ u' \ u' \ u \ package_sat pc (AStar A B) a' u' u))" + proof (cases "au ## (T f'' \ T f)") + case True + moreover have "mono_transformer T" using \valid_package_set S f\ valid_package_set_def asm0 by fastforce + ultimately have "au ## (T f'' \ T f') \ au ## (T f' \ T f)" using asso3 commutative defined_def f_def + by metis + then obtain a' u' where "(a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u" + using au_def(2) by blast + + then obtain au' where au'_def: "Some au' = a' \ u'" + "au' ## (T f'' \ T f') \ (\a'' u''. (a'', u'', T) \ S'' \ |a''| \ |a'| \ au' \ (T f'' \ T f') = a'' \ u'' \ u'' \ u' \ package_sat pc B a'' u'' u')" + using \\u a T. (a, u, T) \ S' \ \au. Some au = a \ u \ (au ## T f'' \ T f' \ (\a' u'. (a', u', T) \ S'' \ |a'| \ |a| \ au \ (T f'' \ T f') = a' \ u' \ u' \ u \ package_sat pc B a' u' u))\ by blast + moreover have "au' ## T f'' \ T f'" + using True \(a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u\ calculation(1) commutative defined_sum_move f_def by fastforce + ultimately obtain a'' u'' where "(a'', u'', T) \ S'' \ |a''| \ |a'| \ au' \ (T f'' \ T f') = a'' \ u'' \ u'' \ u' \ package_sat pc B a'' u'' u'" + by blast + + then have "au \ (T f'' \ T f) = a'' \ u''" + proof - + have "au \ (T f'' \ T f) = splus (Some au) (Some (T f'' \ T f))" + by simp + also have "... = splus (Some au) (splus (Some (T f'' \ T f')) (Some (T f' \ T f)))" + using f_def by auto + finally show ?thesis + by (metis (full_types) \(a'', u'', T) \ S'' \ |a''| \ |a'| \ au' \ (T f'' \ T f') = a'' \ u'' \ u'' \ u' \ package_sat pc B a'' u'' u'\ \(a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u\ au'_def(1) splus.simps(3) splus_asso splus_comm) + qed + moreover have "package_sat pc (AStar A B) a'' u'' u" + proof (rule package_satI) + assume "pc |a''|" + then have "pc |a'|" + by (metis AStar.prems(3) \(a'', u'', T) \ S'' \ |a''| \ |a'| \ au' \ (T f'' \ T f') = a'' \ u'' \ u'' \ u' \ package_sat pc B a'' u'' u'\ greater_equiv minus_core minus_core_weaker minus_equiv_def mono_pure_cond_def pure_def) + then obtain x where "Some x = |a'| \ (u' \ u) \ sat A x" + using \(a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u\ package_sat_def by fastforce + then obtain x' where "Some x' = |a''| \ (u'' \ u') \ sat B x'" + using \(a'', u'', T) \ S'' \ |a''| \ |a'| \ au' \ (T f'' \ T f') = a'' \ u'' \ u'' \ u' \ package_sat pc B a'' u'' u'\ \pc |a''|\ package_sat_def by auto + have "u'' \ u'' \ u" + by (metis minus_default minus_smaller succ_refl) + moreover have "a'' ## u''" + using True \au \ (T f'' \ T f) = a'' \ u''\ defined_def by auto + ultimately obtain x'' where "Some x'' = |a''| \ (u'' \ u)" + by (metis commutative defined_def max_projection_prop_pure_core mpp_smaller not_None_eq smaller_compatible) + moreover have "Some (u'' \ u) = (u'' \ u') \ (u' \ u)" + using \(a'', u'', T) \ S'' \ |a''| \ |a'| \ au' \ (T f'' \ T f') = a'' \ u'' \ u'' \ u' \ package_sat pc B a'' u'' u'\ \(a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u\ commutative minus_and_plus minus_equiv_def by presburger + moreover have "|a''| \ |a'|" + using \(a'', u'', T) \ S'' \ |a''| \ |a'| \ au' \ (T f'' \ T f') = a'' \ u'' \ u'' \ u' \ package_sat pc B a'' u'' u'\ by blast + moreover have "Some |a''| = |a'| \ |a''|" + by (metis (no_types, lifting) calculation(3) core_is_pure sep_algebra.asso1 sep_algebra.minus_exists sep_algebra_axioms) + ultimately have "Some x'' = x' \ x" + using asso1[of _ _ x'] \Some x = |a'| \ (u' \ u) \ sat A x\ \Some x' = |a''| \ (u'' \ u') \ sat B x'\ commutative + by metis + then show "\x. Some x = |a''| \ (u'' \ u) \ sat (AStar A B) x" + using \Some x = |a'| \ (u' \ u) \ sat A x\ \Some x' = |a''| \ (u'' \ u') \ sat B x'\ \Some x'' = |a''| \ (u'' \ u)\ commutative by fastforce + qed + ultimately show ?thesis + using \(a'', u'', T) \ S'' \ |a''| \ |a'| \ au' \ (T f'' \ T f') = a'' \ u'' \ u'' \ u' \ package_sat pc B a'' u'' u'\ \(a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u\ au_def(1) succ_trans by blast + next + case False + then show ?thesis + using au_def(1) by blast + qed + qed + ultimately show ?case by blast +next + case (ASem S pc witness B S' \ f) + have "valid_package_set S' f" + proof (rule valid_package_setI) + fix a' u' T assume asm0: "(a', u', T) \ S'" + then show "a' ## u' \ |a'| \ |u'| \ mono_transformer T \ a' \ |T f|" + proof (cases "(a', u', T) \ S") + case True + then show ?thesis + using ASem.prems(1) valid_package_set_def by auto + next + case False + then have "(a', u', T) \ {(a \ b, the (u \ b), T) |a u T b. (a, u, T) \ S \ pc a \ b = witness (a, u, T)}" + using ASem.hyps(2) asm0 by blast + then obtain a u b where "(a, u, T) \ S" "pc a" "b = witness (a, u, T)" "a' = a \ b" "u' = the (u \ b)" by blast + then have "a \ b \ B b" + using ASem.hyps(1) by presburger + have "a ## u" + using ASem.prems(1) \(a, u, T) \ S\ valid_package_set_def by fastforce + then have "Some u' = u \ b" + by (metis \a \ b \ B b\ \u' = the (u \ b)\ commutative defined_def option.exhaust_sel smaller_compatible) + moreover have "Some a = a' \ b" + using \a \ b \ B b\ \a' = a \ b\ commutative minus_equiv_def by presburger + + ultimately have "a' ## u'" + by (metis \a ## u\ asso1 commutative defined_def) + moreover have "|a'| \ |u'|" + proof - + have "|a| \ |u|" + using ASem.prems(1) \(a, u, T) \ S\ valid_package_set_def by fastforce + moreover have "|a'| \ |a|" + by (simp add: \a' = a \ b\ minus_core succ_refl) + moreover have "|a'| \ |b|" + using \a \ b \ B b\ \a' = a \ b\ max_projection_prop_pure_core minus_core mpp_mono by presburger + ultimately show ?thesis + by (metis \Some u' = u \ b\ \a' = a \ b\ core_is_pure core_sum minus_core pure_def smaller_pure_sum_smaller) + qed + moreover have "a' \ |T f|" + proof - + have "a \ |T f|" using \(a, u, T) \ S\ \valid_package_set S f\ valid_package_set_def + by fastforce + then show ?thesis + by (metis \a' = a \ b\ max_projection_prop_pure_core minus_core mpp_mono mpp_smaller sep_algebra.mpp_invo sep_algebra.succ_trans sep_algebra_axioms) + qed + ultimately show ?thesis using \(a, u, T) \ S\ \valid_package_set S f\ valid_package_set_def + by fastforce + qed + qed + moreover have "package_rhs_connection \ f S pc (ASem B) \ f S'" + proof (rule package_rhs_connectionI) + show "\ \ f = \ \ f" + by simp + show "stable f" by (simp add: ASem.prems(4)) + show "\ ## f" by (simp add: ASem.prems(5)) + show "f \ f" by (simp add: succ_refl) + + fix a u T assume asm0: "(a, u, T) \ S" + + then obtain au where "Some au = a \ u" using \valid_package_set S f\ valid_package_set_def defined_def by auto + then have "(\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ Some au = a' \ u' \ u' \ u \ package_sat pc (ASem B) a' u' u)" + proof - + let ?b = "witness (a, u, T)" + let ?a = "a \ ?b" + let ?u = "the (u \ ?b)" + show "\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ Some au = a' \ u' \ u' \ u \ package_sat pc (ASem B) a' u' u" + proof (cases "pc a") + case True + then have "(?a, ?u, T) \ S'" using ASem.hyps(2) asm0 by blast + then have "a \ ?b \ B ?b" using ASem.hyps(1) True asm0 by blast + moreover have "(?a, ?u, T) \ S' \ |?a| \ |a| \ Some au = ?a \ ?u \ ?u \ u" + proof + show "(a \ witness (a, u, T), the (u \ witness (a, u, T)), T) \ S'" + by (simp add: \(a \ witness (a, u, T), the (u \ witness (a, u, T)), T) \ S'\) + have "|a \ witness (a, u, T)| \ |a| " + by (simp add: minus_core succ_refl) + moreover have "Some au = a \ witness (a, u, T) \ the (u \ witness (a, u, T))" + using \Some au = a \ u\ \a \ witness (a, u, T) \ B (witness (a, u, T))\ + asso1[of "a \ witness (a, u, T)" "witness (a, u, T)" a u "the (u \ witness (a, u, T))"] + commutative option.distinct(1) option.exhaust_sel asso3 minus_equiv_def + by metis + moreover have "the (u \ witness (a, u, T)) \ u" + using \Some au = a \ u\ \a \ witness (a, u, T) \ B (witness (a, u, T))\ commutative + greater_def option.distinct(1) option.exhaust_sel asso3[of u "witness (a, u, T)" ] + by metis + ultimately show "|a \ witness (a, u, T)| \ |a| \ Some au = a \ witness (a, u, T) \ the (u \ witness (a, u, T)) \ the (u \ witness (a, u, T)) \ u" + by blast + qed + moreover have "package_sat pc (ASem B) ?a ?u u" + proof (rule package_satI) + assume "pc |a \ witness (a, u, T)|" + have "Some ?u = u \ ?b" + by (metis (no_types, lifting) \Some au = a \ u\ calculation(1) commutative minus_equiv_def option.distinct(1) option.exhaust_sel sep_algebra.asso3 sep_algebra_axioms) + moreover have "?a ## ?u" + by (metis \(a \ witness (a, u, T), the (u \ witness (a, u, T)), T) \ S' \ |a \ witness (a, u, T)| \ |a| \ Some au = a \ witness (a, u, T) \ the (u \ witness (a, u, T)) \ the (u \ witness (a, u, T)) \ u\ defined_def option.distinct(1)) + moreover have "?u \ ?u \ u" + using \(a \ witness (a, u, T), the (u \ witness (a, u, T)), T) \ S' \ |a \ witness (a, u, T)| \ |a| \ Some au = a \ witness (a, u, T) \ the (u \ witness (a, u, T)) \ the (u \ witness (a, u, T)) \ u\ minus_smaller by blast + ultimately obtain x where "Some x = |a \ ?b| \ (?u \ u)" + by (metis (no_types, opaque_lifting) \a \ witness (a, u, T) \ B (witness (a, u, T))\ commutative defined_def minus_core minus_equiv_def option.exhaust smaller_compatible) + moreover have "x \ ?b" + proof - + have "?u \ u \ ?b" + using \Some (the (u \ witness (a, u, T))) = u \ witness (a, u, T)\ minus_bigger by blast + then show ?thesis + using calculation greater_equiv succ_trans by blast + qed + ultimately show "\x. Some x = |a \ witness (a, u, T)| \ (the (u \ witness (a, u, T)) \ u) \ sat (ASem B) x" + using ASem.prems(2) \Some (the (u \ witness (a, u, T))) = u \ witness (a, u, T)\ + \a \ witness (a, u, T) \ B (witness (a, u, T))\ commutative max_projection_prop_def[of pure core] + max_projection_prop_pure_core minus_equiv_def_any_elem mono_pruner_def[of B] + sat.simps(3)[of B] wf_assertion.simps(3)[of B] + by metis + qed + ultimately show ?thesis by blast + next + case False + then have "package_sat pc (ASem B) a u u" + by (metis ASem.prems(3) mono_pure_cond_def package_sat_def) + moreover have "(a, u, T) \ S'" + using False ASem.hyps(2) asm0 by blast + ultimately show ?thesis + using \Some au = a \ u\ succ_refl by blast + qed + qed + moreover have "au \ (T f \ T f) = Some au" + proof - + have "a \ |T f|" using \(a, u, T) \ S\ \valid_package_set S f\ valid_package_set_def by fastforce + then have "|a| \ T f \ T f" + using core_is_smaller max_projection_prop_def max_projection_prop_pure_core minusI by presburger + then have "|au| \ T f \ T f" + using \Some au = a \ u\ core_sum greater_def succ_trans by blast + then show ?thesis using bigger_core_sum_defined by force + qed + ultimately show "\au. Some au = a \ u \ (au ## (T f \ T f) \ (\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ (T f \ T f) = a' \ u' \ u' \ u \ package_sat pc (ASem B) a' u' u))" + using \Some au = a \ u\ by fastforce + qed + ultimately show ?case by blast +next + case (AddFromOutside \ \' m f' S' pc A \'' f'' S'' f S) + have "valid_package_set S' f'" + proof (rule valid_package_setI) + fix a' u T assume asm0: "(a', u, T) \ S'" + then obtain a where "(a, u, T) \ S" "a' ## u" "Some a' = a \ (T f' \ T f)" + using AddFromOutside.hyps(6) by blast + then have "|a| \ |u| \ mono_transformer T \ a \ |T f|" using \valid_package_set S f\ valid_package_set_def + by fastforce + moreover have "a' \ |T f'|" + by (metis (no_types, opaque_lifting) \Some a' = a \ (T f' \ T f)\ commutative greater_equiv minus_core minus_equiv_def minus_smaller succ_trans unit_neutral) + ultimately show "a' ## u \ |a'| \ |u| \ mono_transformer T \ a' \ |T f'|" + using \Some a' = a \ (T f' \ T f)\ \a' ## u\ greater_def max_projection_prop_pure_core mpp_mono succ_trans by blast + qed + then have r: "package_rhs_connection \' f' S' pc A \'' f'' S'' \ valid_package_set S'' f''" + by (metis AddFromOutside.hyps(1) AddFromOutside.hyps(3) AddFromOutside.hyps(4) AddFromOutside.hyps(5) AddFromOutside.prems(2) AddFromOutside.prems(3) AddFromOutside.prems(4) AddFromOutside.prems(5) asso1 commutative defined_def stable_sum) + then obtain r2: "\' \ f' = \'' \ f''" "stable f''" "\' ## f'" "f'' \ f'" + "\a u T. (a, u, T) \ S' \ (\au. Some au = a \ u \ (au ## (T f'' \ T f') \ + (\a' u'. (a', u', T) \ S'' \ |a'| \ |a| \ au \ (T f'' \ T f') = a' \ u' \ u' \ u \ package_sat pc A a' u' u)))" + using package_rhs_connection_def by fastforce + + moreover have "package_rhs_connection \ f S pc A \'' f'' S''" + proof (rule package_rhs_connectionI) + show "\ \ f = \'' \ f''" + by (metis AddFromOutside.hyps(1) AddFromOutside.hyps(5) asso1 commutative r2(1)) + show "stable f''" + using AddFromOutside.hyps(4) calculation(4) r2(2) stable_sum by blast + show "\ ## f" + by (simp add: AddFromOutside.prems(5)) + show "f'' \ f" + using AddFromOutside.hyps(5) bigger_sum greater_def r2(4) by blast + + fix a u T + assume asm0: "(a, u, T) \ S" + then obtain au where "Some au = a \ u" using \valid_package_set S f\ valid_package_set_def defined_def + by fastforce + moreover have "au ## (T f'' \ T f) \ (\a' u'. (a', u', T) \ S'' \ |a'| \ |a| \ au \ (T f'' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u)" + proof - + assume asm1: "au ## (T f'' \ T f)" + moreover have "mono_transformer T" using \valid_package_set S f\ valid_package_set_def asm0 + by fastforce + then have "Some (T f'' \ T f) = (T f'' \ T f') \ (T f' \ T f)" + by (metis AddFromOutside.hyps(5) commutative greater_equiv minus_and_plus minus_equiv_def mono_transformer_def r2(4)) + ultimately have "a ## (T f' \ T f)" + using \Some au = a \ u\ asso2 commutative defined_def minus_exists + by metis + then obtain a' where "Some a' = a \ (T f' \ T f)" + by (meson defined_def option.collapse) + moreover have "a' ## u" + proof - + have "T f'' \ T f \ T f' \ T f" + using \Some (T f'' \ T f) = T f'' \ T f' \ (T f' \ T f)\ greater_equiv by blast + then show ?thesis + using \Some au = a \ u\ asm1 asso1[of u a au "T f' \ T f" a'] asso2[of ] calculation commutative + defined_def[of ] greater_equiv[of "T f'' \ T f" "T f' \ T f"] + by metis + qed + + ultimately have "(a', u, T) \ S'" + using AddFromOutside.hyps(6) asm0 by blast + + moreover have "au ## (T f'' \ T f')" + by (metis \Some (T f'' \ T f) = T f'' \ T f' \ (T f' \ T f)\ asm1 asso3 defined_def) + + then have "\au. Some au = a' \ u \ (au ## (T f'' \ T f') \ (\a'a u'. (a'a, u', T) \ S'' \ |a'a| \ |a'| \ au \ (T f'' \ T f') = a'a \ u' \ u' \ u \ package_sat pc A a'a u' u))" + using r2(5) calculation by blast + + then obtain au' a'' u' where r3: "Some au' = a' \ u" "au' ## (T f'' \ T f') \ (a'', u', T) \ S'' \ |a''| \ |a'| \ au' \ (T f'' \ T f') = a'' \ u' \ u' \ u \ package_sat pc A a'' u' u" + using \au ## (T f'' \ T f')\ by blast + moreover have "au' ## (T f'' \ T f')" using \au ## (T f'' \ T f)\ \Some au = a \ u\ r3(1) + \Some (T f'' \ T f) = (T f'' \ T f') \ (T f' \ T f)\ + \Some a' = a \ (T f' \ T f)\ asso1[of u a au "T f' \ T f" a'] commutative defined_sum_move[of au "T f'' \ T f"] + by metis + ultimately have r4: "(a'', u', T) \ S'' \ |a''| \ |a'| \ au' \ (T f'' \ T f') = a'' \ u' \ u' \ u \ package_sat pc A a'' u' u" + by blast + moreover have "|a''| \ |a|" + proof - + have "|a'| \ |a|" + using \Some a' = a \ (T f' \ T f)\ core_sum greater_def by blast + then show ?thesis + using r4 succ_trans by blast + qed + ultimately show "\a' u'. (a', u', T) \ S'' \ |a'| \ |a| \ au \ (T f'' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u" + using \Some (T f'' \ T f) = T f'' \ T f' \ (T f' \ T f)\ \Some a' = a \ (T f' \ T f)\ \Some au = a \ u\ + commutative r3(1) asso1 splus.simps(3) splus_asso by metis + qed + ultimately show "\au. Some au = a \ u \ (au ## (T f'' \ T f) \ (\a' u'. (a', u', T) \ S'' \ |a'| \ |a| \ au \ (T f'' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u))" + by blast + qed + ultimately show ?case using r by blast +qed + +lemma unit_core: + "|unit| = unit" + by (meson core_is_pure max_projection_prop_pure_core sep_algebra.cancellative sep_algebra.mpp_invo sep_algebra_axioms unit_neutral) + +lemma unit_smaller: + "\ \ unit" + using greater_equiv unit_neutral by auto + + +subsection \Lemmas for completeness\ + +lemma sat_star_exists_bigger: + assumes "sat (AStar A B) \" + and "wf_assertion A" + and "wf_assertion B" + shows "\a b. |a| \ |\| \ |b| \ |\| \ Some \ = a \ b \ sat A a \ sat B b" +proof - + obtain a b where "Some \ = a \ b \ sat A a \ sat B b" + using assms sat.simps(1) by blast + then obtain a' b' where "Some a' = a \ |\|" "Some b' = b \ |\|" + by (meson defined_def greater_def greater_equiv option.collapse smaller_compatible_core) + then have "a' \ a \ b' \ b" + using greater_def by blast + then have "sat A a' \ sat B b'" + using \Some \ = a \ b \ sat A a \ sat B b\ \Some a' = a \ |\|\ \Some b' = b \ |\|\ assms(2) assms(3) core_is_pure pure_def wf_assertion_sat_larger_pure by blast + moreover have "Some \ = a' \ b'" + by (metis (no_types, lifting) \Some \ = a \ b \ sat A a \ sat B b\ \Some a' = a \ |\|\ \Some b' = b \ |\|\ asso1 commutative core_is_smaller) + ultimately show ?thesis + by (metis \Some \ = a \ b \ sat A a \ sat B b\ \Some a' = a \ |\|\ \Some b' = b \ |\|\ commutative greater_def smaller_than_core succ_refl) +qed + +lemma let_pair_instantiate: + assumes "(a, b) = f x y" + shows "(let (a, b) = f x y in g a b) = g a b" + by (metis assms case_prod_conv) + + +lemma greater_than_sum_exists: + assumes "a \ b" + and "Some b = b1 \ b2" + shows "\r. Some a = r \ b2 \ |r| \ |a| \ r \ b1" +proof - + obtain r where "Some a = r \ b2 \ r \ b1" + by (metis assms(1) assms(2) bigger_sum commutative) + then obtain r' where "Some r' = r \ |a|" + by (metis defined_def greater_def option.exhaust smaller_compatible_core) + then have "Some a = r' \ b2" + by (metis \Some a = r \ b2 \ r \ b1\ commutative core_is_smaller sep_algebra.asso1 sep_algebra_axioms) + then show ?thesis + by (metis \Some a = r \ b2 \ r \ b1\ \Some r' = r \ |a|\ core_is_pure greater_def smaller_than_core succ_trans) +qed + +lemma bigger_the: + assumes "Some a = x' \ y" + and "x' \ x" + shows "the ( |a| \ x') \ the ( |a| \ x)" +proof - + have "a \ x'" + using assms(1) greater_def by blast + then have "|a| ## x'" + using commutative defined_def smaller_compatible_core by auto + moreover have "|a| ## x" + by (metis assms(2) calculation defined_def sep_algebra.asso3 sep_algebra.minus_exists sep_algebra_axioms) + ultimately show ?thesis + using addition_bigger assms(2) commutative defined_def by force +qed + +lemma wf_assertion_and_the: + assumes "|a| ## b" + and "sat A b" + and "wf_assertion A" + shows "sat A (the ( |a| \ b))" + by (metis assms(1) assms(2) assms(3) commutative defined_def max_projection_prop_pure_core option.collapse sep_algebra.mpp_prop sep_algebra_axioms wf_assertion_sat_larger_pure) + +lemma minus_some: + assumes "a \ b" + shows "Some a = b \ (a \ b)" + using assms commutative minus_equiv_def by force + +lemma core_mono: + assumes "a \ b" + shows "|a| \ |b|" + using assms max_projection_prop_pure_core mpp_mono by auto + +lemma prove_last_completeness: + assumes "a' \ a" + and "Some a = nf1 \ f2" + shows "a' \ nf1 \ f2" + by (meson assms(1) assms(2) greater_def greater_minus_trans minus_bigger succ_trans) + +lemma completeness_aux: + assumes "\a u T. (a, u, T) \ S \ |f1 a u T| \ |a| \ Some a = f1 a u T \ f2 a u T \ (pc |a| \ sat A (the ( |a| \ (f1 a u T))))" + and "valid_package_set S f" + and "wf_assertion A" + and "mono_pure_cond pc" + and "stable f \ \ ## f" + shows "\S'. package_rhs \ f S pc A \ f S' \ (\(a', u', T) \ S'. \a u. (a, u, T) \ S \ a' \ f2 a u T \ |a'| = |a| )" + using assms +proof (induct A arbitrary: S pc f1 f2) + case (AImp b A) + let ?pc = "bool_conj pc b" + + have "\S'. package_rhs \ f S (bool_conj pc b) A \ f S' \ (\a\S'. case a of (a', u', T) \ \a u. (a, u, T) \ S \ a' \ f2 a u T \ |a'| = |a| )" + proof (rule AImp(1)) + show "valid_package_set S f" + by (simp add: AImp.prems(2)) + show "wf_assertion A" using AImp.prems(3) by auto + show "mono_pure_cond (bool_conj pc b)" + by (meson AImp.prems(3) AImp.prems(4) mono_pure_cond_conj wf_assertion.simps(2)) + show "stable f \ \ ## f" using \stable f \ \ ## f\ by simp + + fix a u T + assume asm0: "(a, u, T) \ S" + then have "Some a = f1 a u T \ f2 a u T" + using AImp.prems(1) by blast + moreover have "bool_conj pc b |a| \ sat A (the ( |a| \ f1 a u T))" + proof - + assume "bool_conj pc b |a|" + then have "pc |a|" + by (meson bool_conj_def) + then have "|f1 a u T| \ |a| \ Some a = f1 a u T \ f2 a u T \ sat (AImp b A) (the ( |a| \ f1 a u T))" + using AImp.prems(1) asm0(1) by blast + moreover have "b (the ( |a| \ f1 a u T))" + proof - + have "|a| ## f1 a u T \ |a| \ |f1 a u T|" + by (metis calculation commutative core_is_smaller defined_def greater_def max_projection_prop_pure_core mpp_mono option.discI succ_antisym) + then obtain x where "Some x = |a| \ f1 a u T" + by (meson defined_def option.collapse) + then have "|x| = |a|" + by (metis \Some x = |a| \ f1 a u T\ \|a| ## f1 a u T \ |a| \ |f1 a u T|\ commutative core_is_pure core_sum max_projection_prop_pure_core mpp_smaller smaller_than_core) + then show ?thesis + by (metis AImp.prems(3) \Some x = |a| \ f1 a u T\ \bool_conj pc b |a|\ bool_conj_def mono_pure_cond_def option.sel wf_assertion.simps(2)) + qed + ultimately show "sat A (the ( |a| \ f1 a u T))" by (metis sat.simps(2)) + qed + ultimately show "|f1 a u T| \ |a| \ Some a = f1 a u T \ f2 a u T \ (bool_conj pc b |a| \ sat A (the ( |a| \ f1 a u T)))" + by (metis AImp.prems(1) asm0) + qed + then obtain S' where r: "package_rhs \ f S (bool_conj pc b) A \ f S'" "\a' u' T. (a', u', T) \ S' \ (\a u. (a, u, T) \ S \ a' \ f2 a u T)" + by fast + moreover have "package_rhs \ f S pc (AImp b A) \ f S'" + by (simp add: package_rhs.AImp r(1)) + ultimately show ?case + using \\S'. package_rhs \ f S (bool_conj pc b) A \ f S' \ (\a\S'. case a of (a', u', T) \ \a u. (a, u, T) \ S \ a' \ f2 a u T \ |a'| = |a| )\ package_rhs.AImp by blast +next + case (ASem A) + let ?witness = "\(a, u, T). the ( |a| \ f1 a u T)" + + obtain S' where S'_def: "S' = { (a, u, T) |a u T. (a, u, T) \ S \ \ pc a } + \ { (a \ b, the (u \ b), T) |a u T b. (a, u, T) \ S \ pc a \ b = ?witness (a, u, T) }" + by blast + + have "package_rhs \ f S pc (ASem A) \ f S'" + proof (rule package_rhs.ASem) + show "S' = {(a, u, T) |a u T. (a, u, T) \ S \ \ pc a} \ {(a \ b, the (u \ b), T) |a u T b. (a, u, T) \ S \ pc a \ b = ?witness (a, u, T)}" + using S'_def by blast + fix a u T b + assume asm0: "(a, u, T) \ S" "pc a" "b = (case (a, u, T) of (a, u, T) \ the ( |a| \ f1 a u T))" + then have "b = the ( |a| \ f1 a u T)" by fastforce + moreover have "pc |a|" + by (meson ASem.prems(4) asm0(2) mono_pure_cond_def) + then have "|f1 a u T| \ |a| \ Some a = f1 a u T \ f2 a u T \ sat (ASem A) (the ( |a| \ f1 a u T))" + using ASem.prems(1) asm0(1) by blast + then have "Some b = |a| \ f1 a u T" by (metis calculation commutative defined_def minus_bigger minus_core option.exhaust_sel smaller_compatible_core) + moreover have "a \ b" + proof - + have "a \ f1 a u T" + using \|f1 a u T| \ |a| \ Some a = f1 a u T \ f2 a u T \ sat (ASem A) (the ( |a| \ f1 a u T))\ asso1 calculation(2) commutative core_is_smaller greater_def by metis + then show ?thesis + by (metis calculation(2) commutative max_projection_prop_pure_core mpp_smaller sep_algebra.mpp_prop sep_algebra_axioms smaller_pure_sum_smaller) + qed + ultimately show "a \ b \ A b" + using \|f1 a u T| \ |a| \ Some a = f1 a u T \ f2 a u T \ sat (ASem A) (the ( |a| \ f1 a u T))\ commutative greater_def max_projection_prop_def max_projection_prop_pure_core sat.simps(3) smaller_pure_sum_smaller + by metis + qed + + moreover have "\a' u' T. (a', u', T) \ S' \ (\a u. (a, u, T) \ S \ a' \ f2 a u T \ |a'| = |a| )" + proof - + fix a' u' T assume asm0: "(a', u', T) \ S'" + then show "\a u. (a, u, T) \ S \ a' \ f2 a u T \ |a'| = |a| " + proof (cases "(a', u', T) \ {(a, u, T) |a u T. (a, u, T) \ S \ \ pc a}") + case True + then show ?thesis using ASem.prems(1) greater_equiv by fastforce + next + case False + then have "(a', u', T) \ { (a \ b, the (u \ b), T) |a u T b. (a, u, T) \ S \ pc a \ b = ?witness (a, u, T) }" + using S'_def asm0 by blast + then obtain a u b where "a' = a \ b" "u' = the (u \ b)" "(a, u, T) \ S" "pc a" "b = ?witness (a, u, T)" + by blast + then have "a' \ f2 a u T" + proof - + have "a \ b" + proof - + have "a \ f1 a u T" + using ASem.prems(1) \(a, u, T) \ S\ greater_def by blast + moreover have "Some b = |a| \ f1 a u T" + by (metis \b = (case (a, u, T) of (a, u, T) \ the ( |a| \ f1 a u T))\ calculation case_prod_conv commutative defined_def option.exhaust_sel smaller_compatible_core) + ultimately show ?thesis + by (metis commutative max_projection_prop_pure_core mpp_smaller sep_algebra.mpp_prop sep_algebra_axioms smaller_pure_sum_smaller) + qed + then show ?thesis + using ASem.prems(1)[of a u T] + \(a, u, T) \ S\ \a' = a \ b\ \b = (case (a, u, T) of (a, u, T) \ the ( |a| \ f1 a u T))\ + commutative core_is_smaller minus_bigger option.exhaust_sel option.simps(3) + asso1[of "f2 a u T" "f1 a u T" a "|a|" "the ( |a| \ f1 a u T)"] asso2[of "f2 a u T" "f1 a u T"] + split_conv + by metis + qed + then show ?thesis + using \(a, u, T) \ S\ \a' = a \ b\ minus_core by blast + qed + qed + + ultimately show ?case by blast +next + case (AStar A B) + + let ?fA = "\a u T. SOME x. \y. Some (f1 a u T) = x \ y \ |x| \ |f1 a u T| \ |y| \ |a| \ (pc |a| \ sat A (the ( |a| \ x)) \ sat B (the ( |a| \ y)))" + let ?fB = "\a u T. SOME y. Some (f1 a u T) = ?fA a u T \ y \ |y| \ |a| \ (pc |a| \ sat B (the ( |a| \ y)))" + let ?f2 = "\a u T. the (?fB a u T \ f2 a u T)" + + have r: "\a u T. (a, u, T) \ S \ Some (f1 a u T) = ?fA a u T \ ?fB a u T \ |?fA a u T| \ |f1 a u T| \ |?fB a u T| \ |a| \ (pc |a| \ sat A (the ( |a| \ ?fA a u T)) \ sat B (the ( |a| \ ?fB a u T))) + \ Some (?f2 a u T) = ?fB a u T \ f2 a u T" + proof - + fix a u T assume asm0: "(a, u, T) \ S" + then have "Some a = f1 a u T \ f2 a u T \ (pc |a| \ sat (AStar A B) (the ( |a| \ f1 a u T)))" + using AStar.prems(1) by blast + then have "\x y. Some (the ( |a| \ f1 a u T )) = x \ y \ (pc |a| \ sat A x) \ (pc |a| \ sat B y) \ + x \ |(the ( |a| \ f1 a u T))| \ y \ |(the ( |a| \ f1 a u T))|" + proof (cases "pc |a|") + case True + then show ?thesis + using AStar.prems(3) \Some a = f1 a u T \ f2 a u T \ (pc |a| \ sat (AStar A B) (the ( |a| \ f1 a u T)))\ + max_projection_prop_def[of pure core] max_projection_prop_pure_core + sat_star_exists_bigger[of A B "(the ( |a| \ f1 a u T))"] + succ_trans[of ] wf_assertion.simps(1)[of A B] + by blast + next + case False + then have "Some (the ( |a| \ f1 a u T )) = the ( |a| \ f1 a u T) \ |the ( |a| \ f1 a u T )|" + by (simp add: core_is_smaller) + then show ?thesis by (metis False max_projection_prop_pure_core mpp_smaller succ_refl) + qed + then obtain x y where "Some (the ( |a| \ f1 a u T)) = x \ y" "pc |a| \ sat A x" "pc |a| \ sat B y" + "x \ |(the ( |a| \ f1 a u T))|" "y \ |(the ( |a| \ f1 a u T))|" by blast + moreover obtain af where "Some af = |a| \ f1 a u T" + by (metis \Some a = f1 a u T \ f2 a u T \ (pc |a| \ sat (AStar A B) (the ( |a| \ f1 a u T)))\ commutative defined_def minus_bigger minus_core option.exhaust_sel smaller_compatible_core) + ultimately have "Some (f1 a u T) = x \ y" + by (metis AStar.prems(1) \Some a = f1 a u T \ f2 a u T \ (pc |a| \ sat (AStar A B) (the ( |a| \ f1 a u T)))\ asm0 commutative core_is_smaller greater_def max_projection_prop_pure_core mpp_mono option.sel succ_antisym) + moreover have "|a| ## x \ |a| ## y" + by (metis \Some af = |a| \ f1 a u T\ calculation commutative defined_def option.discI sep_algebra.asso3 sep_algebra_axioms) + then have "the ( |a| \ x) \ x \ the ( |a| \ y) \ y" + using commutative defined_def greater_def by auto + + ultimately have "pc |a| \ sat A (the ( |a| \ x)) \ sat B (the ( |a| \ y))" + by (metis AStar.prems(3) \pc |a| \ sat A x\ \pc |a| \ sat B y\ \|a| ## x \ |a| ## y\ commutative defined_def max_projection_prop_pure_core option.exhaust_sel package_logic.wf_assertion.simps(1) package_logic_axioms sep_algebra.mpp_prop sep_algebra_axioms wf_assertion_sat_larger_pure) + + have "\y. Some (f1 a u T) = ?fA a u T \ y \ |?fA a u T| \ |f1 a u T| \ |y| \ |a| \ (pc |a| \ sat A (the ( |a| \ ?fA a u T)) \ sat B (the ( |a| \ y)))" + proof (rule someI_ex) + show "\x y. Some (f1 a u T) = x \ y \ |x| \ |f1 a u T| \ |y| \ |a| \ (pc |a| \ sat A (the ( |a| \ x)) \ sat B (the ( |a| \ y)))" + using \Some (f1 a u T) = x \ y\ \Some (the ( |a| \ f1 a u T)) = x \ y\ \pc |a| \ sat A (the ( |a| \ x)) \ sat B (the ( |a| \ y))\ \x \ |the ( |a| \ f1 a u T)|\ \y \ |the ( |a| \ f1 a u T)|\ core_is_pure max_projection_propE(3) max_projection_prop_pure_core option.sel pure_def + by (metis AStar.prems(1) asm0 minusI minus_core) + qed + then obtain yy where "Some (f1 a u T) = ?fA a u T \ yy \ |?fA a u T| \ |f1 a u T| \ |yy| \ |a| \ (pc |a| \ sat A (the ( |a| \ ?fA a u T)) \ sat B (the ( |a| \ yy)))" + by blast + moreover have "Some (f1 a u T) = ?fA a u T \ ?fB a u T \ |?fB a u T| \ |a| \ (pc |a| \ sat B (the ( |a| \ ?fB a u T)))" + proof (rule someI_ex) + show "\y. Some (f1 a u T) = ?fA a u T \ y \ |y| \ |a| \ (pc |a| \ sat B (the ( |a| \ y)))" + using \\y. Some (f1 a u T) = ?fA a u T \ y \ |?fA a u T| \ |f1 a u T| \ |y| \ |a| \ (pc |a| \ sat A (the ( |a| \ ?fA a u T)) \ sat B (the ( |a| \ y)))\ + by blast + qed + ultimately have "?fB a u T \ f2 a u T \ None" + using \Some a = f1 a u T \ f2 a u T \ (pc |a| \ sat (AStar A B) (the ( |a| \ f1 a u T)))\ + option.distinct(1) [of ] option.exhaust_sel[of "?fB a u T \ f2 a u T"] asso2[of "?fA a u T" "?fB a u T" "f1 a u T" "f2 a u T"] + by metis + then show "Some (f1 a u T) = ?fA a u T \ ?fB a u T \ |?fA a u T| \ |f1 a u T| \ |?fB a u T| \ |a| \ (pc |a| \ sat A (the ( |a| \ ?fA a u T)) \ sat B (the ( |a| \ ?fB a u T))) +\ Some (?f2 a u T) = ?fB a u T \ f2 a u T" + using \Some a = f1 a u T \ f2 a u T \ (pc |a| \ sat (AStar A B) (the ( |a| \ f1 a u T)))\ + option.distinct(1) option.exhaust_sel[of "?fB a u T \ f2 a u T"] asso2[of "?fA a u T" "?fB a u T" "f1 a u T" "f2 a u T"] +\Some (f1 a u T) = ?fA a u T \ ?fB a u T \ |?fB a u T| \ |a| \ (pc |a| \ sat B (the ( |a| \ ?fB a u T)))\ +\Some (f1 a u T) = ?fA a u T \ yy \ |?fA a u T| \ |f1 a u T| \ |yy| \ |a| \ (pc |a| \ sat A (the ( |a| \ ?fA a u T)) \ sat B (the ( |a| \ yy)))\ + by simp + qed + have ih1: "\S'. package_rhs \ f S pc A \ f S' \ (\a\S'. case a of (a', u', T) \ \a u. (a, u, T) \ S \ a' \ ?f2 a u T \ |a'| = |a| )" + proof (rule AStar(1)) + show "valid_package_set S f" + by (simp add: AStar.prems(2)) + show "wf_assertion A" + using AStar.prems(3) by auto + show "mono_pure_cond pc" + by (simp add: AStar.prems(4)) + show "stable f \ \ ## f" using \stable f \ \ ## f\ by simp + + fix a u T + assume asm0: "(a, u, T) \ S" + then have b: "Some (f1 a u T) = ?fA a u T \ ?fB a u T \ |?fA a u T| \ |f1 a u T| \ |?fB a u T| \ |a| \ (pc |a| \ sat A (the ( |a| \ ?fA a u T)) \ sat B (the ( |a| \ ?fB a u T)))" + using r by fast + show "|?fA a u T| \ |a| \ Some a = ?fA a u T \ ?f2 a u T \ (pc |a| \ sat A (the ( |a| \ ?fA a u T)))" + proof - + have "|?fA a u T| \ |a|" + using AStar.prems(1)[of a u T] asm0 b asso1[of "?fA a u T" "?fB a u T" "f1 a u T" ] + asso2[of "?fA a u T" "?fB a u T" ] option.sel succ_trans[of "|?fA a u T|" _ "|a|"] + by blast + moreover have "Some a = ?fA a u T \ ?f2 a u T" + using AStar.prems(1)[of a u T] asm0 b asso1[of "?fA a u T" "?fB a u T" "f1 a u T" "f2 a u T" "?f2 a u T"] + asso2[of "?fA a u T" "?fB a u T" "f1 a u T" "f2 a u T"] option.sel + option.exhaust_sel[of "?fB a u T \ f2 a u T" "Some a = ?fA a u T \ ?f2 a u T"] + by force + moreover have "pc |a| \ sat A (the ( |a| \ ?fA a u T))" + using AStar.prems(1)[of a u T] asm0 b + asso2[of "?fA a u T" "?fB a u T" ] option.sel succ_trans[of "|?fA a u T|" _ "|a|"] + by blast + ultimately show ?thesis + by blast + qed + qed + then obtain S' where r': "package_rhs \ f S pc A \ f S'" "\a' u' T. (a', u', T) \ S' \ \a u. (a, u, T) \ S \ a' \ ?f2 a u T \ |a'| = |a| " + by fast + + let ?project = "\a' T. (SOME r. \a u. r = (a, u) \ (a, u, T) \ S \ a' \ ?f2 a u T \ |a'| = |a| )" + have project_prop: "\a' u' T. (a', u', T) \ S' \ \a u. ?project a' T = (a, u) \ (a, u, T) \ S \ a' \ ?f2 a u T \ |a'| = |a| " + proof - + fix a' u' T assume "(a', u', T) \ S'" + then obtain a u where "(a, u, T) \ S \ a' \ ?f2 a u T \ |a'| = |a| " + using \\a' u' p. (a', u', T) \ S' \ \a u. (a, u, T) \ S \ a' \ ?f2 a u T \ |a'| = |a| \ by blast + show "\a u. ?project a' T = (a, u) \ (a, u, T) \ S \ a' \ ?f2 a u T \ |a'| = |a| " + proof (rule someI_ex) + show "\r a u. r = (a, u) \ (a, u, T) \ S \ a' \ ?f2 a u T \ |a'| = |a| " using \(a, u, T) \ S \ a' \ ?f2 a u T \ |a'| = |a| \ by blast + qed + qed + + let ?nf1 = "\a' u' T. let (a, u) = ?project a' T in (SOME r. Some r = |a'| \ ?fB a u T)" + let ?nf2 = "\a' u' T. a' \ ?nf1 a' u' T" + + have "\S''. package_rhs \ f S' pc B \ f S'' \ (\a\S''. case a of (a', u', T) \ \a u. (a, u, T) \ S' \ a' \ ?nf2 a u T \ |a'| = |a| )" + proof (rule AStar(2)) + show "stable f \ \ ## f" using \stable f \ \ ## f\ by simp + + then show "valid_package_set S' f" + using AStar.prems \package_rhs \ f S pc A \ f S'\ package_logic.package_rhs_proof package_logic.wf_assertion.simps(1) package_logic_axioms + by metis + show "wf_assertion B" + using AStar.prems(3) by auto + show "mono_pure_cond pc" + by (simp add: AStar.prems(4)) + fix a' u' T assume "(a', u', T) \ S'" + then obtain a u where a_u_def: "(a, u) = ?project a' T" "(a, u, T) \ S" "a' \ ?f2 a u T" "|a'| = |a|" + using project_prop by force + define nf1 where "nf1 = ?nf1 a' u' T" + define nf2 where "nf2 = ?nf2 a' u' T" + moreover have rnf1_def: "Some nf1 = |a'| \ ?fB a u T" + proof - + let ?x = "(SOME r. Some r = |a'| \ ?fB a u T )" + have "Some ?x = |a'| \ ?fB a u T" + proof (rule someI_ex) + have "Some (f1 a u T) = ?fA a u T \ ?fB a u T \ |?fA a u T| \ |f1 a u T| \ |?fB a u T| \ |a| + \ (pc |a| \ sat A (the ( |a| \ ?fA a u T)) \ sat B (the ( |a| \ ?fB a u T)))" + using r a_u_def by blast + then have "Some (?f2 a u T) = ?fB a u T \ f2 a u T" + by (metis (no_types, lifting) AStar.prems(1) a_u_def(2) asso2 option.distinct(1) option.exhaust_sel) + moreover have "a' \ (?f2 a u T)" using \a' \ ?f2 a u T\ by blast + ultimately have "a' \ ?fB a u T" using succ_trans greater_def + by blast + then obtain r where "Some r = |a'| \ ?fB a u T" + using + commutative + greater_equiv[of a' "?fB a u T"] + minus_equiv_def_any_elem[of a'] + by fastforce + then show "\r. Some r = |a'| \ ?fB a u T" by blast + qed + moreover have "?nf1 a' u' T = ?x" + using let_pair_instantiate[of a u _ a' T "\a u. (SOME r. Some r = |a'| \ ?fB a u T )"] a_u_def + by fast + ultimately show ?thesis using nf1_def by argo + qed + + moreover have rnf2_def: "Some a' = nf1 \ nf2" + proof - + have "nf2 = a' \ nf1" using nf1_def nf2_def by blast + moreover have "a' \ nf1" + proof - + have "?f2 a u T \ nf1" + proof - + have "Some (?f2 a u T) = ?fB a u T \ f2 a u T" using r \(a, u, T) \ S\ by blast + then have "?f2 a u T \ ?fB a u T" + using greater_def by blast + moreover have "?f2 a u T \ |a'|" + proof - + have "|?f2 a u T| \ |a|" + proof - + have "|?f2 a u T| \ |?fB a u T|" using \?f2 a u T \ ?fB a u T\ core_mono by blast + moreover have "|?fB a u T| \ |a|" using r \(a, u, T) \ S\ by blast + ultimately show ?thesis using succ_trans \|a'| = |a|\ by blast + qed + then show ?thesis + using a_u_def(4) + bigger_core_sum_defined[of "?f2 a u T"] + greater_equiv[of _ "|a|"] + by auto + qed + ultimately show ?thesis using + core_is_pure[of a'] commutative pure_def[of "|a'|"] smaller_pure_sum_smaller[of _ _ "|a'|"] rnf1_def + by (metis (no_types, lifting)) + qed + then show ?thesis using \a' \ ?f2 a u T\ succ_trans by blast + qed + ultimately show ?thesis using minus_some nf2_def by blast + qed + + moreover have "pc |a'| \ sat B (the ( |a'| \ ?nf1 a' u' T))" + proof - + assume "pc |a'|" + moreover have "|a'| = |a|" + by (simp add: a_u_def(4)) + then have "pc |a|" using \pc |a'|\ by simp + ultimately have "sat B (the ( |a| \ ?fB a u T))" + using r a_u_def by blast + then have "sat B (the ( |a'| \ ?fB a u T))" using \|a'| = |a|\ by simp + + then show "sat B (the ( |a'| \ ?nf1 a' u' T))" + proof - + have "nf1 \ |a'|" using rnf1_def + using greater_def by blast + then have "Some nf1 = |a'| \ nf1" + by (metis bigger_core_sum_defined commutative core_mono max_projection_prop_pure_core mpp_invo) + then show ?thesis using nf1_def rnf1_def \sat B (the ( |a'| \ ?fB a u T))\ by argo + qed + qed + moreover have "|?nf1 a' u' T| \ |a'|" + proof - + have "?nf1 a' u' T \ |a'|" using nf1_def greater_def rnf1_def by blast + then show ?thesis + using max_projection_propE(3) max_projection_prop_pure_core sep_algebra.mpp_prop sep_algebra_axioms by fastforce + qed + ultimately show "|?nf1 a' u' T| \ |a'| \ Some a' = ?nf1 a' u' T \ ?nf2 a' u' T \ (pc |a'| \ sat B (the ( |a'| \ ?nf1 a' u' T)))" + using nf1_def + by blast + qed + + then obtain S'' where "package_rhs \ f S' pc B \ f S''" "\a' u' T. (a', u', T) \ S'' \ \a u. (a, u, T) \ S' \ a' \ ?nf2 a u T \ |a'| = |a| " + by fast + + then have "package_rhs \ f S pc (AStar A B) \ f S''" + using \package_rhs \ f S pc A \ f S'\ package_rhs.AStar by presburger + moreover have "\a'' u'' T. (a'', u'', T) \ S'' \ \a u. (a, u, T) \ S \ a'' \ f2 a u T \ |a''| = |a|" + proof - + fix a'' u'' T assume asm0: "(a'', u'', T) \ S''" + + + then obtain a' u' where "(a', u', T) \ S' \ a'' \ ?nf2 a' u' T \ |a''| = |a'| " + using \\a' u' p. (a', u', T) \ S'' \ \a u. (a, u, T) \ S' \ a' \ ?nf2 a u T \ |a'| = |a| \ by blast + + then obtain a u where a_u_def: "(a, u) = ?project a' T" "(a, u, T) \ S" "a' \ ?f2 a u T" "|a'| = |a|" + using project_prop by force + + define nf1 where "nf1 = ?nf1 a' u' T" + define nf2 where "nf2 = ?nf2 a' u' T" + + moreover have rnf1_def: "Some nf1 = |a'| \ ?fB a u T" + proof - + let ?x = "(SOME r. Some r = |a'| \ ?fB a u T )" + have "Some ?x = |a'| \ ?fB a u T" + proof (rule someI_ex) + have "Some (f1 a u T) = ?fA a u T \ ?fB a u T \ |?fA a u T| \ |f1 a u T| \ |?fB a u T| \ |a| + \ (pc |a| \ sat A (the ( |a| \ ?fA a u T)) \ sat B (the ( |a| \ ?fB a u T)))" + using r a_u_def by blast + then have "Some (?f2 a u T) = ?fB a u T \ f2 a u T" + by (metis (no_types, lifting) AStar.prems(1) a_u_def(2) asso2 option.distinct(1) option.exhaust_sel) + moreover have "a' \ (?f2 a u T)" using \a' \ ?f2 a u T\ by blast + ultimately have "a' \ ?fB a u T" using succ_trans greater_def + by blast + then obtain r where "Some r = |a'| \ ?fB a u T" + using commutative greater_equiv[of a' "?fB a u T"] minus_equiv_def_any_elem[of a' ] by fastforce + then show "\r. Some r = |a'| \ ?fB a u T" by blast + qed + moreover have "?nf1 a' u' T = ?x" + using let_pair_instantiate[of a u _ a' T "\a u. (SOME r. Some r = |a'| \ ?fB a u T )"] a_u_def + by fast + ultimately show ?thesis using nf1_def by argo + qed + + moreover have rnf2_def: "a' \ nf1 \ ?nf2 a' u' T \ f2 a u T" + proof - + have "nf2 = a' \ nf1" using nf1_def nf2_def by blast + moreover have "a' \ nf1 \ a' \ nf1 \ f2 a u T" + proof - + have "?f2 a u T \ nf1" + proof - + have "Some (?f2 a u T) = ?fB a u T \ f2 a u T" using r \(a, u, T) \ S\ by blast + then have "?f2 a u T \ ?fB a u T" + using greater_def by blast + moreover have "?f2 a u T \ |a'|" + proof - + have "|?f2 a u T| \ |a|" + proof - + have "|?f2 a u T| \ |?fB a u T|" using \?f2 a u T \ ?fB a u T\ core_mono by blast + moreover have "|?fB a u T| \ |a|" using r \(a, u, T) \ S\ by blast + ultimately show ?thesis using succ_trans \|a'| = |a|\ by blast + qed + then show ?thesis + using a_u_def(4) + bigger_core_sum_defined + greater_equiv[of "?f2 a u T" "|a'|"] + by auto + qed + ultimately show ?thesis using + core_is_pure[of "a'"] commutative pure_def[of "|a'|"] smaller_pure_sum_smaller[of "?f2 a u T" _ "|a'|"] rnf1_def + by simp + qed + then have r1: "a' \ nf1" using \a' \ ?f2 a u T\ succ_trans by blast + then have "Some a' = nf1 \ nf2" using minus_some nf2_def \nf2 = a' \ nf1\ by presburger + have r2: "a' \ nf1 \ f2 a u T" + using \a' \ ?f2 a u T\ + proof (rule prove_last_completeness) + + have "Some (?f2 a u T) = ?fB a u T \ f2 a u T" + using r \(a, u, T) \ S\ by blast + moreover have "Some nf1 = |a'| \ ?fB a u T" using rnf1_def by blast + + have "Some (?f2 a u T) = ?fB a u T \ f2 a u T" using r \(a, u, T) \ S\ by blast + then have "?f2 a u T \ ?fB a u T" + using greater_def by blast + moreover have "?f2 a u T \ |a'|" + proof - + have "|?f2 a u T| \ |a|" + proof - + have "|?f2 a u T| \ |?fB a u T|" using \?f2 a u T \ ?fB a u T\ core_mono by blast + moreover have "|?fB a u T| \ |a|" using r \(a, u, T) \ S\ by blast + ultimately show ?thesis using succ_trans \|a'| = |a|\ by blast + qed + then show ?thesis + using a_u_def(4) + bigger_core_sum_defined[of _ "|a|"] + greater_equiv[of "?f2 a u T" "|a|"] + by auto + qed + ultimately show "Some (?f2 a u T) = nf1 \ f2 a u T" + using asso1[of "|a'|" "?fB a u T" nf1 "f2 a u T" "?f2 a u T"] + asso1[of "|a'|" "|a'|" "|a'|" ] core_is_pure[of "a'"] greater_def[of "?f2 a u T" "|a'|"] rnf1_def + by (metis (no_types, lifting)) + qed + then show ?thesis using \a' \ ?f2 a u T\ succ_trans using r1 by force + qed + ultimately show ?thesis using nf2_def by argo + qed + ultimately have "(a, u, T) \ S \ a' \ ?f2 a u T \ ?nf2 a' u' T \ f2 a u T" using nf1_def nf2_def + a_u_def by blast + then have "a'' \ f2 a u T \ |a''| = |a'| " using \(a', u', T) \ S' \ a'' \ ?nf2 a' u' T \ |a''| = |a'| \ + using succ_trans by blast + then show "\a u. (a, u, T) \ S \ a'' \ f2 a u T \ |a''| = |a| " using r' + using a_u_def(2) a_u_def(4) by auto + qed + ultimately show ?case by blast +qed + + + + + + +subsection Soundness + +theorem general_soundness: + assumes "package_rhs \ unit { (a, unit, T) |a T. (a, T) \ S } (\_. True) A \' f S'" + and "\a T. (a, T) \ S \ mono_transformer T" + and "wf_assertion A" + and "intuitionistic (sat A) \ pure_remains S'" + shows "Some \ = \' \ f \ stable f \ (\(a, T) \ S. a ## T f \ sat A (the (a \ T f)))" +proof - + let ?S = "{ (a, unit, p) |a p. (a, p) \ S }" + let ?pc = "\_. True" + have "package_rhs_connection \ unit ?S ?pc A \' f S' \ valid_package_set S' f" + proof (rule package_rhs_proof) + show "package_rhs \ unit {(a, unit, p) |a p. (a, p) \ S} (\_. True) A \' f S'" + using assms(1) by auto + show "valid_package_set {(a, unit, p) |a p. (a, p) \ S} unit" + proof (rule valid_package_setI) + fix a u T + assume "(a, u, T) \ {(a, unit, p) |a p. (a, p) \ S}" + then have "u = unit" by blast + moreover have "|T unit| = unit" + using \(a, u, T) \ {(a, unit, p) |a p. (a, p) \ S}\ assms(2) mono_transformer_def unit_core by fastforce + then show "a ## u \ |a| \ |u| \ mono_transformer T \ a \ |T unit|" + using \(a, u, T) \ {(a, unit, p) |a p. (a, p) \ S}\ assms(2) defined_def unit_core unit_neutral unit_smaller by auto + qed + show "wf_assertion A" by (simp add: assms(3)) + show "mono_pure_cond (\_. True)" + using mono_pure_cond_def by auto + show "stable unit" by (simp add: stable_unit) + show "\ ## unit" + using defined_def unit_neutral by auto + qed + + then obtain r: "\ \ unit = \' \ f" "stable f" + "\a u T. (a, u, T) \ ?S \ (\au. Some au = a \ u \ (au ## (T f \ T unit) \ + (\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ (T f \ T unit) = a' \ u' \ u' \ u \ package_sat ?pc A a' u' u)))" + using package_rhs_connection_def by force + + moreover have "\a T x. (a, T) \ S \ Some x = a \ T f \ sat A x" + proof - + fix a T x assume asm0: "(a, T) \ S \ Some x = a \ T f" + then have "T f \ T unit = T f" + by (metis assms(2) commutative minus_equiv_def mono_transformer_def option.sel unit_neutral unit_smaller) + then obtain au where "Some au = a \ unit \ (au ## T f \ + (\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ T f = a' \ u' \ u' \ unit \ package_sat ?pc A a' u' unit))" + using r asm0 by fastforce + then have "au = a" by (metis option.inject unit_neutral) + then have "(\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ a \ T f = a' \ u' \ package_sat ?pc A a' u' unit)" + using \Some au = a \ unit \ (au ## T f \ (\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ T f = a' \ u' \ u' \ unit \ package_sat (\_. True) A a' u' unit))\ asm0 defined_def + by auto + then obtain a' u' where "(a', u', T) \ S' \ |a'| \ |a| \ a \ T f = a' \ u' \ package_sat ?pc A a' u' unit" + by presburger + then obtain y where "Some y = |a'| \ (u' \ unit) \ sat A y" + using package_sat_def by auto + then have "Some y = |a'| \ u'" + by (metis commutative minus_equiv_def splus.simps(3) unit_neutral unit_smaller) + then have "x \ y" + by (metis \(a', u', T) \ S' \ |a'| \ |a| \ a \ T f = a' \ u' \ package_sat (\_. True) A a' u' unit\ addition_bigger asm0 max_projection_prop_pure_core mpp_smaller) + then show "sat A x" + proof (cases "intuitionistic (sat A)") + case True + then show ?thesis by (meson \Some y = |a'| \ (u' \ unit) \ sat A y\ \x \ y\ intuitionistic_def) + next + case False + then have "pure_remains S'" using assms(4) by auto + then have "pure a'" using pure_remains_def \(a', u', T) \ S' \ |a'| \ |a| \ a \ T f = a' \ u' \ package_sat (\_. True) A a' u' unit\ + by fast + then show ?thesis using \(a', u', T) \ S' \ |a'| \ |a| \ a \ T f = a' \ u' \ package_sat (\_. True) A a' u' unit\ + \Some y = |a'| \ (u' \ unit) \ sat A y\ \Some y = |a'| \ u'\ asm0 core_is_smaller + core_max option.sel pure_def asso1[of a'] + by metis + qed + qed + then have "(\(a, T) \ S. a ## T f \ sat A (the (a \ T f)))" + using sep_algebra.defined_def sep_algebra_axioms by fastforce + moreover have "Some \ = \' \ f \ stable f" + using r(1) r(2) unit_neutral by auto + ultimately show ?thesis by blast +qed + +theorem soundness: + assumes "wf_assertion B" + and "\a. sat A a \ a \ S" + and "\a. a \ S \ mono_transformer (R a)" + and "package_rhs \ unit { (a, unit, R a) |a. a \ S } (\_. True) B \' w S'" + and "intuitionistic (sat B) \ pure_remains S'" + shows "stable w \ Some \ = \' \ w \ is_footprint_general w R A B" +proof - + let ?S = "{ (a, R a) |a. a \ S} " + have r: "Some \ = \' \ w \ stable w \ (\(a, T)\{(a, R a) |a. a \ S}. a ## T w \ sat B (the (a \ T w)))" + proof (rule general_soundness) + show "package_rhs \ unit {(a, unit, T) |a T. (a, T) \ {(a, R a) |a. a \ S}} (\_. True) B \' w S'" + using assms(4) by auto + show "\a T. (a, T) \ {(a, R a) |a. a \ S} \ mono_transformer T" using assms(3) by blast + show "wf_assertion B" by (simp add: assms(1)) + show "intuitionistic (sat B) \ pure_remains S'" by (simp add: assms(5)) + qed + moreover have "is_footprint_general w R A B" + proof (rule is_footprint_generalI) + fix a b assume asm: "sat A a \ Some b = a \ R a w" + then have "(a, R a) \ ?S" + using assms(2) by blast + then have "sat B (the (a \ R a w))" using r using asm defined_def by fastforce + then show "sat B b" by (metis asm option.sel) + qed + ultimately show ?thesis by blast +qed + +corollary soundness_paper: + assumes "wf_assertion B" + and "\a. sat A a \ a \ S" + and "package_rhs \ unit { (a, unit, id) |a. a \ S } (\_. True) B \' w S'" + and "intuitionistic (sat B) \ pure_remains S'" + shows "stable w \ Some \ = \' \ w \ is_footprint_standard w A B" +proof - + have "stable w \ Some \ = \' \ w \ is_footprint_general w (\_. id) A B" + using assms soundness[of B A S "\_. id" \ \' w S'] + by (simp add: mono_transformer_def) + then show ?thesis + using is_footprint_general_def is_footprint_standardI by fastforce +qed + + + +subsection Completeness + +theorem general_completeness: + assumes "\a u T x. (a, u, T) \ S \ Some x = a \ T f \ sat A x" + and "Some \ = \' \ f" + and "stable f" + and "valid_package_set S unit" + and "wf_assertion A" + shows "\S'. package_rhs \ unit S (\_. True) A \' f S'" +proof - + define S' where "S' = { (r, u, T) |a u T r. (a, u, T) \ S \ Some r = a \ (T f \ T unit) \ r ## u }" + let ?pc = "\_. True" + have "\S''. package_rhs \' f S' ?pc A \' f S''" + proof - + let ?f2 = "\a u T. unit" + let ?f1 = "\a u T. a" + have "\S''. package_rhs \' f S' ?pc A \' f S'' \ (\(a', u', T) \ S''. \a u. (a, u, T) \ S' \ a' \ ?f2 a u T \ |a'| = |a| )" + proof (rule completeness_aux) + show "mono_pure_cond (\_. True)" by (simp add: mono_pure_cond_def) + show "wf_assertion A" by (simp add: assms(5)) + show "valid_package_set S' f" + proof (rule valid_package_setI) + fix a' u' T + assume "(a', u', T) \ S'" + then obtain a where asm: "(a, u', T) \ S \ Some a' = a \ (T f \ T unit) \ a' ## u'" + using S'_def by blast + then have "a ## u' \ |a| \ |u'| \ mono_transformer T " + using assms(4) valid_package_set_def by fastforce + moreover have "|T f \ T unit| = |T f|" + by (simp add: minus_core) + ultimately show "a' ## u' \ |a'| \ |u'| \ mono_transformer T \ a' \ |T f| " + by (meson asm core_sum greater_def greater_equiv minus_equiv_def mono_transformer_def succ_trans unit_neutral) + qed + show "stable f \ \' ## f" + by (metis assms(2) assms(3) defined_def domI domIff) + fix a u T + assume "(a, u, T) \ S'" + then obtain a' u' where "(a', u', T) \ S" "Some a = a' \ (T f \ T unit)" using S'_def by blast + moreover have "T f \ T unit = T f" + proof - + have "mono_transformer T" using \valid_package_set S unit\ valid_package_set_def \(a', u', T) \ S\ by auto + then show ?thesis + by (metis commutative minus_default minus_equiv_def mono_transformer_def option.sel unit_neutral) + qed + + then have "sat A (the ( |a| \ a))" + by (metis assms(1) calculation(1) calculation(2) commutative core_is_smaller option.sel) + then show "|a| \ |a| \ Some a = a \ unit \ (True \ sat A (the ( |a| \ a)))" + by (simp add: succ_refl unit_neutral) + qed + then show ?thesis by auto + qed + then obtain S'' where "package_rhs \' f S' ?pc A \' f S''" by blast + have "package_rhs \ unit S ?pc A \' f S''" + using assms(2) + proof (rule package_rhs.AddFromOutside) + show "package_rhs \' f S' ?pc A \' f S''" + by (simp add: \package_rhs \' f S' ?pc A \' f S''\) + show "stable f" using assms(3) by simp + show "Some f = unit \ f" + by (simp add: commutative unit_neutral) + show "S' = { (r, u, T) |a u T r. (a, u, T) \ S \ Some r = a \ (T f \ T unit) \ r ## u }" + using S'_def by blast + qed + then show ?thesis + by blast +qed + +theorem completeness: + assumes "wf_assertion B" + and "stable w \ is_footprint_general w R A B" + and "Some \ = \' \ w" + and "\a. sat A a \ mono_transformer (R a)" + shows "\S'. package_rhs \ unit {(a, unit, R a) |a. sat A a} (\_. True) B \' w S'" +proof - + let ?S = "{(a, unit, R a) |a. sat A a}" + have "\S'. package_rhs \ unit {(a, unit, R a) |a. sat A a} (\_. True) B \' w S'" + proof (rule general_completeness[of ?S w B \ \']) + show "\a u T x. (a, u, T) \ {(a, unit, R a) |a. sat A a} \ Some x = a \ T w \ sat B x" + using assms(2) is_footprint_general_def by blast + show "Some \ = \' \ w" by (simp add: assms(3)) + show "stable w" by (simp add: assms(2)) + show "wf_assertion B" by (simp add: assms(1)) + + show "valid_package_set {(a, unit, R a) |a. sat A a} unit" + proof (rule valid_package_setI) + fix a u T assume asm0: "(a, u, T) \ {(a, unit, R a) |a. sat A a}" + then have "u = unit \ T = R a \ sat A a" by fastforce + then show "a ## u \ |a| \ |u| \ mono_transformer T \ a \ |T unit|" + using assms(4) defined_def mono_transformer_def unit_core unit_neutral unit_smaller by auto + qed + qed + then show ?thesis by meson +qed + +corollary completeness_paper: + assumes "wf_assertion B" + and "stable w \ is_footprint_standard w A B" + and "Some \ = \' \ w" + shows "\S'. package_rhs \ unit {(a, unit, id) |a. sat A a} (\_. True) B \' w S'" +proof - + have "\S'. package_rhs \ unit {(a, unit, (\_. id) a) |a. sat A a} (\_. True) B \' w S'" + using assms(1) + proof (rule completeness) + show "stable w \ is_footprint_general w (\a. id) A B" + using assms(2) is_footprint_general_def is_footprint_standard_def by force + show "Some \ = \' \ w" by (simp add: assms(3)) + show "\a. sat A a \ mono_transformer id" using mono_transformer_def by auto + qed + then show ?thesis by meson +qed + + +end + +end diff --git a/thys/Package_logic/ROOT b/thys/Package_logic/ROOT new file mode 100644 --- /dev/null +++ b/thys/Package_logic/ROOT @@ -0,0 +1,10 @@ +chapter AFP + +session Package_logic (AFP) = HOL + + options [timeout=300] + theories + SepAlgebra + PackageLogic + document_files + "root.bib" + "root.tex" diff --git a/thys/Package_logic/SepAlgebra.thy b/thys/Package_logic/SepAlgebra.thy new file mode 100755 --- /dev/null +++ b/thys/Package_logic/SepAlgebra.thy @@ -0,0 +1,1042 @@ +section \Separation Algebra\ + +text \In this section, we formalize the concept of a separation algebra~\cite{Calcagno2007, Dockins2009}, on which our package logic is based.\ + +theory SepAlgebra + imports Main +begin + +type_synonym 'a property = "'a \ bool" + +locale sep_algebra = + + fixes plus :: "'a \ 'a \ 'a option" (infixl "\" 63) + + fixes core :: "'a \ 'a" (" |_| ") + (* Largest duplicable part of a state *) + + assumes commutative: "a \ b = b \ a" + and asso1: "a \ b = Some ab \ b \ c = Some bc \ ab \ c = a \ bc" + and asso2: "a \ b = Some ab \ b \ c = None \ ab \ c = None" + +(* The core of x is the max of { p | pure p \ x \ p} *) + and core_is_smaller: "Some x = x \ |x|" + and core_is_pure: "Some |x| = |x| \ |x|" + and core_max: "Some x = x \ c \ (\r. Some |x| = c \ r)" + and core_sum: "Some c = a \ b \ Some |c| = |a| \ |b|" + + and positivity: "a \ b = Some c \ Some c = c \ c \ Some a = a \ a" + and cancellative: "Some a = b \ x \ Some a = b \ y \ |x| = |y| \ x = y" + +begin + +lemma asso3: + assumes "a \ b = None" + and "b \ c = Some bc" + shows "a \ bc = None" + by (metis assms(1) assms(2) sep_algebra.asso2 sep_algebra.commutative sep_algebra_axioms) + +subsection \Definitions\ + +definition defined :: "'a \ 'a \ bool" (infixl "##" 62) where + "a ## b \ a \ b \ None" + +definition greater :: "'a \ 'a \ bool" (infixl "\" 50) where + "a \ b \ (\c. Some a = b \ c)" + +definition pure :: "'a \ bool" where + "pure a \ Some a = a \ a" + +definition minus :: "'a \ 'a \ 'a" (infixl "\" 63) + where "b \ a = (THE_default b (\x. Some b = a \ x \ x \ |b| ))" + +definition add_set :: "'a set \ 'a set \ 'a set" (infixl "\" 60) where + "A \ B = { \ | \ a b. a \ A \ b \ B \ Some \ = a \ b }" + +definition greater_set :: "'a set \ 'a set \ bool" (infixl "\" 50) where + "A \ B \ (\a \ A. \b \ B. a \ b)" + +definition up_closed :: "'a set \ bool" where + "up_closed A \ (\\'. (\\ \ A. \' \ \) \ \' \ A)" + +definition equiv :: "'a set \ 'a set \ bool" (infixl "\" 40) where + "A \ B \ A \ B \ B \ A" + +definition setify :: "'a property \ ('a set \ bool)" where + "setify P A \ (\x \ A. P x)" + +definition mono_prop :: "'a property \ bool" where + "mono_prop P \ (\x y. y \ x \ P x \ P y)" + +definition under :: "'a set \ 'a \ 'a set" where + "under A \ = { \' | \'. \' \ A \ \ \ \'}" + +definition max_projection_prop :: "('a \ bool) \ ('a \ 'a) \ bool" where + "max_projection_prop P f \ (\x. x \ f x \ P (f x) \ + (\p. P p \ x \ p \ f x \ p))" + +inductive multi_plus :: "'a list \ 'a \ bool" where + MPSingle: "multi_plus [a] a" +| MPConcat: "\ length la > 0 ; length lb > 0 ; multi_plus la a ; multi_plus lb b ; Some \ = a \ b \ \ multi_plus (la @ lb) \" + +fun splus :: "'a option \ 'a option \ 'a option" where + "splus None _ = None" +| "splus _ None = None" +| "splus (Some a) (Some b) = a \ b" + + + +subsection \First lemmata\ + +lemma greater_equiv: + "a \ b \ (\c. Some a = c \ b)" + using commutative greater_def by auto + +lemma smaller_compatible: + assumes "a' ## b" + and "a' \ a" + shows "a ## b" + by (metis (full_types) assms(1) assms(2) asso3 commutative defined_def greater_def) + +lemma bigger_sum_smaller: + assumes "Some c = a \ b" + and "a \ a'" + shows "\b'. b' \ b \ Some c = a' \ b'" +proof - + obtain r where "Some a = a' \ r" + using assms(2) greater_def by auto + then obtain br where "Some br = r \ b" + by (metis assms(1) asso2 domD domIff option.discI) + then have "Some c = a' \ br" + by (metis \Some a = a' \ r\ assms(1) asso1) + then show ?thesis + using \Some br = r \ b\ commutative greater_def by force +qed + +subsubsection \splus\ + +lemma splus_develop: + assumes "Some a = b \ c" + shows "a \ d = splus (splus (Some b) (Some c)) (Some d)" + by (metis assms splus.simps(3)) + +lemma splus_comm: + "splus a b = splus b a" + apply (cases a) + apply (cases b) + apply simp_all + apply (cases b) + by (simp_all add: commutative) + +lemma splus_asso: + "splus (splus a b) c = splus a (splus b c)" +proof (cases a) + case None + then show ?thesis + by simp +next + case (Some a') + then have "a = Some a'" by simp + then show ?thesis + proof (cases b) + case None + then show ?thesis by (simp add: Some) + next + case (Some b') + then have "b = Some b'" by simp + then show ?thesis + proof (cases c) + case None + then show ?thesis by (simp add: splus_comm) + next + case (Some c') + then have "c = Some c'" by simp + then show ?thesis + proof (cases "a' \ b'") + case None + then have "a' \ b' = None" by simp + then show ?thesis + proof (cases "b' \ c'") + case None + then show ?thesis + by (simp add: Some \a = Some a'\ \a' \ b' = None\ \b = Some b'\) + next + case (Some bc) + then show ?thesis + by (metis (full_types) None \a = Some a'\ \b = Some b'\ \c = Some c'\ sep_algebra.asso2 sep_algebra_axioms splus.simps(2) splus.simps(3) splus_comm) + qed + next + case (Some ab) + then have "Some ab = a' \ b'" by simp + then show ?thesis + proof (cases "b' \ c'") + case None + then show ?thesis + by (metis Some \a = Some a'\ \b = Some b'\ \c = Some c'\ asso2 splus.simps(2) splus.simps(3)) + next + case (Some bc) + then show ?thesis + by (metis \Some ab = a' \ b'\ \a = Some a'\ \b = Some b'\ \c = Some c'\ sep_algebra.asso1 sep_algebra_axioms splus.simps(3)) + qed + qed + qed + qed +qed + + + + + + + +subsubsection \Pure\ + +(* Maybe need more *) +lemma pure_stable: + assumes "pure a" + and "pure b" + and "Some c = a \ b" + shows "pure c" + by (metis assms asso1 commutative pure_def) + +(* Specific to pure *) +lemma pure_smaller: + assumes "pure a" + and "a \ b" + shows "pure b" + by (metis assms greater_def positivity pure_def) + + +subsection \Succ is an order\ + +lemma succ_antisym: + assumes "a \ b" + and "b \ a" + shows "a = b" +proof - + obtain ra where "Some a = b \ ra" + using assms(1) greater_def by auto + obtain rb where "Some b = a \ rb" + using assms(2) greater_def by auto + then have "Some a = splus (Some a) (splus (Some ra) (Some rb))" + proof - + have "Some b = splus (Some a) (Some rb)" + by (simp add: \Some b = a \ rb\) + then show ?thesis + by (metis (full_types) \Some a = b \ ra\ sep_algebra.splus.simps(3) sep_algebra_axioms splus_asso splus_comm) + qed + moreover have "Some b = splus (Some b) (splus (Some ra) (Some rb))" + by (metis \Some a = b \ ra\ \Some b = a \ rb\ sep_algebra.splus.simps(3) sep_algebra_axioms splus_asso) + moreover have "pure ra \ pure rb" + proof - + obtain rab where "Some rab = ra \ rb" + by (metis calculation(2) splus.elims splus.simps(3)) + then have "|a| \ rab" + by (metis calculation(1) core_max greater_def splus.simps(3)) + then have "pure rab" + using core_is_pure pure_def pure_smaller by blast + moreover have "rab \ ra \ rab \ rb" + using \Some rab = ra \ rb\ greater_def greater_equiv by blast + ultimately have "pure ra" using pure_smaller + by blast + moreover have "pure rb" + using \pure rab\ \rab \ ra \ rab \ rb\ pure_smaller by blast + ultimately show ?thesis + by blast + qed + ultimately show ?thesis + by (metis \Some b = a \ rb\ option.inject pure_def sep_algebra.splus.simps(3) sep_algebra_axioms splus_asso) +qed + +lemma succ_trans: + assumes "a \ b" + and "b \ c" + shows "a \ c" + using assms(1) assms(2) bigger_sum_smaller greater_def by blast + +lemma succ_refl: + "a \ a" + using core_is_smaller greater_def by blast + + + + + + + + +subsection \Core (pure) and stabilize (stable)\ + +lemma max_projection_propI: + assumes "\x. x \ f x" + and "\x. P (f x)" + and "\x p. P p \ x \ p \ f x \ p" + shows "max_projection_prop P f" + by (simp add: assms(1) assms(2) assms(3) max_projection_prop_def) + +lemma max_projection_propE: + assumes "max_projection_prop P f" + shows "\x. x \ f x" + and "\x. P (f x)" + and "\x p. P p \ x \ p \ f x \ p" + using assms max_projection_prop_def by auto + +lemma max_projection_prop_pure_core: + "max_projection_prop pure core" +proof (rule max_projection_propI) + fix x + show "x \ |x|" + using core_is_smaller greater_equiv by blast + show "pure |x|" + by (simp add: core_is_pure pure_def) + show "\p. pure p \ x \ p \ |x| \ p" + proof - + fix p assume "pure p \ x \ p" + then obtain r where "Some x = p \ r" + using greater_def by blast + then show "|x| \ p" + by (metis \pure p \ x \ p\ asso1 commutative core_max greater_equiv pure_def) + qed +qed + +lemma mpp_smaller: + assumes "max_projection_prop P f" + shows "x \ f x" + using assms max_projection_propE(1) by auto + +lemma mpp_compatible: + assumes "max_projection_prop P f" + and "a ## b" + shows "f a ## f b" + by (metis (mono_tags, opaque_lifting) assms(1) assms(2) commutative defined_def max_projection_prop_def smaller_compatible) + + + +lemma mpp_prop: + assumes "max_projection_prop P f" + shows "P (f x)" + by (simp add: assms max_projection_propE(2)) + + +lemma mppI: + assumes "max_projection_prop P f" + and "a \ x" + and "P x" + and "x \ f a" + shows "x = f a" +proof - + have "f a \ x" + using assms max_projection_propE(3) by auto + then show ?thesis + by (simp add: assms(4) succ_antisym) +qed + +lemma mpp_invo: + assumes "max_projection_prop P f" + shows "f (f x) = f x" + using assms max_projection_prop_def succ_antisym by auto + +lemma mpp_mono: + assumes "max_projection_prop P f" + and "a \ b" + shows "f a \ f b" + by (metis assms max_projection_prop_def succ_trans) + + +subsection \Subtraction\ + +lemma addition_bigger: + assumes "a' \ a" + and "Some x' = a' \ b" + and "Some x = a \ b" + shows "x' \ x" + by (metis assms asso1 bigger_sum_smaller greater_def) + + +lemma smaller_than_core: + assumes "y \ x" + and "Some z = x \ |y|" + shows "|z| = |y|" +proof - + have "Some |z| = |x| \ |y|" + using assms(2) core_sum max_projection_prop_pure_core mpp_invo by fastforce + then have "Some |z| = |x| \ |y|" + by simp + moreover have "|z| \ |y|" + using calculation greater_equiv by blast + ultimately show ?thesis + by (meson addition_bigger assms(1) assms(2) core_is_smaller core_sum greater_def succ_antisym) +qed + +lemma extract_core: + assumes "Some b = a \ x \ x \ |b|" + shows "|x| = |b|" +proof - + obtain r where "Some x = r \ |b|" + using assms greater_equiv by auto + show ?thesis + proof (rule smaller_than_core) + show "Some x = r \ |b|" + using \Some x = r \ |b|\ by auto + show "b \ r" + by (metis \Some x = r \ |b|\ assms commutative greater_def succ_trans) + qed +qed + + +lemma minus_unique: + assumes "Some b = a \ x \ x \ |b|" + and "Some b = a \ y \ y \ |b|" + shows "x = y" +proof - + have "|x| = |b|" + using assms(1) extract_core by blast + moreover have "|y| = |b|" + using assms(2) extract_core by blast + ultimately show ?thesis + using assms(1) assms(2) cancellative by auto +qed + +lemma minus_exists: + assumes "b \ a" + shows "\x. Some b = a \ x \ x \ |b|" + using assms bigger_sum_smaller core_is_smaller by blast + +lemma minus_equiv_def: + assumes "b \ a" + shows "Some b = a \ (b \ a) \ (b \ a) \ |b|" +proof - + let ?x = "THE_default b (\x. Some b = a \ x \ x \ |b| )" + have "(\x. Some b = a \ x \ x \ |b| ) ?x" + proof (rule THE_defaultI') + show "\!x. Some b = a \ x \ x \ |b|" + using assms local.minus_unique minus_exists by blast + qed + then show ?thesis by (metis minus_def) +qed + +lemma minus_default: + assumes "\ b \ a" + shows "b \ a = b" + using THE_default_none assms greater_def minus_def by fastforce + +lemma minusI: + assumes "Some b = a \ x" + and "x \ |b|" + shows "x = b \ a" + using assms(1) assms(2) greater_def local.minus_unique minus_equiv_def by blast + +lemma minus_core: + "|a \ b| = |a|" +proof (cases "a \ b") + case True + then have "Some a = b \ (a \ b) \ a \ b \ |a|" + using minus_equiv_def by auto + then show ?thesis + using extract_core by blast +next + case False + then show ?thesis by (simp add: minus_default) +qed + + +lemma minus_core_weaker: + "|a \ b| = |a| \ |b|" +proof (cases "a \ b") + case True + then show ?thesis + by (metis greater_equiv max_projection_prop_pure_core minus_core minus_default minus_equiv_def mpp_invo succ_antisym) +next + case False + then show ?thesis + by (metis greater_equiv max_projection_prop_pure_core minus_default minus_equiv_def mpp_invo succ_antisym) +qed + +lemma minus_equiv_def_any_elem: + assumes "Some x = a \ b" + shows "Some (x \ a) = b \ |x|" +proof - + obtain r where "Some r = b \ |x|" + by (metis assms core_is_smaller domD domIff option.simps(3) sep_algebra.asso2 sep_algebra_axioms) + have "r = x \ a" + proof (rule minusI) + show "Some x = a \ r" + by (metis \Some r = b \ |x|\ assms asso1 core_is_smaller) + moreover show "r \ |x|" + using \Some r = b \ |x|\ greater_equiv by blast + qed + then show ?thesis + using \Some r = b \ |x|\ by blast +qed + +lemma minus_bigger: + assumes "Some x = a \ b" + shows "x \ a \ b" + using assms greater_def minus_equiv_def_any_elem by blast + +lemma minus_smaller: + assumes "x \ a" + shows "x \ x \ a" + using assms greater_equiv minus_equiv_def by blast + +lemma minus_sum: + assumes "Some a = b \ c" + and "x \ a" + shows "x \ a = (x \ b) \ c" +proof (rule minusI) + obtain r where "Some r = c \ (x \ a)" + by (metis assms(1) assms(2) asso2 minus_equiv_def option.exhaust_sel) + have "r = (x \ b)" + proof (rule minusI) + show "Some x = b \ r" + by (metis \Some r = c \ (x \ a)\ assms(1) assms(2) asso1 minus_equiv_def) + moreover show "r \ |x|" + by (meson \Some r = c \ (x \ a)\ assms(2) greater_equiv sep_algebra.minus_equiv_def sep_algebra_axioms succ_trans) + qed + then show "Some (x \ b) = c \ (x \ a)" + using \Some r = c \ (x \ a)\ by blast + moreover show "x \ a \ |x \ b|" + by (simp add: assms(2) minus_core minus_equiv_def) +qed + +lemma smaller_compatible_core: + assumes "y \ x" + shows "x ## |y|" + by (metis assms asso2 core_is_smaller defined_def greater_equiv option.discI) + +lemma smaller_pure_sum_smaller: + assumes "y \ a" + and "y \ b" + and "Some x = a \ b" + and "pure b" + shows "y \ x" +proof - + obtain r where "Some y = r \ b" "r \ a" + by (metis assms(1) assms(2) assms(4) asso1 greater_equiv pure_def) + then show ?thesis + using addition_bigger assms(3) by blast +qed + +lemma greater_minus_trans: + assumes "y \ x" + and "x \ a" + shows "y \ a \ x \ a" +proof - + obtain r where "Some y = x \ r" + using assms(1) greater_def by blast + then obtain ra where "Some x = a \ ra" + using assms(2) greater_def by blast + then have "Some (x \ a) = ra \ |x|" + by (simp add: minus_equiv_def_any_elem) + then obtain yy where "Some yy = (x \ a) \ r" + by (metis (full_types) \Some y = x \ r\ assms(2) asso3 commutative minus_equiv_def not_Some_eq) + then have "Some x = a \ (x \ a) \ x \ a \ |x|" + by (simp add: assms(2) sep_algebra.minus_equiv_def sep_algebra_axioms) + then obtain y' where "Some y' = a \ yy" + using \Some y = x \ r\ \Some yy = x \ a \ r\ asso1 + by metis + moreover have "y \ y'" + by (metis \Some x = a \ (x \ a) \ x \ a \ |x|\ \Some y = x \ r\ \Some yy = x \ a \ r\ asso1 calculation option.inject succ_refl) + moreover obtain x' where "Some x' = (x \ a) \ a" + using assms(2) commutative minus_equiv_def by fastforce + then have "y \ x'" + by (metis assms(1) assms(2) commutative minus_equiv_def option.sel) + moreover have "x' \ x \ a" + using \Some x' = x \ a \ a\ greater_def by auto + ultimately show ?thesis + using \Some x' = x \ a \ a\ \Some y = x \ r\ assms(2) asso1 commutative greater_equiv minus_bigger minus_equiv_def option.sel sep_algebra.succ_trans sep_algebra_axioms + proof - + have f1: "Some y' = a \ yy" + by (simp add: \Some y' = a \ yy\ commutative) + then have "y = y'" + by (metis \Some y = x \ r\ \Some yy = x \ a \ r\ \x \ a\ asso1 minus_equiv_def option.sel) + then show ?thesis + using f1 by (metis (no_types) \Some yy = x \ a \ r\ commutative greater_equiv minus_bigger sep_algebra.succ_trans sep_algebra_axioms) + qed +qed + + + + +lemma minus_and_plus: + assumes "Some \' = \ \ r" + and "\ \ a" + shows "Some (\' \ a) = (\ \ a) \ r" +proof - + have "\ \ \ \ a" + by (simp add: assms(2) minus_smaller) + then have "(\ \ a) ## r" + by (metis (full_types) assms(1) defined_def option.discI sep_algebra.smaller_compatible sep_algebra_axioms) + then obtain x where "Some x = (\ \ a) \ r" + using defined_def by auto + then have "Some \' = a \ x \ x \ |\'|" + by (metis (no_types, lifting) assms asso1 core_sum max_projection_prop_pure_core minus_core minus_equiv_def mpp_smaller option.inject) + then have "x = \' \ a" + by (simp add: minusI) + then show ?thesis + using \Some x = \ \ a \ r\ by blast +qed + + + + + + + + + +subsection \Lifting the algebra to sets of states\ + +lemma add_set_commm: + "A \ B = B \ A" +proof + show "A \ B \ B \ A" + using add_set_def sep_algebra.commutative sep_algebra_axioms by fastforce + show "B \ A \ A \ B" + using add_set_def commutative by fastforce +qed + +lemma x_elem_set_product: + "x \ A \ B \ (\a b. a \ A \ b \ B \ Some x = a \ b)" + using sep_algebra.add_set_def sep_algebra_axioms by fastforce + +lemma x_elem_set_product_splus: + "x \ A \ B \ (\a b. a \ A \ b \ B \ Some x = splus (Some a) (Some b))" + using sep_algebra.add_set_def sep_algebra_axioms by fastforce + +lemma add_set_asso: + "(A \ B) \ C = A \ (B \ C)" (is "?A = ?B") +proof - + have "?A \ ?B" + proof (rule subsetI) + fix x assume "x \ ?A" + then obtain ab c where "Some x = ab \ c" "ab \ A \ B" "c \ C" + using x_elem_set_product by auto + then obtain a b where "Some ab = a \ b" "a \ A" "b \ B" + using x_elem_set_product by auto + then obtain bc where "Some bc = b \ c" + by (metis \Some x = ab \ c\ asso2 option.exhaust) + then show "x \ ?B" + by (metis \Some ab = a \ b\ \Some x = ab \ c\ \a \ A\ \b \ B\ \c \ C\ asso1 x_elem_set_product) + qed + moreover have "?B \ ?A" + proof (rule subsetI) + fix x assume "x \ ?B" + then obtain a bc where "Some x = a \ bc" "a \ A" "bc \ B \ C" + using x_elem_set_product by auto + then obtain b c where "Some bc = b \ c" "c \ C" "b \ B" + using x_elem_set_product by auto + then obtain ab where "Some ab = a \ b" + by (metis \Some x = a \ bc\ asso3 option.collapse) + then show "x \ ?A" + by (metis \Some bc = b \ c\ \Some x = a \ bc\ \a \ A\ \b \ B\ \c \ C\ asso1 x_elem_set_product) + qed + ultimately show ?thesis by blast +qed + +lemma up_closedI: + assumes "\\' \. (\' :: 'a) \ \ \ \ \ A \ \' \ A" + shows "up_closed A" + using assms up_closed_def by blast + +lemma up_closed_plus_UNIV: + "up_closed (A \ UNIV)" +proof (rule up_closedI) + fix \ \' + assume asm: "\' \ \ \ \ \ A \ UNIV" + then obtain r a b where "Some \' = \ \ r" "Some \ = a \ b" "a \ A" + using greater_def x_elem_set_product by auto + then obtain br where "Some br = b \ r" + by (metis asso2 option.exhaust_sel) + then have "Some \' = a \ br" + by (metis \Some \ = a \ b\ \Some \' = \ \ r\ splus.simps(3) splus_asso) + then show "\' \ A \ UNIV" + using \a \ A\ x_elem_set_product by auto +qed + + +lemma succ_set_trans: + assumes "A \ B" + and "B \ C" + shows "A \ C" + by (meson assms(1) assms(2) greater_set_def succ_trans) + +lemma greater_setI: + assumes "\a. a \ A \ (\b \ B. a \ b)" + shows "A \ B" + by (simp add: assms greater_set_def) + +lemma bigger_set: + assumes "A' \ A" + shows "A' \ B \ A \ B" +proof (rule greater_setI) + fix x assume "x \ A' \ B" + then obtain a' b where "Some x = a' \ b" "a' \ A'" "b \ B" + using x_elem_set_product by auto + then obtain a where "a' \ a" "a \ A" + using assms greater_set_def by blast + then obtain ab where "Some ab = a \ b" + by (metis \Some x = a' \ b\ asso2 domD domIff greater_equiv) + then show "\ab\A \ B. x \ ab" + using \Some x = a' \ b\ \a \ A\ \a' \ a\ \b \ B\ addition_bigger x_elem_set_product by blast +qed + +lemma bigger_singleton: + assumes "\' \ \" + shows "{\'} \ {\}" + by (simp add: assms greater_set_def) + +lemma add_set_elem: + "\ \ A \ B \ (\a b. Some \ = a \ b \ a \ A \ b \ B)" + using add_set_def by auto + +lemma up_closed_sum: + assumes "up_closed A" + shows "up_closed (A \ B)" +proof (rule up_closedI) + fix \' \ assume asm: "\' \ \ \ \ \ A \ B" + then obtain a b where "a \ A" "b \ B" "Some \ = a \ b" + using add_set_elem by auto + moreover obtain r where "Some \' = \ \ r" + using asm greater_def by blast + then obtain ar where "Some ar = a \ r" + by (metis asso2 calculation(3) commutative option.exhaust_sel option.simps(3)) + then have "ar \ A" + by (meson assms calculation(1) greater_def sep_algebra.up_closed_def sep_algebra_axioms) + then show "\' \ A \ B" + by (metis \Some \' = \ \ r\ \Some ar = a \ r\ add_set_elem asso1 calculation(2) calculation(3) commutative) +qed + +lemma up_closed_bigger_subset: + assumes "up_closed B" + and "A \ B" + shows "A \ B" + by (meson assms(1) assms(2) greater_set_def sep_algebra.up_closed_def sep_algebra_axioms subsetI) + +lemma up_close_equiv: + assumes "up_closed A" + and "up_closed B" + shows "A \ B \ A = B" +proof - + have "A \ B \ A \ B \ B \ A" + using local.equiv_def by auto + also have "... \ A \ B \ B \ A" + by (metis assms(1) assms(2) greater_set_def set_eq_subset succ_refl up_closed_bigger_subset) + ultimately show ?thesis + by blast +qed + +lemma equiv_stable_sum: + assumes "A \ B" + shows "A \ C \ B \ C" + using assms bigger_set local.equiv_def by auto + +lemma equiv_up_closed_subset: + assumes "up_closed A" + and "equiv B C" + shows "B \ A \ C \ A" (is "?B \ ?C") +proof - + have "?B \ ?C" + by (meson greater_set_def up_closed_def equiv_def assms(1) assms(2) subsetD subsetI) + moreover have "?C \ ?B" + by (meson greater_set_def up_closed_def equiv_def assms(1) assms(2) subsetD subsetI) + ultimately show ?thesis by blast +qed + +lemma mono_propI: + assumes "\x y. y \ x \ P x \ P y" + shows "mono_prop P" + using assms mono_prop_def by blast + +lemma mono_prop_set: + assumes "A \ B" + and "setify P B" + and "mono_prop P" + shows "setify P A" + using assms(1) assms(2) assms(3) greater_set_def local.setify_def mono_prop_def by auto + +lemma mono_prop_set_equiv: + assumes "mono_prop P" + and "equiv A B" + shows "setify P A \ setify P B" + by (meson assms(1) assms(2) local.equiv_def sep_algebra.mono_prop_set sep_algebra_axioms) + +lemma setify_sum: + "setify P (A \ B) \ (\x \ A. setify P ({x} \ B))" (is "?A \ ?B") +proof - + have "?A \ ?B" + using local.setify_def sep_algebra.add_set_elem sep_algebra_axioms singletonD by fastforce + moreover have "?B \ ?A" + using add_set_elem local.setify_def by fastforce + ultimately show ?thesis by blast +qed + +lemma setify_sum_image: + "setify P ((Set.image f A) \ B) \ (\x \ A. setify P ({f x} \ B))" +proof + show "setify P (f ` A \ B) \ \x\A. setify P ({f x} \ B)" + by (meson rev_image_eqI sep_algebra.setify_sum sep_algebra_axioms) + show "\x\A. setify P ({f x} \ B) \ setify P (f ` A \ B)" + by (metis (mono_tags, lifting) image_iff sep_algebra.setify_sum sep_algebra_axioms) +qed + +lemma equivI: + assumes "A \ B" + and "B \ A" + shows "equiv A B" + by (simp add: assms(1) assms(2) local.equiv_def) + +lemma sub_bigger: + assumes "A \ B" + shows "A \ B" + by (meson assms greater_set_def in_mono succ_refl) + +lemma larger_set_refl: + "A \ A" + by (simp add: sub_bigger) + + +definition upper_closure where + "upper_closure A = { \' |\' \. \' \ \ \ \ \ A }" + + + +lemma upper_closure_up_closed: + "up_closed (upper_closure A)" +proof (rule up_closedI) + fix \' \ + assume asm0: "\' \ \ \ \ \ upper_closure A" + then obtain a where "a \ A \ \ \ a" + using sep_algebra.upper_closure_def sep_algebra_axioms by fastforce + then have "\' \ a" + using asm0 succ_trans by blast + then show "\' \ upper_closure A" + using \a \ A \ \ \ a\ upper_closure_def by auto +qed + + +subsection \Addition of more than two states\ + +lemma multi_decompose: + assumes "multi_plus l \" + shows "length l \ 2 \ (\a b la lb. l = la @ lb \ length la > 0 \ length lb > 0 \ multi_plus la a \ multi_plus lb b \ Some \ = a \ b)" + using assms + apply (rule multi_plus.cases) + by auto[2] + + + +lemma multi_take_drop: + assumes "multi_plus l \" + and "length l \ 2" + shows "\n a b. n > 0 \ n < length l \ multi_plus (take n l) a \ multi_plus (drop n l) b \ Some \ = a \ b" +proof - + obtain a b la lb where "l = la @ lb \ length la > 0 \ length lb > 0 \ multi_plus la a \ multi_plus lb b \ Some \ = a \ b" + using assms(1) assms(2) multi_decompose by blast + let ?n = "length la" + have "la = take ?n l" + by (simp add: \l = la @ lb \ 0 < length la \ 0 < length lb \ multi_plus la a \ multi_plus lb b \ Some \ = a \ b\) + moreover have "lb = drop ?n l" + by (simp add: \l = la @ lb \ 0 < length la \ 0 < length lb \ multi_plus la a \ multi_plus lb b \ Some \ = a \ b\) + ultimately show ?thesis + by (metis \l = la @ lb \ 0 < length la \ 0 < length lb \ multi_plus la a \ multi_plus lb b \ Some \ = a \ b\ length_drop zero_less_diff) +qed + +lemma multi_plus_single: + assumes "multi_plus [v] a" + shows "a = v" + using assms + apply (cases) + apply simp + by (metis (no_types, lifting) Nil_is_append_conv butlast.simps(2) butlast_append length_greater_0_conv) + +lemma multi_plus_two: + assumes "length l \ 2" + shows "multi_plus l \ \ (\a b la lb. l = (la @ lb) \ length la > 0 \ length lb > 0 \ multi_plus la a \ multi_plus lb b \ Some \ = a \ b)" (is "?A \ ?B") + by (meson MPConcat assms multi_decompose) + +lemma multi_plus_head_tail: + "length l \ n \ length l \ 2 \ (multi_plus l \ \ (\r. Some \ = (List.hd l) \ r \ multi_plus (List.tl l) r))" +proof (induction n arbitrary: l \) + case 0 + then show ?case by auto +next + case (Suc n) + then have IH: "\(l :: 'a list) \. length l \ n \ length l \ 2 \ multi_plus l \ = (\r. Some \ = hd l \ r \ multi_plus (tl l) r)" + by blast + then show ?case + proof (cases "n = 0") + case True + then have "n = 0" by simp + then show ?thesis by linarith + next + case False + then have "length (l :: 'a list) \ 2 \ length l \ n + 1 \ multi_plus l \ \ (\r. Some \ = hd l \ r \ multi_plus (tl l) r)" (is "length l \ 2 \ length l \ n + 1 \ ?A \ ?B") + proof - + assume asm: "length (l :: 'a list) \ 2 \ length l \ n + 1" + have "?B \ ?A" + proof - + assume "?B" + then obtain r where "Some \ = hd l \ r \ multi_plus (tl l) r" by blast + then have "multi_plus [hd l] (hd l)" + using MPSingle by blast + moreover have "[hd l] @ (tl l) = l" + by (metis Suc_le_length_iff asm append_Cons list.collapse list.simps(3) numeral_2_eq_2 self_append_conv2) + ultimately show ?A + by (metis (no_types, lifting) MPConcat Suc_1 Suc_le_mono asm \Some \ = hd l \ r \ multi_plus (tl l) r\ append_Nil2 length_Cons length_greater_0_conv list.size(3) not_one_le_zero zero_less_Suc) + qed + moreover have "?A \ ?B" + proof - + assume ?A + then obtain la lb a b where "l = la @ lb" "length la > 0" "length lb > 0" "multi_plus la a" "multi_plus lb b" "Some \ = a \ b" + using asm multi_decompose by blast + then have "length la \ n \ length la \ 2 \ multi_plus la a = (\r. Some a = hd la \ r \ multi_plus (tl la) r)" + using IH by blast + then show ?B + proof (cases "length la \ 2") + case True + then obtain ra where "Some a = (hd la) \ ra" "multi_plus (tl la) ra" + by (metis Suc_eq_plus1 \0 < length lb\ \l = la @ lb\ \length la \ n \ 2 \ length la \ multi_plus la a = (\r. Some a = hd la \ r \ multi_plus (tl la) r)\ \multi_plus la a\ append_eq_conv_conj asm drop_eq_Nil le_add1 le_less_trans length_append length_greater_0_conv less_Suc_eq_le order.not_eq_order_implies_strict) + moreover obtain rab where "Some rab = ra \ b" + by (metis \Some \ = a \ b\ calculation(1) asso2 option.exhaust_sel) + then have "multi_plus ((tl la) @ lb) rab" + by (metis (no_types, lifting) Nil_is_append_conv \multi_plus lb b\ calculation(2) length_greater_0_conv list.simps(3) multi_plus.cases sep_algebra.MPConcat sep_algebra_axioms) + moreover have "Some \ = hd la \ rab" + by (metis \Some \ = a \ b\ \Some rab = ra \ b\ asso1 calculation(1)) + ultimately show ?B + using \0 < length la\ \l = la @ lb\ by auto + next + case False + then have "length la = 1" + using \0 < length la\ by linarith + then have "la = [a]" + by (metis Nitpick.size_list_simp(2) One_nat_def Suc_le_length_iff \multi_plus la a\ diff_Suc_1 le_numeral_extra(4) length_0_conv list.sel(3) sep_algebra.multi_plus_single sep_algebra_axioms) + then show ?thesis + using \Some \ = a \ b\ \l = la @ lb\ \multi_plus lb b\ by auto + qed + qed + then show ?thesis using calculation by blast + qed + then show ?thesis by (metis (no_types, lifting) Suc_eq_plus1) + qed +qed + +lemma not_multi_plus_empty: + "\ multi_plus [] \" + by (metis Nil_is_append_conv length_greater_0_conv list.simps(3) sep_algebra.multi_plus.simps sep_algebra_axioms) + +lemma multi_plus_deter: + "length l \ n \ multi_plus l \ \ multi_plus l \' \ \ = \'" +proof (induction n arbitrary: l \ \') + case 0 + then show ?case + using multi_plus.cases by auto +next + case (Suc n) + then show ?case + proof (cases "length l \ 2") + case True + then obtain r where "Some \ = (List.hd l) \ r \ multi_plus (List.tl l) r" + using Suc.prems(2) multi_plus_head_tail by blast + moreover obtain r' where "Some \' = (List.hd l) \ r' \ multi_plus (List.tl l) r'" + using Suc.prems(3) True multi_plus_head_tail by blast + ultimately have "r = r'" + by (metis Suc.IH Suc.prems(1) drop_Suc drop_eq_Nil) + then show ?thesis + by (metis \Some \ = hd l \ r \ multi_plus (tl l) r\ \Some \' = hd l \ r' \ multi_plus (tl l) r'\ option.inject) + next + case False + then have "length l \ 1" + by simp + then show ?thesis + proof (cases "length l = 0") + case True + then show ?thesis + using Suc.prems(2) sep_algebra.not_multi_plus_empty sep_algebra_axioms by fastforce + next + case False + then show ?thesis + by (metis One_nat_def Suc.prems(2) Suc.prems(3) Suc_length_conv \length l \ 1\ le_SucE le_zero_eq length_greater_0_conv less_numeral_extra(3) sep_algebra.multi_plus_single sep_algebra_axioms) + qed + qed +qed + +lemma multi_plus_implies_multi_plus_of_drop: + assumes "multi_plus l \" + and "n < length l" + shows "\a. multi_plus (drop n l) a \ \ \ a" + using assms +proof (induction n arbitrary: l \) + case 0 + then show ?case using succ_refl by fastforce +next + case (Suc n) + then have "length l \ 2" + by linarith + then obtain r where "Some \ = (List.hd l) \ r \ multi_plus (List.tl l) r" + using Suc.prems(1) multi_plus_head_tail by blast + then obtain a where "multi_plus (drop n (List.tl l)) a \ r \ a" + using Suc.IH Suc.prems(2) by fastforce + then show ?case + by (metis \Some \ = hd l \ r \ multi_plus (tl l) r\ bigger_sum_smaller commutative drop_Suc greater_def) +qed + +lemma multi_plus_bigger_than_head: + assumes "length l > 0" + and "multi_plus l \" + shows "\ \ List.hd l" +proof (cases "length l \ 2") + case True + then obtain r where "Some \ = (List.hd l) \ r \ multi_plus (List.tl l) r" + using assms(1) assms(2) multi_plus_head_tail by blast + then show ?thesis + using greater_def by blast +next + case False + then show ?thesis + by (metis Cons_nth_drop_Suc MPSingle assms(1) assms(2) drop_0 drop_eq_Nil hd_conv_nth length_greater_0_conv not_less_eq_eq numeral_2_eq_2 sep_algebra.multi_plus_deter sep_algebra_axioms succ_refl) +qed + +lemma multi_plus_bigger: + assumes "i < length l" + and "multi_plus l \" + shows "\ \ (l ! i)" +proof - + obtain a where "multi_plus (drop i l) a \ \ \ a" + using assms(1) assms(2) multi_plus_implies_multi_plus_of_drop order.strict_trans by blast + moreover have "List.hd (drop i l) = l ! i" + by (simp add: assms(1) hd_drop_conv_nth) + then show ?thesis + by (metis (no_types, lifting) succ_trans assms(1) assms(2) drop_eq_Nil leD length_greater_0_conv multi_plus_bigger_than_head multi_plus_implies_multi_plus_of_drop) +qed + + +lemma sum_then_singleton: + "Some a = b \ c \ {a} = {b} \ {c}" (is "?A \ ?B") +proof - + have "?A \ ?B" + proof - + assume ?A + then have "{a} \ {b} \ {c}" + using add_set_elem by auto + moreover have "{b} \ {c} \ {a}" + proof (rule subsetI) + fix x assume "x \ {b} \ {c}" + then show "x \ {a}" + by (metis \Some a = b \ c\ option.sel sep_algebra.add_set_elem sep_algebra_axioms singleton_iff) + qed + ultimately show ?thesis by blast + qed + moreover have "?B \ ?A" + using add_set_elem by auto + ultimately show ?thesis by blast +qed + +lemma empty_set_sum: + "{} \ A = {}" + by (simp add: add_set_def) + + +end + +end diff --git a/thys/Package_logic/document/root.bib b/thys/Package_logic/document/root.bib new file mode 100644 --- /dev/null +++ b/thys/Package_logic/document/root.bib @@ -0,0 +1,47 @@ + + +@inproceedings{Dockins2009, +author = {Dockins, Robert and Hobor, Aquinas and Appel, Andrew W.}, +pages = {161--177}, +title = {{A Fresh Look at Separation Algebras and Share Accounting}}, +booktitle = {Asian Symposium on Programming Languages and Systems (APLAS)}, +editor = {Zhenjiang Hu}, +year = {2009} +} + +@inproceedings{Calcagno2007, +author = {Calcagno, Cristiano and O'Hearn, Peter W. and Yang, Hongseok}, +pages = {366--375}, +title = {{Local Action and Abstract Separation Logic}}, +booktitle = {Logic in Computer Science (LICS)}, +year = {2007} +} + +@inproceedings{SchwerhoffSummers15, + author = {M. Schwerhoff and A. J. Summers}, + title = {{Lightweight Support for Magic Wands in an Automatic Verifier}}, + booktitle = {European Conference on Object-Oriented Programming (ECOOP)}, + pages = {614--638}, + series = {LIPIcs}, + year = {2015}, + volume = {37}, + editor = {J. T. Boyland}, + publisher = {Schloss Dagstuhl}, +} + +@inproceedings{Dardinier22, + author = {Dardinier, Thibault and Parthasarathy, Gaurav and Weeks, No\'e and M\"uller, Peter and Summers, Alexander J.}, + title = {{Sound Automation of Magic Wands}}, + booktitle = {Computer Aided Verification (CAV)}, + year = {2022}, + note = {To appear} +} + +@inproceedings{Reynolds02a, + author = {J. C. Reynolds}, + title = {{Separation Logic: A Logic for Shared Mutable Data Structures}}, + booktitle = {Logic in Computer Science (LICS)}, + Publisher = {IEEE}, + pages = {55--74}, + year = {2002} +} diff --git a/thys/Package_logic/document/root.tex b/thys/Package_logic/document/root.tex new file mode 100644 --- /dev/null +++ b/thys/Package_logic/document/root.tex @@ -0,0 +1,78 @@ +\documentclass[11pt,a4paper]{article} +\usepackage[T1]{fontenc} +\usepackage{isabelle,isabellesym} + +% further packages required for unusual symbols (see also +% isabellesym.sty), use only when needed + +%\usepackage{amssymb} + %for \, \, \, \, \, \, + %\, \, \, \, \, + %\, \, \ + +%\usepackage{eurosym} + %for \ + +%\usepackage[only,bigsqcap,bigparallel,fatsemi,interleave,sslash]{stmaryrd} + %for \, \, \, \, \ + +%\usepackage{eufrak} + %for \ ... \, \ ... \ (also included in amssymb) + +%\usepackage{textcomp} + %for \, \, \, \, \, + %\ + +% this should be the last package used +\usepackage{pdfsetup} + +% urls in roman style, theory text in math-similar italics +\urlstyle{rm} +\isabellestyle{it} + +% for uniform font size +%\renewcommand{\isastyle}{\isastyleminor} + +\newcommand{\wand}{\ensuremath{\mathbin{-\!\!*}}} +\newcommand{\cwand}{\ensuremath{\mathbin{-\!\!*}_c}} +\newcommand{\twand}{\ensuremath{\mathbin{-\!\!*}_{\mathcal{T}}}} + +\begin{document} + +\title{Formalization of a Framework for the Sound Automation of Magic Wands} +\author{Thibault Dardinier} +\maketitle + +\begin{abstract} +The magic wand $\wand$ (also called separating implication) is a separation logic~\cite{Reynolds02a} connective % I find it a bit tricky that we talk about the connective and a formula built from it as if these were the same thing +commonly used to specify properties of partial data structures, +for instance during iterative traversals. +A \emph{footprint} of a magic wand formula $A \wand B$ is a state that, combined with any state in which $A$ holds, yields a state in which $B$ holds. +The key challenge of proving a magic wand (also called \emph{packaging} a wand) is to find such a footprint. +Existing package algorithms either have a high annotation overhead or are unsound. + +In this entry, we formally define a framework for the sound automation of magic wands, described in a paper at CAV~2022~\cite{Dardinier22}, +and prove that it is sound and complete. +This framework, called the \emph{package logic}, precisely characterises a wide design space of possible package algorithms applicable to a large class of separation logics. +%Moreover, we define a novel, restricted definition of wands, called \emph{combinable wands}, and prove that it is possible to soundly combine fractions of such wands, which is not the case for arbitrary wands. +%Finally, we instantiate the package logic to show our framework can also be used with combinable wands. +\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/Pluennecke_Ruzsa_Inequality/Pluennecke_Ruzsa_Inequality.thy b/thys/Pluennecke_Ruzsa_Inequality/Pluennecke_Ruzsa_Inequality.thy new file mode 100644 --- /dev/null +++ b/thys/Pluennecke_Ruzsa_Inequality/Pluennecke_Ruzsa_Inequality.thy @@ -0,0 +1,750 @@ +section\The Pl\"{u}nnecke-Ruzsa Inequality\ + +text\Authors: Angeliki Koutsoukou-Argyraki and Lawrence C. Paulson, University of Cambridge.\ + +text\We formalise Pl\"{u}nnecke's inequality and the Pl\"{u}nnecke-Ruzsa inequality, +following the notes by Timothy Gowers: "Introduction to Additive +Combinatorics" (2022) for the University of Cambridge. To this end, we first introduce basic definitions +and prove elementary facts on sumsets and difference sets. Then, we show (two versions of) +the Ruzsa triangle inequality. We follow with a proof due to Petridis. \ + +theory Pluennecke_Ruzsa_Inequality + imports + "Jacobson_Basic_Algebra.Ring_Theory" + Complex_Main + +begin + +notation plus (infixl "+" 65) +notation minus (infixl "-" 65) +notation uminus ("- _" [81] 80) + +subsection \Key definitions (sumset, difference set) and basic lemmas \ + +text \Working in an arbitrary Abelian group, with additive syntax\ + +locale additive_abelian_group = abelian_group G "(\)" \ + for G and addition (infixl "\" 65) and zero ("\") + +begin + +abbreviation G_minus:: "'a \ 'a \ 'a" (infixl "\" 70) + where "x \ y \ x \ inverse y " + +lemma inverse_closed: "x \ G \ inverse x \ G" + by blast + + +subsubsection \Sumsets\ + +inductive_set sumset :: "'a set \ 'a set \ 'a set" for A B + where + sumsetI[intro]: "\a \ A; a \ G; b \ B; b \ G\ \ a \ b \ sumset A B" + +lemma sumset_eq: "sumset A B = {c. \a \ A \ G. \b \ B \ G. c = a \ b}" + by (auto simp: sumset.simps elim!: sumset.cases) + +lemma sumset: "sumset A B = (\a \ A \ G. \b \ B \ G. {a \ b})" + by (auto simp: sumset_eq) + +lemma sumset_subset_carrier: "sumset A B \ G" + by (auto simp: sumset_eq) + +lemma sumset_Int_carrier [simp]: "sumset A B \ G = sumset A B" + by (simp add: Int_absorb2 sumset_subset_carrier) + +lemma sumset_mono: "\A' \ A; B' \ B\ \ sumset A' B' \ sumset A B" + by (auto simp: sumset_eq) + +lemma sumset_insert1: "NO_MATCH {} A \ sumset (insert x A) B = sumset {x} B \ sumset A B" + by (auto simp: sumset_eq) + +lemma sumset_insert2: "NO_MATCH {} B \ sumset A (insert x B) = sumset A {x} \ sumset A B" + by (auto simp: sumset_eq) + +lemma sumset_subset_Un1: "sumset (A \ A') B = sumset A B \ sumset A' B" + by (auto simp: sumset_eq) + +lemma sumset_subset_Un2: "sumset A (B \ B') = sumset A B \ sumset A B'" + by (auto simp: sumset_eq) + +lemma sumset_subset_insert: "sumset A B \ sumset A (insert x B)" "sumset A B \ sumset (insert x A) B" + by (auto simp: sumset_eq) + +lemma sumset_subset_Un: "sumset A B \ sumset A (B\C)" "sumset A B \ sumset (A\C) B" + by (auto simp: sumset_eq) + +lemma sumset_empty [simp]: "sumset A {} = {}" "sumset {} A = {}" + by (auto simp: sumset_eq) + +lemma sumset_empty': + assumes "A \ G = {}" + shows "sumset B A = {}" "sumset A B = {}" + using assms by (auto simp: sumset_eq) + +lemma sumset_is_empty_iff [simp]: "sumset A B = {} \ A \ G = {} \ B \ G = {}" + by (auto simp: sumset_eq) + +lemma sumset_D [simp]: "sumset A {\} = A \ G" "sumset {\} A = A \ G" + by (auto simp: sumset_eq) + +lemma sumset_Int_carrier_eq [simp]: "sumset A (B \ G) = sumset A B" "sumset (A \ G) B = sumset A B" + by (auto simp: sumset_eq) + +lemma sumset_assoc: + shows "sumset (sumset A B) C = sumset A (sumset B C)" + by (fastforce simp add: sumset_eq associative Bex_def) + +lemma sumset_commute: + shows "sumset A B = sumset B A" + by (auto simp: sumset_eq; meson Int_iff commutative) + +lemma finite_sumset: + assumes "finite A" "finite B" shows "finite (sumset A B)" + using assms by (auto simp: sumset_eq) + +lemma finite_sumset': + assumes "finite (A \ G)" "finite (B \ G)" + shows "finite (sumset A B)" + using assms by (auto simp: sumset_eq) + +lemma sumsetdiff_sing: "sumset (A - B) {x} = sumset A {x} - sumset B {x}" + by (auto simp: sumset_eq) + +lemma card_sumset_singleton_eq: + assumes "finite A" shows "card (sumset A {a}) = (if a \ G then card (A \ G) else 0)" +proof (cases "a \ G") + case True + then have "sumset A {a} = (\x. x \ a) ` (A \ G)" + by (auto simp: sumset_eq) + moreover have "inj_on (\x. x \ a) (A \ G)" + by (auto simp: inj_on_def True) + ultimately show ?thesis + by (metis True card_image) +qed (auto simp: sumset_eq) + +lemma card_sumset_le: + assumes "finite A" shows "card (sumset A {a}) \ card A" + by (simp add: assms card_mono card_sumset_singleton_eq) + +lemma infinite_sumset_aux: + assumes "infinite (A \ G)" + shows "infinite (sumset A B) \ B \ G \ {}" +proof (cases "B \ G = {}") + case False + then obtain b where b: "b \ B" "b \ G" by blast + with assms commutative have "((\)b) ` (A \ G) \ sumset A B" + by (auto simp: sumset) + moreover have "inj_on ((\)b) (A \ G)" + by (meson IntD2 b inj_onI invertible invertible_left_cancel) + ultimately show ?thesis + by (metis False assms inj_on_finite) +qed (auto simp: sumset_eq) + +lemma infinite_sumset_iff: + shows "infinite (sumset A B) \ infinite (A \ G) \ B \ G \ {} \ A \ G \ {} \ infinite (B \ G)" + by (metis (no_types, lifting) finite_sumset' infinite_sumset_aux sumset_commute) + +lemma card_le_sumset: + assumes A: "finite A" "a \ A" "a \ G" + and B: "finite B" "B \ G" + shows "card B \ card (sumset A B)" +proof - + have "B \ (\) (inverse a) ` sumset A B" + using A B + apply (clarsimp simp: sumset image_iff) + by (metis Int_absorb2 Int_iff invertible invertible_left_inverse2) + with A B show ?thesis + by (meson finite_sumset surj_card_le) +qed + +lemma card_sumset_0_iff': "card (sumset A B) = 0 \ card (A \ G) = 0 \ card (B \ G) = 0" +proof (cases "infinite (A \ G) \ infinite (B \ G)") + case True + then show ?thesis + by (metis card_eq_0_iff infinite_sumset_iff sumset_empty') +qed (auto simp: sumset_eq) + +lemma card_sumset_0_iff: + assumes "A \ G" "B \ G" + shows "card (sumset A B) = 0 \ card A = 0 \ card B = 0" + by (metis assms le_iff_inf card_sumset_0_iff') + +lemma card_sumset_leq: + assumes "A \ G" + shows "card(sumset A A) \ Suc(card A) choose 2" + using assms +proof (induction "card A" arbitrary: A) + case 0 + then show ?case + by (metis card_sumset_0_iff zero_le) +next + case (Suc n A) + then obtain a A' where a: "a \ A" "A' = A - {a}" "a \ G" + by (metis Zero_neq_Suc card_eq_0_iff subset_empty subset_eq) + then have n: "card A' = n" + by (metis Suc(2) card_Diff_singleton diff_Suc_Suc minus_nat.diff_0 One_nat_def) + have "finite A" + by (metis Suc(2) Zero_neq_Suc card.infinite) + have "card (sumset A A) \ card (sumset A' A') + card A" + proof - + have A: "A = A' \ {a}" + using a by auto + then have "sumset A A = (sumset A' A') \ (sumset A {a})" + by (auto simp: sumset_eq commutative) + with a \finite A\ card_sumset_le show ?thesis + by (simp add: order_trans[OF card_Un_le]) + qed + also have "\ \ (card A) choose 2 + card A" + using Suc a by (metis add_le_mono1 insert_Diff_single insert_absorb insert_subset n) + also have "\ \ Suc (card A) choose 2" + by (simp add: numeral_2_eq_2) + finally show ?case . +qed + + +subsubsection \Iterated sumsets\ + +definition sumset_iterated :: "'a set \ nat \ 'a set" + where "sumset_iterated A r \ Finite_Set.fold (sumset \ (\_. A)) {\} {..}" + by (simp add: sumset_iterated_def) + +lemma sumset_iterated_Suc [simp]: "sumset_iterated A (Suc k) = sumset A (sumset_iterated A k)" + (is "?lhs = ?rhs") +proof - + interpret comp_fun_commute_on "{..k}" "sumset \ (\_. A)" + using sumset_assoc sumset_commute by (auto simp: comp_fun_commute_on_def) + have "?lhs = (sumset \ (\_. A)) k (Finite_Set.fold (sumset \ (\_. A)) {\} {.. = ?rhs" + by (simp add: sumset_iterated_def) + finally show ?thesis . +qed + +lemma sumset_iterated_2: + shows "sumset_iterated A 2 = sumset A A" + by (simp add: eval_nat_numeral) + +lemma sumset_iterated_r: "r > 0 \ sumset_iterated A r = sumset A (sumset_iterated A (r-1))" + using gr0_conv_Suc by force + +lemma sumset_iterated_subset_carrier: "sumset_iterated A k \ G" + by (cases k; simp add: sumset_subset_carrier) + +lemma finite_sumset_iterated: "finite A \ finite (sumset_iterated A r)" + by(induction r) (auto simp: finite_sumset) + +lemma sumset_iterated_empty: "r>0 \ sumset_iterated {} r = {}" + by (induction r) auto + +subsubsection \Difference sets\ + +inductive_set minusset :: "'a set \ 'a set" for A + where + minussetI[intro]: "\a \ A; a \ G\ \ inverse a \ minusset A" + +lemma minusset_eq: "minusset A = inverse ` (A \ G)" + by (auto simp: minusset.simps) + + +abbreviation "differenceset A B \ sumset A (minusset B)" + +lemma minusset_is_empty_iff [simp]: "minusset A = {} \ A \ G = {}" + by (auto simp: minusset_eq) + +lemma minusset_triv [simp]: "minusset {\} = {\}" + by (auto simp: minusset_eq) + +lemma minusset_subset_carrier: "minusset A \ G" + by (auto simp: minusset_eq) + +lemma minus_minusset [simp]: "minusset (minusset A) = A \ G" + apply (auto simp: minusset_eq) + by (metis inverse_equality invertible invertibleE minusset.minussetI minusset_eq) + +lemma card_minusset [simp]: "card (minusset A) = card (A \ G)" +proof (rule bij_betw_same_card) + show "bij_betw (inverse) (minusset A) (A \ G)" + unfolding minusset_eq by (force intro: bij_betwI) +qed + +lemma card_minusset': "A \ G \ card (minusset A) = card A" + by (simp add: Int_absorb2) + +lemma diff_minus_set: + "differenceset (minusset A) B = minusset (sumset A B)" (is "?lhs = ?rhs") +proof (rule Set.set_eqI) + fix u + have "u \ ?lhs \ + (\x \ A \ G. \y \ B \ G. u = inverse x \ y)" + by (auto simp: sumset minusset_eq) + also have "\ \ (\x \ A \ G. \y \ B \ G. u = inverse (y \ x))" + using inverse_composition_commute by auto + also have "\ \ u \ ?rhs" + by (auto simp: sumset minusset_eq commutative) + finally show "u \ ?lhs \ u \ ?rhs" . +qed + +lemma differenceset_commute [simp]: + shows "minusset (differenceset B A) = differenceset A B " + by (metis diff_minus_set minus_minusset sumset_Int_carrier_eq(1) sumset_commute) + +lemma minusset_distrib_sum: + shows "minusset (sumset A B) = sumset (minusset A) (minusset B)" + by (simp add: diff_minus_set) + +lemma minusset_iterated_minusset: "sumset_iterated (minusset A) k = minusset (sumset_iterated A k)" + by (induction k) (auto simp: diff_minus_set) + +lemma card_sumset_iterated_minusset: + "card (sumset_iterated (minusset A) k) = card (sumset_iterated A k)" + by (metis card_minusset' minusset_iterated_minusset sumset_iterated_subset_carrier) + +lemma finite_minusset: "finite A \ finite (minusset A)" + by (simp add: minusset_eq) + + +subsection\The Ruzsa triangle inequality\ + +lemma Ruzsa_triangle_ineq1: + assumes U: "finite U" "U \ G" + and V: "finite V" "V \ G" + and W: "finite W" "W \ G" + shows "(card U) * card(differenceset V W) \ card (differenceset U V) * card (differenceset U W)" +proof - + have fin: "finite (differenceset U V)" "finite (differenceset U W)" + using U V W finite_minusset finite_sumset by auto + have "\v w. v \ V \ w \ W \ x = v \ w" if "x \ differenceset V W" for x + using that by (auto simp: sumset_eq minusset_eq) + then obtain v w where vinV: "v x \ V" and winW: "w x \ W" and vw_eq: "v x \ (w x) = x" + if "x \ differenceset V W" for x by metis + have vinG: "v x \ G" and winG: "w x \ G" if "x \ differenceset V W" for x + using V W that vinV winW by auto + define \ where "\ \ \(u,x). (u \ (v x), u \ (w x))" + have "inj_on \ (U \ differenceset V W)" + proof (clarsimp simp add: \_def inj_on_def) + fix u1 :: 'a and x1 :: 'a and u2 :: 'a and x2 :: 'a + assume "u1 \ U" "u2 \ U" + and x1: "x1 \ differenceset V W" + and x2: "x2 \ differenceset V W" + and v: "u1 \ v x1 = u2 \ v x2" + and w: "u1 \ w x1 = u2 \ w x2" + then obtain "u1 \ G" "u2 \ G" "x1 \ G" "x2 \ G" + by (meson \U \ G\ subset_iff sumset_subset_carrier) + show "u1 = u2 \ x1 = x2" + proof + have "v x1 \ w x1 = (u1 \ w x1) \ (u1 \ v x1)" + by (smt (verit, del_insts) \u1 \ G\ associative commutative composition_closed inverse_closed + invertible invertible_right_inverse2 vinG winG x1) + also have "\ = (u2 \ w x2) \ (u2 \ v x2)" + using v w by presburger + also have "\ = v x2 \ w x2" + by (smt (verit, del_insts) \u2 \ G\ associative commutative composition_closed inverse_equality + invertible invertible_def invertible_right_inverse2 vinG winG x2) + finally have "v x1 \ w x1 = v x2 \ w x2" . + then show "x1=x2" + by (simp add: x1 x2 vw_eq) + then show "u1=u2" + using \u1 \ G\ \u2 \ G\ w winG x1 by force + qed + qed + moreover have "\ \ (U \ differenceset V W) \ (differenceset U V) \ (differenceset U W)" + using \U \ G\ \V \ G\ \W \ G\ + by (fastforce simp: \_def intro: vinV winW) + ultimately have "card (U \ differenceset V W) \ card (differenceset U V \ differenceset U W)" + using card_inj fin by blast + then show ?thesis + by (simp flip: card_cartesian_product) +qed + + + +definition Ruzsa_distance:: "'a set \ 'a set \ real" + where "Ruzsa_distance A B \ card(differenceset A B)/(sqrt(card A) * sqrt(card B))" + +lemma Ruzsa_triangle_ineq2: + assumes U: "finite U" "U \ G" "U \ {}" + and V: "finite V" "V \ G" + and W: "finite W" "W \ G" + shows "Ruzsa_distance V W \ (Ruzsa_distance V U) * (Ruzsa_distance U W)" +proof - + have "card U * card (differenceset V W) \ card (differenceset U V) * card (differenceset U W)" + using assms Ruzsa_triangle_ineq1 by metis + \\now divide both sides with the same quantity\ + then have "card U * card (differenceset V W) / (card U * sqrt (card V) * sqrt (card W)) + \ card (differenceset U V) * card (differenceset U W) / (card U * sqrt (card V) * sqrt (card W))" + using assms + by (metis divide_right_mono mult_eq_0_iff mult_left_mono of_nat_0_le_iff of_nat_mono real_sqrt_ge_0_iff) + then have *: "card(differenceset V W) / (sqrt(card V) * sqrt(card W)) \ + card (differenceset U V) * card (differenceset U W) + / (card U * sqrt(card V) * sqrt(card W))" + using assms by simp + have "card (differenceset U V) * card (differenceset U W)/(card U * sqrt(card V) * sqrt(card W)) + = card(differenceset V U) / (sqrt(card U) * sqrt(card V))* + card(differenceset U W) / (sqrt(card U) * sqrt(card W))" + using assms + by (simp add: divide_simps) (metis card_minusset differenceset_commute minus_minusset) + then have + "card(differenceset V W) / (sqrt(card V) * sqrt(card W)) \ + card(differenceset V U) / (sqrt(card U) * sqrt(card V)) * + card(differenceset U W) / (sqrt(card U) * sqrt(card W))" + using * assms by auto + then show ?thesis unfolding Ruzsa_distance_def + by (metis divide_divide_eq_left divide_divide_eq_left' times_divide_eq_right) +qed + + +subsection \Petridis's proof of the Pl\"{u}nnecke-Ruzsa inequality \ + +lemma Plu_2_2: + assumes K0: "card (sumset A0 B) \ K0 * real (card A0)" + and A0: "finite A0" "A0 \ G" "A0 \ {}" + and B: "finite B" "B \ G" "B \ {}" + obtains A K + where "A \ A0" "A \ {}" "0 < K" "K \ K0" + and "\C. C \ G \ finite C \ card (sumset A (sumset B C)) \ K * real (card(sumset A C))" +proof + define KS where "KS \ (\A. card (sumset A B) / real (card A)) ` (Pow A0 - {{}})" + define K where "K \ Min KS" + define A where "A \ @A. A \ Pow A0 - {{}} \ K = card (sumset A B) / real (card A)" + obtain KS: "finite KS" "KS \ {}" + using KS_def A0 by blast + then have "K \ KS" + using K_def Min_in by blast + then have "\A. A \ Pow A0 - {{}} \ K = card (sumset A B) / real (card A)" + using KS_def by blast + then obtain "A \ Pow A0 - {{}}" and Keq: "K = card (sumset A B) / real (card A)" + by (metis (mono_tags, lifting) A_def someI_ex) + then show A: "A \ A0" "A \ {}" + by auto + with A0 finite_subset have "A \ G" "finite A" + by blast+ + have gt0: "0 < real (card (sumset A B)) / real (card A)" if "A \ {}" and "A \ A0" for A + using that assms + by (smt (verit, best) order_trans card_0_eq card_sumset_0_iff divide_pos_pos of_nat_le_0_iff finite_subset) + then show "K > 0" + using A Keq by presburger + have K_cardA: "K * (card A) = card (sumset A B)" + unfolding Keq using Keq \0 < K\ by force + have K_le: "real (card (sumset A' B)) / card A' \ K" if "A' \ A" "A' \ {}" for A' + using KS K_def KS_def \A \ A0\ that by force + with A0 have "card (sumset A0 B) / real (card A0) \ KS" + by (auto simp: KS_def) + with A0 show "K \ K0" + by (metis KS K_def Min_le_iff card_gt_0_iff mult_imp_div_pos_le of_nat_0_less_iff K0) + show "card (sumset A (sumset B C)) \ K * real (card(sumset A C))" + if "finite C" "C \ G" for C + using that + proof (induction C) + case empty + then show ?case by simp + \ \This is actually trivial: it does not follow from @{term "card (sumset A B) = K * card A"} + as claimed in the notes.\ + next + case (insert x C) + then have "x \ G" "C \ G" "finite C" + by auto + define A' where "A' \ A \ {a. (a\x) \ sumset A C}" + with \finite A\ have "finite A'" "A' \ A" by auto + then have [simp]: "real (card A - card A') = real (card A) - real (card A')" + by (meson \finite A\ card_mono of_nat_diff) + have 0: "sumset A C \ sumset (A - A') {x} = {}" + by (clarsimp simp add: A'_def sumset_eq disjoint_iff) (metis IntI) + have 1: "sumset A (insert x C) = sumset A C \ sumset (A - A') {x}" + by (auto simp: A'_def sumset_eq) + have "card (sumset A (insert x C)) = card (sumset A C) + card (sumset (A - A') {x})" + by (simp add: 0 1 \finite A\ card_Un_disjoint finite_sumset local.insert) + also have "\ = card (sumset A C) + card ((A - A') \ G)" + using \finite A\ \x \ G\ by (simp add: card_sumset_singleton_eq) + also have "\ = card (sumset A C) + card (A - A')" + by (metis \A \ G\ Int_absorb2 Int_Diff Int_commute) + also have "\ = card (sumset A C) + (card A - card A')" + by (simp add: A'_def \finite A\ card_Diff_subset) + finally have *: "card (sumset A (insert x C)) = card (sumset A C) + (card A - card A')" . + have "sumset A' (sumset B {x}) \ sumset A (sumset B C)" + by (clarsimp simp add: A'_def sumset_eq Bex_def) (metis associative commutative composition_closed) + then have "sumset A (sumset B (insert x C)) + \ sumset A (sumset B C) \ (sumset A (sumset B {x}) - sumset A' (sumset B {x}))" + by (auto simp: sumset_insert2 sumset_subset_Un2) + then have "card (sumset A (sumset B (insert x C))) \ card (sumset A (sumset B C)) + + card ((sumset A (sumset B {x}) - sumset A' (sumset B {x})))" + by (smt (verit, best) B(1) \finite A\ \finite C\ order_trans card_Un_le card_mono finite.emptyI + finite.insertI finite_Diff finite_Un finite_sumset) + also have "\ = card (sumset A (sumset B C)) + (card (sumset A (sumset B {x})) - card (sumset A' (sumset B {x})))" + by (simp add: \A' \ A\ \finite A'\ \finite B\ card_Diff_subset finite_sumset sumset_mono) + also have "\ \ card (sumset A (sumset B C)) + (card (sumset A B) - card (sumset A' B))" + using \finite A\ \finite A'\ \finite B\ by (simp add: card_sumset_singleton_eq finite_sumset flip: sumset_assoc) + also have "\ \ K * card (sumset A C) + (K * card A - K * card A')" + proof (cases "A' = {}") + case True + with local.insert \C \ G\ K_cardA show ?thesis by auto + next + case False + then have "K * card A' \ real (card (sumset A' B))" + using K_le[OF \A' \ A\] by (simp add: divide_simps split: if_split_asm) + then have "real (card (sumset A B) - card (sumset A' B)) \ K * real (card A) - K * real (card A')" + by (simp add: B(1) K_cardA \A' \ A\ \finite A\ card_mono finite_sumset of_nat_diff sumset_mono) + with local.insert show ?thesis by simp + qed + also have "\ \ K * real (card (sumset A (insert x C)))" + using * \A' \ A\ by (simp add: algebra_simps) + finally show ?case + using of_nat_mono by blast + qed +qed + +lemma Cor_Plu_2_3: + assumes K: "card (sumset A B) \ K * real (card A)" + and A: "finite A" "A \ G" "A \ {}" + and B: "finite B" "B \ G" + obtains A' where "A' \ A" "A' \ {}" + "\r. card (sumset A' (sumset_iterated B r)) \ K^r * real (card A')" +proof (cases "B = {}") + case True + have "K \ 0" + using assms by (simp add: True zero_le_mult_iff) + moreover have *: "sumset_iterated B r = (if r=0 then {\} else {})" for r + by (metis True sumset_iterated_0 sumset_iterated_empty zero_less_iff_neq_zero) + ultimately have "real (card (sumset A (sumset_iterated B r))) + \ K ^ r * real (card A)" for r + by (simp add: "*" Int_commute Int_absorb2 \A \ G\) + with \A \ {}\ that show ?thesis by blast +next + case False + obtain A' K' + where A': "A' \ A" "A' \ {}" "0 < K'" "K' \ K" + and A'_card: "\C. C \ G \ finite C \ card (sumset A' (sumset B C)) \ K' * real (card(sumset A' C))" + by (metis A B Plu_2_2 K False) + with A have "A' \ G" by blast + have *: "card (sumset A' (sumset_iterated B (Suc r))) \ K' * card (sumset A' (sumset_iterated B r))" + (is "?lhs \ ?rhs") + for r + proof - + have "?lhs = card (sumset A' (sumset B (sumset_iterated B r)))" + using that by (simp add: sumset_iterated_r) + also have "\ \ ?rhs" + using A'_card B finite_sumset_iterated sumset_iterated_subset_carrier by meson + finally show ?thesis . + qed + have **: "card (sumset A' (sumset_iterated B r)) \ K'^r * real (card A')" for r + proof (induction r) + case 0 + with \A' \ G\ show ?case + by (simp add: Int_absorb2) + next + case (Suc r) + then show ?case + by (smt (verit) "*" \0 < K'\ mult.commute mult.left_commute mult_le_cancel_left_pos power_Suc) + qed + show thesis + proof + show "real (card (sumset A' (sumset_iterated B r))) \ K ^ r * real (card A')" for r + by (meson "**" A' order_trans less_eq_real_def mult_right_mono of_nat_0_le_iff power_mono) + qed (use A' in auto) +qed + + +text\The following Corollary of the above is an important special case, +also referred to as the original version of Pl\"{u}nnecke's inequality first shown by Pl\"{u}nnecke. \ + +lemma Cor_Plu_2_3_Pluennecke_ineq: + assumes K: "card (sumset A B) \ K * real (card A)" + and A: "finite A" "A \ G" "A \ {}" + and B: "finite B" "B \ G" + shows "real (card (sumset_iterated B r)) \ K ^ r * real (card A)" +proof- + obtain A' where *:"A' \ A" "A' \ {}" + "card (sumset A' (sumset_iterated B r)) \ K^r * real (card A')" + using assms Cor_Plu_2_3 by metis + with assms have **: "card (sumset_iterated B r) \ card (sumset A' (sumset_iterated B r))" + by (meson card_le_sumset finite_subset finite_sumset_iterated subset_empty subset_iff sumset_iterated_subset_carrier) + with * show ?thesis + by (smt (verit, best) A(1) K card_mono mult_left_mono of_nat_0_le_iff of_nat_le_iff zero_le_mult_iff zero_le_power) +qed + +text \Special case where @{term "B=A"}\ +lemma Cor_Plu_2_3_1: + assumes K: "card (sumset A A) \ K * real (card A)" + and A: "finite A" "A \ G" "A \ {}" + shows "card (sumset_iterated A r) \ K^r * real (card A)" +proof - + have "K > 0" + by (meson A K Plu_2_2 less_le_trans) + obtain A' where A': "A' \ A" "A' \ {}" + and A'_card: "\r. card (sumset A' (sumset_iterated A r)) \ K^r * real (card A')" + by (meson A Cor_Plu_2_3 K) + with A obtain a where "a \ A'" "a \ G" "finite A'" + by (metis ex_in_conv finite_subset subset_iff) + then have "card (sumset_iterated A r) \ card (sumset A' (sumset_iterated A r))" + using A card_le_sumset finite_sumset_iterated sumset_iterated_subset_carrier by meson + also have "\ \ K^r * real (card A')" + using A'_card by meson + also have "\ \ K^r * real (card A)" + by (simp add: \A' \ A\ \finite A\ \0 < K\ card_mono) + finally show ?thesis + by linarith +qed + + +text \Special case where @{term "B=-A"}\ +lemma Cor_Plu_2_3_2: + assumes K: "card (differenceset A A) \ K * real (card A)" + and A: "finite A" "A \ G" "A \ {}" + shows "card (sumset_iterated A r) \ K^r * real (card A)" +proof - + have "card A > 0" + by (simp add: A card_gt_0_iff) + with K have "K \ 0" + by (smt (verit, del_insts) of_nat_0_less_iff of_nat_less_0_iff zero_le_mult_iff) + obtain A' where A': "A' \ A" "A' \ {}" + and A'_card: "\r. card (sumset A' (sumset_iterated (minusset A) r)) \ K^r * real (card A')" + by (metis A Cor_Plu_2_3 assms(1) card_eq_0_iff card_minusset' minusset_subset_carrier) + with A obtain a where "a \ A'" "a \ G" "finite A'" + by (metis ex_in_conv finite_subset subset_iff) + then have "card (sumset_iterated A r) \ card (sumset A' (sumset_iterated (minusset A) r))" + by (metis A(1) card_le_sumset card_sumset_iterated_minusset finite_minusset finite_sumset_iterated sumset_iterated_subset_carrier) + also have "\ \ K^r * real (card A')" + using A'_card by meson + also have "\ \ K^r * real (card A)" + by (simp add: \A' \ A\ \finite A\ \0 \ K\ card_mono mult_left_mono) + finally show ?thesis + by linarith +qed + +text \The following result is known as the Pl\"{u}nnecke-Ruzsa inequality (Theorem 2.5 +in Gowers's notes). The proof will make use of the Ruzsa triangle inequality.\ + +theorem Pluennecke_Ruzsa_ineq: + assumes K: "card (sumset A B) \ K * real (card A)" + and A: "finite A" "A \ G" "A \ {}" + and B: "finite B" "B \ G" + and "0 < r" "0 < s" + shows "card (differenceset (sumset_iterated B r) (sumset_iterated B s)) \ K^(r+s) * real(card A)" +proof - + have "card A > 0" + by (simp add: A card_gt_0_iff) + with K have "K \ 0" + by (smt (verit, del_insts) of_nat_0_less_iff of_nat_less_0_iff zero_le_mult_iff) + obtain A' where A': "A' \ A" "A' \ {}" + and A'_le: "\r. card (sumset A' (sumset_iterated B r)) \ K^r * real (card A')" + using Cor_Plu_2_3 assms by metis + define C where "C \ minusset A'" + have "minusset C = A'" and "C \{}" and cardA: "card A' \ card A" and cardC: "card C = card A'" + using A' A card_mono by (auto simp: C_def card_minusset' Int_absorb2) + then have cardCA: "card C \ card A" by linarith + have "\r. card (differenceset C (sumset_iterated B r)) \ K^r * real (card A')" + using A'_le C_def card_minusset' diff_minus_set sumset_subset_carrier by presburger + then have r: "card (differenceset C (sumset_iterated B r)) \ K^r * real (card C)" + and s: "card (differenceset C (sumset_iterated B s)) \ K^s * real (card C)" + using cardC by presburger+ + have "card C > 0" + by (metis A' \finite A\ cardC card_gt_0_iff finite_subset) + moreover have "C \ G" + by (simp add: C_def minusset_subset_carrier) + ultimately have "card C * card (differenceset (sumset_iterated B r) (sumset_iterated B s)) + \ card (differenceset C (sumset_iterated B r)) * + card (differenceset C (sumset_iterated B s))" + by (meson Ruzsa_triangle_ineq1 B card_gt_0_iff finite_sumset_iterated sumset_iterated_subset_carrier) + also have "\ \ K^(r+s) * card C * card C" + using mult_mono [OF r s] \0 \ K\ by (simp add: power_add field_simps) + finally have "card (differenceset (sumset_iterated B r) (sumset_iterated B s)) \ K^(r+s) * card C" + using \card C > 0\ by (simp add: field_simps) + then show ?thesis + by (smt (verit, ccfv_SIG) \0 \ K\ cardA cardC mult_left_mono of_nat_mono zero_le_power) +qed + +text \The following is an alternative version of the Pl\"{u}nnecke-Ruzsa inequality (Theorem 2.1 +in Gowers's notes).\ + +theorem Pluennecke_Ruzsa_ineq_alt: + assumes "finite A" "A \ G" + and "card (sumset A A) \ K * real (card A)" "r > 0" "s > 0" + shows "card (differenceset (sumset_iterated A r) (sumset_iterated A s)) \ K^(r+s) * real(card A)" +proof (cases "A = {}") + case True + then have "sumset_iterated A r = {}" if "r>0" for r + using sumset_iterated_empty that by force + with assms show ?thesis + by (auto simp: True) +next + case False + with assms Pluennecke_Ruzsa_ineq show ?thesis by presburger +qed + +theorem Pluennecke_Ruzsa_ineq_alt_2: + assumes "finite A" "A \ G" + and "card (differenceset A A) \ K * real (card A)" "r > 0" "s > 0" + shows "card (differenceset (sumset_iterated A r) (sumset_iterated A s)) \ K^(r+s) * real(card A)" +proof (cases "A = {}") + case True + then have "sumset_iterated A r = {}" if "r>0" for r + using sumset_iterated_empty that by force + with assms show ?thesis + by (auto simp: True) +next + case False + with assms Pluennecke_Ruzsa_ineq show ?thesis + by (smt (verit, ccfv_threshold) card_minusset' differenceset_commute finite_minusset + minusset_distrib_sum minusset_iterated_minusset minusset_subset_carrier) +qed + +end + + +subsection \Supplementary material on sumsets for sets of integers: basic inequalities\ + +lemma moninv_int: "monoid.invertible UNIV (+) 0 u" for u::int + using monoid.invertibleI [where v = "-u"] by (simp add: Group_Theory.monoid_def) + +interpretation int: additive_abelian_group UNIV "(+)" "0::int" + by unfold_locales (use moninv_int in auto) + +lemma card_sumset_geq1: + assumes A: "A \ {}" "finite A" and B: "B \ {}" "finite B" + shows "card(int.sumset A B) \ (card A) + (card B) - 1" + using A +proof (induction "card A" arbitrary: A) + case (Suc n) + define a where "a = Max A" + define A' where "A' \ A - {a}" + then obtain a: "a \ A" "A' = A - {a}" "finite A'" "a \ A'" and A: "A = insert a A'" + using Max_in Suc a_def by blast + with Suc have n: "card A' = n" + by (metis card_Diff_singleton diff_Suc_Suc minus_nat.diff_0 One_nat_def) + show ?case + proof (cases "A' = {}") + case True + then show ?thesis + by (simp add: A B(2) int.card_sumset_singleton_eq int.sumset_commute) + next + case False + have "a + Max B \ int.sumset A' B" + using \finite A\ \finite B\ + by (smt (verit, best) DiffE Max_ge a a_def int.sumset.cases singleton_iff) + then have *: "\ int.sumset A' B \ (+) a ` B \ int.sumset A' B" + using B Max_in by blast + have "card A + card B - 1 \ Suc (card (int.sumset A' B))" + using Suc False A a using le_diff_conv by force + also have "\ \ card (int.sumset A' B \ (+) a ` B)" + using a B + by (metis "*" card_seteq finite_Un finite_imageI int.finite_sumset not_less_eq_eq sup_ge1) + also have "\ \ card (int.sumset A B)" + proof (rule card_mono) + show "finite (int.sumset A B)" + using B Suc.prems int.finite_sumset by blast + show "int.sumset A' B \ (+) a ` B \ int.sumset A B" + using A by (force simp: int.sumset) + qed + finally show ?thesis . + qed +qed auto + +lemma card_sumset_geq2: + shows "card(int.sumset A A) \ 2 * (card A) - 1" + using card_sumset_geq1 [of A] + by (metis mult.commute Nat.add_0_right card_eq_0_iff diff_0_eq_0 le0 mult_2_right) + +end diff --git a/thys/Pluennecke_Ruzsa_Inequality/ROOT b/thys/Pluennecke_Ruzsa_Inequality/ROOT new file mode 100644 --- /dev/null +++ b/thys/Pluennecke_Ruzsa_Inequality/ROOT @@ -0,0 +1,12 @@ +chapter AFP + +session Pluennecke_Ruzsa_Inequality (AFP) = "HOL-Library" + + options [timeout = 600] + sessions + "Jacobson_Basic_Algebra" + theories + Pluennecke_Ruzsa_Inequality + document_files + "root.tex" + "root.bib" + diff --git a/thys/Pluennecke_Ruzsa_Inequality/document/root.bib b/thys/Pluennecke_Ruzsa_Inequality/document/root.bib new file mode 100644 --- /dev/null +++ b/thys/Pluennecke_Ruzsa_Inequality/document/root.bib @@ -0,0 +1,22 @@ +%% This BibTeX bibliography file was created using BibDesk. +%% http://bibdesk.sourceforge.net/ + + +%% Created for Larry Paulson at 2022-05-24 14:39:58 +0100 + + +%% Saved with string encoding Unicode (UTF-8) + + + +@inproceedings{petridis-plunnecke-ruzsa, + abstract = {In this expository article we present an overview of the Pl{\"u}nnecke--Ruzsa inequality: the known proofs, some of its well-known applications and possible extensions. We begin with the graph-theoretic setting in which Pl{\"u}nnecke and later Ruzsa worked in. The more purely combinatorial proofs of the inequality are subsequently presented. In the concluding sections we discuss the sharpness of the various results presented thus far and possible extensions of the inequality to the non-commutative setting.}, + author = {Petridis, G.}, + booktitle = {Combinatorial and Additive Number Theory}, + date-modified = {2022-05-24 14:39:58 +0100}, + editor = {Nathanson, Melvyn B.}, + isbn = {978-1-4939-1601-6}, + pages = {229-241}, + publisher = {Springer}, + title = {The {Pl{\"u}nnecke--Ruzsa} Inequality: An Overview}, + year = {2014}} diff --git a/thys/Pluennecke_Ruzsa_Inequality/document/root.tex b/thys/Pluennecke_Ruzsa_Inequality/document/root.tex new file mode 100644 --- /dev/null +++ b/thys/Pluennecke_Ruzsa_Inequality/document/root.tex @@ -0,0 +1,42 @@ +\documentclass[11pt,a4paper]{article} +\usepackage[T1]{fontenc} +\usepackage{isabelle,isabellesym} +\usepackage{amssymb} + +% 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{The Pl\"{u}nnecke-Ruzsa Inequality} +\author{Angeliki Koutsoukou-Argyraki and Lawrence C. Paulson} +\maketitle + +\begin{abstract} +We formalise Pl\"{u}nnecke's inequality and the Pl\"{u}nnecke-Ruzsa inequality, +following the notes by Timothy Gowers: "Introduction to Additive +Combinatorics" (2022) for the University of Cambridge. To this end, we first introduce basic definitions +and prove elementary facts on sumsets and difference sets. Then, we show two versions of +the Ruzsa triangle inequality. We follow with a proof due to Petridis~\cite{petridis-plunnecke-ruzsa}. +\end{abstract} + +\newpage +\tableofcontents + +\paragraph*{Acknowledgements} +The authors were supported by the ERC Advanced Grant ALEXANDRIA (Project 742178) funded by the European Research Council. + +\newpage + +% include generated text of all theories +\input{session} + +\bibliographystyle{abbrv} +\bibliography{root} + +\end{document} diff --git a/thys/ROOTS b/thys/ROOTS --- a/thys/ROOTS +++ b/thys/ROOTS @@ -1,680 +1,686 @@ ADS_Functor AI_Planning_Languages_Semantics AODV AVL-Trees AWN Abortable_Linearizable_Modules Abs_Int_ITP2012 Abstract-Hoare-Logics Abstract-Rewriting Abstract_Completeness Abstract_Soundness Ackermanns_not_PR Actuarial_Mathematics Adaptive_State_Counting Affine_Arithmetic Aggregation_Algebras Akra_Bazzi Algebraic_Numbers Algebraic_VCs Allen_Calculus Amicable_Numbers Amortized_Complexity AnselmGod Applicative_Lifting Approximation_Algorithms Architectural_Design_Patterns Aristotles_Assertoric_Syllogistic Arith_Prog_Rel_Primes ArrowImpossibilityGS Attack_Trees Auto2_HOL Auto2_Imperative_HOL AutoFocus-Stream Automated_Stateful_Protocol_Verification Automatic_Refinement AxiomaticCategoryTheory BDD BD_Security_Compositional BNF_CC BNF_Operations BTree Banach_Steinhaus Belief_Revision Bell_Numbers_Spivey BenOr_Kozen_Reif Berlekamp_Zassenhaus Bernoulli Bertrands_Postulate Bicategory BinarySearchTree Binding_Syntax_Theory Binomial-Heaps Binomial-Queues BirdKMP Blue_Eyes 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 CSP_RefTK CYK CZH_Elementary_Categories CZH_Foundations CZH_Universal_Constructions CakeML CakeML_Codegen Call_Arity Card_Equiv_Relations Card_Multisets Card_Number_Partitions Card_Partitions Cartan_FP Case_Labeling Catalan_Numbers Category Category2 Category3 Cauchy Cayley_Hamilton Certification_Monads Chandy_Lamport Chord_Segments Circus Clean Clique_and_Monotone_Circuits ClockSynchInst Closest_Pair_Points CoCon CoSMeDis CoSMed CofGroups Coinductive Coinductive_Languages Collections +Combinable_Wands Combinatorics_Words Combinatorics_Words_Graph_Lemma Combinatorics_Words_Lyndon Comparison_Sort_Lower_Bound Compiling-Exceptions-Correctly Complete_Non_Orders Completeness Complex_Bounded_Operators Complex_Geometry Complx ComponentDependencies ConcurrentGC ConcurrentIMP Concurrent_Ref_Alg Concurrent_Revisions Conditional_Simplification Conditional_Transfer_Rule Consensus_Refined Constructive_Cryptography Constructive_Cryptography_CM Constructor_Funs Containers CoreC++ Core_DOM Core_SC_DOM Correctness_Algebras Cotangent_PFD_Formula Count_Complex_Roots CryptHOL CryptoBasedCompositionalProperties Cubic_Quartic_Equations DFS_Framework DOM_Components DPT-SAT-Solver DataRefinementIBP Datatype_Order_Generator Decl_Sem_Fun_PL Decreasing-Diagrams Decreasing-Diagrams-II Dedekind_Real Deep_Learning Delta_System_Lemma Density_Compiler Dependent_SIFUM_Refinement Dependent_SIFUM_Type_Systems Depth-First-Search Derangements Deriving Descartes_Sign_Rule Design_Theory Dict_Construction Differential_Dynamic_Logic Differential_Game_Logic Digit_Expansions Dijkstra_Shortest_Path Diophantine_Eqns_Lin_Hom Dirichlet_L Dirichlet_Series DiscretePricing Discrete_Summation DiskPaxos Dominance_CHK +DPRM_Theorem DynamicArchitectures Dynamic_Tables E_Transcendental Echelon_Form EdmondsKarp_Maxflow Efficient-Mergesort Elliptic_Curves_Group_Law Encodability_Process_Calculi Epistemic_Logic Equivalence_Relation_Enumeration Ergodic_Theory Error_Function Euler_MacLaurin Euler_Partition Eval_FO Example-Submission Extended_Finite_State_Machine_Inference Extended_Finite_State_Machines FFT FLP FOL-Fitting FOL_Axiomatic FOL_Harrison FOL_Seq_Calc1 FOL_Seq_Calc2 FOL_Seq_Calc3 Factor_Algebraic_Polynomial Factored_Transition_System_Bounding Falling_Factorial_Sum Farkas FeatherweightJava Featherweight_OCL Fermat3_4 FileRefinement FinFun Finger-Trees Finite-Map-Extras Finite_Automata_HF +Finite_Fields Finitely_Generated_Abelian_Groups First_Order_Terms First_Welfare_Theorem Fishburn_Impossibility Fisher_Yates Fishers_Inequality Flow_Networks Floyd_Warshall Flyspeck-Tame FocusStreamsCaseStudies Forcing Formal_Puiseux_Series Formal_SSA Formula_Derivatives Foundation_of_geometry Fourier FO_Theory_Rewriting Free-Boolean-Algebra Free-Groups Frequency_Moments Fresh_Identifiers FunWithFunctions FunWithTilings Functional-Automata Functional_Ordered_Resolution_Prover Furstenberg_Topology GPU_Kernel_PL Gabow_SCC GaleStewart_Games Gale_Shapley Game_Based_Crypto Gauss-Jordan-Elim-Fun Gauss_Jordan Gauss_Sums Gaussian_Integers GenClock General-Triangle Generalized_Counting_Sort Generic_Deriving Generic_Join GewirthPGCProof Girth_Chromatic GoedelGod Goedel_HFSet_Semantic Goedel_HFSet_Semanticless Goedel_Incompleteness Goodstein_Lambda GraphMarkingIBP Graph_Saturation Graph_Theory Green Groebner_Bases Groebner_Macaulay Gromov_Hyperbolicity Grothendieck_Schemes Group-Ring-Module HOL-CSP HOLCF-Prelude HRB-Slicing Hahn_Jordan_Decomposition Heard_Of Hello_World HereditarilyFinite Hermite Hermite_Lindemann Hidden_Markov_Models Higher_Order_Terms Hoare_Time Hood_Melville_Queue HotelKeyCards Huffman Hybrid_Logic Hybrid_Multi_Lane_Spatial_Logic Hybrid_Systems_VCs HyperCTL Hyperdual IEEE_Floating_Point IFC_Tracking IMAP-CRDT IMO2019 IMP2 IMP2_Binary_Heap IMP_Compiler IP_Addresses Imperative_Insertion_Sort Impossible_Geometry Incompleteness Incredible_Proof_Machine Independence_CH Inductive_Confidentiality Inductive_Inference InfPathElimination InformationFlowSlicing InformationFlowSlicing_Inter Integration Interpolation_Polynomials_HOL_Algebra Interpreter_Optimizations Interval_Arithmetic_Word32 Intro_Dest_Elim Iptables_Semantics Irrational_Series_Erdos_Straus Irrationality_J_Hancl Irrationals_From_THEBOOK IsaGeoCoq Isabelle_C Isabelle_Marries_Dirac Isabelle_Meta_Model Jacobson_Basic_Algebra Jinja JinjaDCI JinjaThreads JiveDataStoreModel Jordan_Hoelder Jordan_Normal_Form KAD KAT_and_DRA KBPs KD_Tree Key_Agreement_Strong_Adversaries Kleene_Algebra Knights_Tour Knot_Theory Knuth_Bendix_Order Knuth_Morris_Pratt Koenigsberg_Friendship Kruskal Kuratowski_Closure_Complement LLL_Basis_Reduction LLL_Factorization LOFT LTL LTL_Master_Theorem LTL_Normal_Form LTL_to_DRA LTL_to_GBA Lam-ml-Normalization LambdaAuth LambdaMu Lambda_Free_EPO Lambda_Free_KBOs Lambda_Free_RPOs Lambert_W Landau_Symbols Laplace_Transform Latin_Square LatticeProperties Launchbury Laws_of_Large_Numbers Lazy-Lists-II Lazy_Case Lehmer Lifting_Definition_Option Lifting_the_Exponent 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 Logging_Independent_Anonymity Lowe_Ontological_Argument Lower_Semicontinuous Lp LP_Duality Lucas_Theorem MDP-Algorithms MDP-Rewards MFMC_Countable MFODL_Monitor_Optimized MFOTL_Monitor MSO_Regex_Equivalence Markov_Models Marriage Mason_Stothers Matrices_for_ODEs Matrix Matrix_Tensor Matroids Max-Card-Matching Median_Method Median_Of_Medians_Selection Menger Mereology Mersenne_Primes Metalogic_ProofChecker MiniML MiniSail Minimal_SSA Minkowskis_Theorem Minsky_Machines Modal_Logics_for_NTS Modular_Assembly_Kit_Security Modular_arithmetic_LLL_and_HNF_algorithms Monad_Memo_DP Monad_Normalisation MonoBoolTranAlgebra MonoidalCategory Monomorphic_Monad MuchAdoAboutTwo Multiset_Ordering_NPC Multi_Party_Computation Multirelations Myhill-Nerode Name_Carrying_Type_Inference Nash_Williams Nat-Interval-Logic Native_Word Nested_Multisets_Ordinals Network_Security_Policy_Verification Neumann_Morgenstern_Utility No_FTL_observers Nominal2 Noninterference_CSP Noninterference_Concurrent_Composition Noninterference_Generic_Unwinding Noninterference_Inductive_Unwinding Noninterference_Ipurge_Unwinding Noninterference_Sequential_Composition NormByEval Nullstellensatz Octonions OpSets Open_Induction Optics Optimal_BST Orbit_Stabiliser Order_Lattice_Props Ordered_Resolution_Prover Ordinal Ordinal_Partitions Ordinals_and_Cardinals Ordinary_Differential_Equations PAC_Checker +Package_logic PAL PCF PLM POPLmark-deBruijn PSemigroupsConvolution Padic_Ints Pairing_Heap Paraconsistency Parity_Game Partial_Function_MR Partial_Order_Reduction Password_Authentication_Protocol Pell Perfect-Number-Thm Perron_Frobenius Physical_Quantities Pi_Calculus Pi_Transcendental Planarity_Certificates +Pluennecke_Ruzsa_Inequality Poincare_Bendixson Poincare_Disc Polynomial_Factorization Polynomial_Interpolation Polynomials Pop_Refinement Posix-Lexing Possibilistic_Noninterference Power_Sum_Polynomials Pratt_Certificate Prefix_Free_Code_Combinators Presburger-Automata Prim_Dijkstra_Simple Prime_Distribution_Elementary Prime_Harmonic_Series Prime_Number_Theorem Priority_Queue_Braun Priority_Search_Trees Probabilistic_Noninterference Probabilistic_Prime_Tests Probabilistic_System_Zoo Probabilistic_Timed_Automata Probabilistic_While Program-Conflict-Analysis Progress_Tracking Projective_Geometry Projective_Measurements Promela Proof_Strategy_Language PropResPI Propositional_Proof_Systems Prpu_Maxflow PseudoHoops Psi_Calculi Ptolemys_Theorem Public_Announcement_Logic QHLProver QR_Decomposition Quantales Quasi_Borel_Spaces Quaternions Quick_Sort_Cost RIPEMD-160-SPARK ROBDD RSAPSS Ramsey-Infinite Random_BSTs Random_Graph_Subgraph_Threshold Randomised_BSTs Randomised_Social_Choice Rank_Nullity_Theorem Real_Impl Real_Power Recursion-Addition Recursion-Theory-I Refine_Imperative_HOL Refine_Monadic RefinementReactive Regex_Equivalence Registers Regression_Test_Selection Regular-Sets Regular_Algebras Regular_Tree_Relations Relation_Algebra Relational-Incorrectness-Logic Relational_Disjoint_Set_Forests Relational_Forests Relational_Method Relational_Minimum_Spanning_Trees Relational_Paths Rep_Fin_Groups ResiduatedTransitionSystem Residuated_Lattices Resolution_FOL +Rewrite_Properties_Reduction Rewriting_Z Ribbon_Proofs Robbins-Conjecture Robinson_Arithmetic Root_Balanced_Tree Roth_Arithmetic_Progressions Routing Roy_Floyd_Warshall SATSolverVerification SC_DOM_Components SDS_Impossibility SIFPL SIFUM_Type_Systems SPARCv8 Safe_Distance Safe_OCL Saturation_Framework Saturation_Framework_Extensions Schutz_Spacetime Secondary_Sylow Security_Protocol_Refinement Selection_Heap_Sort SenSocialChoice Separata Separation_Algebra Separation_Logic_Imperative_HOL SequentInvertibility Shadow_DOM Shadow_SC_DOM Shivers-CFA ShortestPath Show Sigma_Commit_Crypto Signature_Groebner Simpl Simple_Firewall Simplex Simplicial_complexes_and_boolean_functions SimplifiedOntologicalArgument Skew_Heap Skip_Lists Slicing Sliding_Window_Algorithm Smith_Normal_Form Smooth_Manifolds Sophomores_Dream Sort_Encodings Source_Coding_Theorem SpecCheck Special_Function_Bounds Splay_Tree Sqrt_Babylonian Stable_Matching Statecharts Stateful_Protocol_Composition_and_Typing Stellar_Quorums Stern_Brocot Stewart_Apollonius Stirling_Formula Stochastic_Matrices Stone_Algebras Stone_Kleene_Relation_Algebras Stone_Relation_Algebras Store_Buffer_Reduction Stream-Fusion Stream_Fusion_Code Strong_Security Sturm_Sequences Sturm_Tarski Stuttering_Equivalence Subresultants Subset_Boolean_Algebras SumSquares Sunflowers SuperCalc Surprise_Paradox Symmetric_Polynomials Syntax_Independent_Logic Szemeredi_Regularity Szpilrajn TESL_Language TLA Tail_Recursive_Functions Tarskis_Geometry Taylor_Models Three_Circles Timed_Automata Topological_Semantics Topology TortoiseHare Transcendence_Series_Hancl_Rucki Transformer_Semantics Transition_Systems_and_Automata Transitive-Closure Transitive-Closure-II Transitive_Models Treaps Tree-Automata Tree_Decomposition Triangle Trie Twelvefold_Way Tycon Types_Tableaus_and_Goedels_God Types_To_Sets_Extension UPF UPF_Firewall UTP Universal_Hash_Families Universal_Turing_Machine UpDown_Scheme Valuation Van_Emde_Boas_Trees Van_der_Waerden VectorSpace VeriComp Verified-Prover Verified_SAT_Based_AI_Planning VerifyThis2018 VerifyThis2019 Vickrey_Clarke_Groves Virtual_Substitution VolpanoSmith VYDRA_MDL WHATandWHERE_Security WOOT_Strong_Eventual_Consistency WebAssembly Weight_Balanced_Trees Weighted_Path_Order Well_Quasi_Orders Wetzels_Problem Winding_Number_Eval Word_Lib WorkerWrapper X86_Semantics XML Youngs_Inequality ZFC_in_HOL Zeta_3_Irrational Zeta_Function pGCL diff --git a/thys/Rewrite_Properties_Reduction/Ground_Reduction_on_GTRS.thy b/thys/Rewrite_Properties_Reduction/Ground_Reduction_on_GTRS.thy new file mode 100644 --- /dev/null +++ b/thys/Rewrite_Properties_Reduction/Ground_Reduction_on_GTRS.thy @@ -0,0 +1,260 @@ +section \Reducing Rewrite Properties to Properties on Ground Terms over Ground Systems\ +theory Ground_Reduction_on_GTRS + imports + Rewriting_Properties + Rewriting_GTRS + Rewriting_LLRG_LV_Mondaic +begin + +lemma ground_sys_nf_eq_lift: + fixes \ :: "('f, 'v) term rel" + assumes gtrs: "ground_sys \" "ground_sys \" + and nf: "NF (gsrstep \ \) = NF (gsrstep \ \)" + shows "NF (srstep \ \) = NF (srstep \ \)" +proof - + {fix s \ \ assume ass: "ground_sys (\ :: ('f, 'v) term rel)" "ground_sys \" + "NF (gsrstep \ \) = NF (gsrstep \ \)" "s \ NF (srstep \ \)" + have "s \ NF (srstep \ \)" + proof (rule ccontr) + assume "s \ NF (srstep \ \)" + then obtain C l r \ where step: "(l, r) \ \" and rep: "s = C\l \ \\" + and funas: "funas_ctxt C \ \" "funas_term l \ \" "funas_term r \ \" using ass(2) + by (auto simp: funas_term_subst NF_def sig_step_def dest!: rstep_imp_C_s_r) blast + from step ass(2) rep have rep: "s = C\l\" "ground l" "ground r" + by (auto intro: ground_subst_apply) + from step rep(2-) funas have "l \ NF (gsrstep \ \)" + by (auto simp: NF_def sig_step_def Image_def) + from this ass(3) have "l \ NF (srstep \ \)" by auto + then obtain t where "(l, t) \ srstep \ \" by auto + from srstep_ctxt_closed[OF funas(1) this, unfolded rep(1)[symmetric]] + show False using ass(4) + by auto + qed} + then show ?thesis using assms + by (smt (verit, best) equalityI subsetI) +qed + +lemma ground_sys_inv: + "ground_sys \ \ ground_sys (\\)" by auto + +lemma ground_sys_symcl: + "ground_sys \ \ ground_sys (\\<^sup>\)" by auto + +lemma ground_sys_comp_rrstep_rel'_ground: + assumes "ground_sys \" "ground_sys \" + and "(s, t) \ comp_rrstep_rel' \ \ \" + shows "ground s" "ground t" +proof - + from assms(3) consider (a) "(s, t) \ srsteps_with_root_step \ \ O (srstep \ \)\<^sup>+" | + (b) "(s, t) \ (srstep \ \)\<^sup>+ O srsteps_with_root_step \ \" + by auto + then have "ground s \ ground t" + proof cases + case a + then show ?thesis using srsteps_with_root_step_ground(1)[OF assms(1)] + using srsteps_with_root_step_ground(2)[OF assms(1), THEN srsteps_pres_ground_l[OF assms(2)]] + by blast + next + case b + then show ?thesis using srsteps_with_root_step_ground(2)[OF assms(2)] + using srsteps_with_root_step_ground(1)[OF assms(2), THEN srsteps_pres_ground_r[OF assms(1)]] + by blast + qed + then show "ground s" "ground t" by simp_all +qed + +lemma GTRS_commute: + assumes "ground_sys \" "ground_sys \" + and com: "commute (gsrstep \ \) (gsrstep \ \)" + shows "commute (srstep \ \) (srstep \ \)" +proof - + {fix s t assume ass: "(s, t) \ comp_rrstep_rel' \ (\\) \" + then obtain u where steps: "(s, u) \ (srstep \ (\\))\<^sup>+" "(u, t) \ (srstep \ \)\<^sup>+" + by (auto simp: sig_step_converse_rstep dest: srsteps_with_root_step_srstepsD) + have gr: "ground s" "ground t" "ground u" + using ground_sys_comp_rrstep_rel'_ground[OF ground_sys_inv[OF assms(1)] assms(2) ass] + using srsteps_pres_ground_r[OF assms(2) _ steps(2)] by auto + then have "(s, u) \ (gsrstep \ (\\))\<^sup>*" "(u, t) \ (gsrstep \ \)\<^sup>*" using steps + by (auto dest!: trancl_into_rtrancl intro: ground_srsteps_eq_gsrsteps_eq) + then have "(s, t) \ (gsrstep \ \)\<^sup>* O (gsrstep \ (\\))\<^sup>*" using com steps + by (auto simp: commute_def rew_converse_inwards) + from gsrsteps_eq_relcomp_srsteps_relcompD[OF this] + have "commute_redp \ \ \ s t" unfolding commute_redp_def + by (simp add: rew_converse_inwards)} + then show ?thesis by (intro commute_rrstep_intro) simp +qed + +lemma GTRS_CR: + assumes "ground_sys \" + and "CR (gsrstep \ \)" + shows "CR (srstep \ \)" using GTRS_commute assms + unfolding CR_iff_self_commute + by blast + + +lemma GTRS_SCR: + assumes gtrs: "ground_sys \" + and scr: "SCR (gsrstep \ \)" + shows "SCR (srstep \ \)" +proof - + {fix s t u assume ass: "(s, t) \ srstep \ \" "(s, u) \ srstep \ \" + and root: "(s, t) \ sig_step \ (rrstep \) \ (s, u) \ sig_step \ (rrstep \)" + from ass have funas: "funas_term s \ \" "funas_term t \ \" "funas_term u \ \" by blast+ + from root have gr: "ground s" "ground t" "ground u" using ass gtrs + using srrstep_ground srstep_pres_ground_l srstep_pres_ground_r + by metis+ + from scr obtain v where v: "(t, v) \ (gsrstep \ \)\<^sup>= \ (u, v) \ (gsrstep \ \)\<^sup>*" + using gr unfolding SCR_on_def + by (metis Int_iff UNIV_I ass mem_Collect_eq mem_Sigma_iff) + then have "SCRp \ \ t u" + by (metis (full_types) Int_iff Un_iff gsrsteps_eq_to_srsteps_eq)} + then show ?thesis by (intro SCR_rrstep_intro) (metis srrstep_to_srestep)+ +qed + +lemma GTRS_WCR: + assumes gtrs: "ground_sys \" + and wcr: "WCR (gsrstep \ \)" + shows "WCR (srstep \ \)" +proof - + {fix s t u assume ass: "(s, t) \ sig_step \ (rrstep \)" "(s, u) \ srstep \ \" + from ass have funas: "funas_term s \ \" "funas_term t \ \" "funas_term u \ \" by blast+ + from srrstep_ground[OF gtrs ass(1)] have gr: "ground s" "ground t" "ground u" + using srstep_pres_ground_l[OF gtrs _ ass(2)] + by simp_all + from this wcr have w: "(t, u) \ (gsrstep \ \)\<^sup>\" using ass funas + unfolding WCR_on_def + by (metis IntI SigmaI UNIV_I mem_Collect_eq srrstep_to_srestep) + then have "(t, u) \ (srstep \ \)\<^sup>\" unfolding join_def + by (metis (full_types) gsrsteps_eq_to_srsteps_eq joinD joinI join_def)} + then show ?thesis by (intro WCR_rrstep_intro) simp +qed + +lemma GTRS_UNF: + assumes gtrs: "ground_sys \" + and unf: "UNF (gsrstep \ \)" + shows "UNF (srstep \ \)" +proof - + {fix s t assume ass: "(s, t) \ comp_rrstep_rel' \ (\\) \" + then obtain u where steps: "(s, u) \ (srstep \ (\\))\<^sup>+" "(u, t) \ (srstep \ \)\<^sup>+" + by (auto simp: sig_step_converse_rstep dest: srsteps_with_root_step_srstepsD) + have gr: "ground s" "ground t" "ground u" + using ground_sys_comp_rrstep_rel'_ground[OF ground_sys_inv[OF gtrs] gtrs ass] + using srsteps_pres_ground_r[OF gtrs _ steps(2)] by auto + from steps(1) have f: "funas_term s \ \" by (simp add: srstepsD) + let ?\ = "\ _. s" + from steps gr have "(s, u \ ?\) \ (gsrstep \ (\\))\<^sup>+" "(u \ ?\, t) \ (gsrstep \ \)\<^sup>+" + unfolding srstep_converse_dist Restr_converse trancl_converse + using srsteps_subst_closed[where ?\ = ?\ and ?s = u, of _ \] f + by (force simp: ground_subst_apply intro: ground_srsteps_gsrsteps)+ + then have "UN_redp \ \ s t" using unf ground_NF_srstep_gsrstep[OF gr(1), of \ \] + using ground_NF_srstep_gsrstep[OF gr(2), of \ \] + by (auto simp: UNF_on_def UN_redp_def normalizability_def rew_converse_outwards) + (meson trancl_into_rtrancl)} + then show ?thesis by (intro UNF_rrstep_intro) simp +qed + + +lemma GTRS_UNC: + assumes gtrs: "ground_sys \" + and unc: "UNC (gsrstep \ \)" + shows "UNC (srstep \ \)" +proof - + {fix s t assume ass: "(s, t) \ srsteps_with_root_step \ (\\<^sup>\)" + from ass have funas: "funas_term s \ \" "funas_term t \ \" + by (meson srstepsD srsteps_with_root_step_srstepsD)+ + from ass have "ground s" "ground t" using srsteps_with_root_step_ground[OF ground_sys_symcl[OF gtrs]] + by auto + then have "UN_redp \ \ s t" unfolding UN_redp_def using ass unc unfolding UNC_def + by (simp add: ground_NF_srstep_gsrstep ground_srsteps_eq_gsrsteps_eq gsrstep_conversion_dist srsteps_with_root_step_sresteps_eqD)} + then show ?thesis by (intro UNC_rrstep_intro) simp +qed + + +lemma GTRS_NFP: + assumes "ground_sys \" + and nfp: "NFP (gsrstep \ \)" + shows "NFP (srstep \ \)" +proof - + {fix s t assume ass: "(s, t) \ comp_rrstep_rel' \ (\\) \" + from ass have funas: "funas_term s \ \" "funas_term t \ \" + by (meson Un_iff relcompEpair srstepsD srsteps_with_root_step_srstepsD)+ + from ass have "ground s" "ground t" + by (metis assms(1) ground_sys_comp_rrstep_rel'_ground ground_sys_inv)+ + from this ass have "(s, t) \ (gsrstep \ (\\))\<^sup>* O (gsrstep \ \)\<^sup>*" + by (intro srsteps_eq_relcomp_gsrsteps_relcomp) (auto dest!: srsteps_with_root_step_sresteps_eqD) + then have "t \ NF (gsrstep \ \) \ (s, t) \ (gsrstep \ \)\<^sup>*" using NFP_stepD[OF nfp] + by (auto simp: rew_converse_outwards) + then have "NFP_redp \ \ s t" unfolding NFP_redp_def + by (simp add: \ground t\ ground_NF_srstep_gsrstep gsrsteps_eq_to_srsteps_eq)} + then show ?thesis by (intro NFP_rrstep_intro) simp +qed + + +lemma GTRS_NE_aux: + assumes "(s, t) \ srsteps_with_root_step \ \" + and gtrs: "ground_sys \" "ground_sys \" + and ne: "NE (gsrstep \ \) (gsrstep \ \)" + shows "NE_redp \ \ \ s t" +proof - + from assms(1) have gr: "ground s" "ground t" + using srsteps_with_root_step_ground[OF gtrs(1)] by simp_all + have "(s, t) \ (gsrstep \ \)\<^sup>+" using gr assms(1) + by (auto dest: srsteps_with_root_step_srstepsD intro: ground_srsteps_gsrsteps) + then have "t \ NF (srstep \ \) \ (s, t) \ (gsrstep \ \)\<^sup>*" + using gr ne unfolding NE_on_def + by (auto simp: normalizability_def ground_subst_apply dest!: trancl_into_rtrancl) blast + then show "NE_redp \ \ \ s t" unfolding NE_redp_def + by (simp add: gsrsteps_eq_to_srsteps_eq) +qed + +lemma GTRS_NE: + assumes gtrs: "ground_sys \" "ground_sys \" + and ne: "NE (gsrstep \ \) (gsrstep \ \)" + shows "NE (srstep \ \) (srstep \ \)" +proof - + {fix s t assume "(s, t) \ srsteps_with_root_step \ \" + from GTRS_NE_aux[OF this gtrs ne] have "NE_redp \ \ \ s t" + by simp} + moreover + {fix s t assume "(s, t) \ srsteps_with_root_step \ \" + from GTRS_NE_aux[OF this gtrs(2, 1) NE_symmetric[OF ne]] + have "NE_redp \ \ \ s t" by simp} + ultimately show ?thesis + using ground_sys_nf_eq_lift[OF gtrs NE_NF_eq[OF ne]] + by (intro NE_rrstep_intro) auto +qed + + +lemma gtrs_CE_aux: + assumes step:"(s, t) \ srsteps_with_root_step \ (\\<^sup>\)" + and gtrs: "ground_sys \" "ground_sys \" + and ce: "CE (gsrstep \ \) (gsrstep \ \)" + shows "(s, t) \ (srstep \ \)\<^sup>\\<^sup>*" +proof - + from step gtrs(1) have "ground s" "ground t" + by (metis ground_sys_symcl srsteps_with_root_step_ground)+ + then have "(s, t) \ (gsrstep \ \)\<^sup>\\<^sup>*" using step + by (simp add: ground_srsteps_eq_gsrsteps_eq gsrstep_conversion_dist srsteps_with_root_step_sresteps_eqD) + then have "(s, t) \ (gsrstep \ \)\<^sup>\\<^sup>*" using ce unfolding CE_on_def + by blast + then show "(s, t) \ (srstep \ \)\<^sup>\\<^sup>*" + by (simp add: gsrstep_conversion_dist gsrsteps_eq_to_srsteps_eq symcl_srsteps_conversion) +qed + + +lemma gtrs_CE: + assumes gtrs: "ground_sys \" "ground_sys \" + and ce: "CE (gsrstep \ \) (gsrstep \ \)" + shows "CE (srstep \ \) (srstep \ \)" +proof - + {fix s t assume "(s, t) \ srsteps_with_root_step \ (\\<^sup>\)" + from gtrs_CE_aux[OF this gtrs ce] have "(s, t) \ (srstep \ \)\<^sup>\\<^sup>*" by simp} + moreover + {fix s t assume "(s, t) \ srsteps_with_root_step \ (\\<^sup>\)" + from gtrs_CE_aux[OF this gtrs(2, 1) CE_symmetric[OF ce]] + have "(s, t) \ (srstep \ \)\<^sup>\\<^sup>*" by simp} + ultimately show ?thesis + by (intro CE_rrstep_intro) auto +qed + +end \ No newline at end of file diff --git a/thys/Rewrite_Properties_Reduction/Ground_Reduction_on_LLRG.thy b/thys/Rewrite_Properties_Reduction/Ground_Reduction_on_LLRG.thy new file mode 100644 --- /dev/null +++ b/thys/Rewrite_Properties_Reduction/Ground_Reduction_on_LLRG.thy @@ -0,0 +1,408 @@ +section \Reducing Rewrite Properties to Properties on Ground Terms over Left-Linear Right-Ground Systems\ +theory Ground_Reduction_on_LLRG + imports + Rewriting_Properties + Rewriting_LLRG_LV_Mondaic +begin + +lemma llrg_linear_sys: + "llrg \ \ linear_sys \" + by (auto simp: llrg_def) + +section \LLRG results\ + +lemma llrg_commute: + assumes sig: "funas_rel \ \ \" "funas_rel \ \ \" + and fresh: "(c, 0) \ \" + and llrg: "llrg \" "llrg \" + and com: "commute (gsrstep (insert (c, 0) \) \) (gsrstep (insert (c, 0) \) \)" + shows "commute (srstep \ \) (srstep \ \)" +proof - + let ?\ = "\ _. Fun c []" let ?\ = "insert (c, 0) \" + from fresh have fresh_sys: "(c, 0) \ funas_rel \" "(c, 0) \ funas_rel (\\)" using sig + by (auto simp: funas_rel_def) + have linear: "linear_sys \" "linear_sys (\\)" using llrg unfolding llrg_def by auto + have sig': "funas_rel \ \ \" "funas_rel (\\) \ \" using sig by (auto simp: funas_rel_def) + have mono: "\ \ ?\" by auto + {fix s t assume ass: "(s, t) \ comp_rrstep_rel' \ (\\) \" + from ass have funas: "funas_term s \ \" "funas_term t \ \" + by (metis Un_iff relcomp.cases srstepsD srsteps_with_root_step_srstepsD)+ + from ass have m: "(s, t) \ (srstep ?\ (\\))\<^sup>* O (srstep ?\ \)\<^sup>*" + using rtrancl_mono[OF sig_step_mono[OF mono]] + by (auto dest!: srsteps_with_root_step_sresteps_eqD trancl_into_rtrancl) + have gr: "ground s \ ground t" using ass llrg + unfolding srstep_converse_dist trancl_converse + by (auto simp: llrg_srsteps_with_root_step_inv_ground llrg_srsteps_with_root_step_ground) + have gstep: "(s \ ?\, t \ ?\) \ (gsrstep ?\ \)\<^sup>* O (gsrstep ?\ (\\))\<^sup>*" + using srsteps_eq_subst_relcomp_closed[OF m, THEN srsteps_eq_relcomp_gsrsteps_relcomp, of ?\, + THEN subsetD[OF com[unfolded commute_def], unfolded rew_converse_inwards]] + by (auto simp: ground_substI) + have [simp]: "ground s \ (c, 0) \ funas_term s" "ground t \ (c, 0) \ funas_term t" + using funas fresh by auto + have "(s, t) \ (rstep \)\<^sup>* O (rstep (\\))\<^sup>*" + using remove_const_subst_relcomp_lhs[OF linear fresh_sys, of t s] + using gsrsteps_eq_relcomp_to_rsteps_relcomp[OF gstep] gr + using remove_const_subst_relcomp_lhs[OF linear fresh_sys, of t s] + using remove_const_subst_relcomp_rhs[OF linear fresh_sys, of s t] + by (cases "ground s") (simp_all add: ground_subst_apply) + from rsteps_eq_relcomp_srsteps_eq_relcompI[OF sig' funas this] + have "commute_redp \ \ \ s t" unfolding commute_redp_def + by (simp add: rew_converse_inwards)} + then show ?thesis by (intro commute_rrstep_intro) simp +qed + +lemma llrg_CR: + assumes sig: "funas_rel \ \ \" + and fresh: "(c, 0) \ \" + and llrg: "llrg \" + and com: "CR (gsrstep (insert (c, 0) \) \)" + shows "CR (srstep \ \)" + using assms llrg_commute unfolding CR_iff_self_commute + by metis + + +lemma llrg_SCR: + assumes sig: "funas_rel \ \ \" and fresh: "(c, 0) \ \" + and llrg: "llrg \" + and scr: "SCR (gsrstep (insert (c, 0) \) \)" + shows "SCR (srstep \ \)" +proof - + let ?\ = "const_subst c" let ?\ = "insert (c, 0) \" + from fresh have fresh_sys: "(c, 0) \ funas_rel \" using sig + by (auto simp: funas_rel_def) + have mono: "\ \ ?\" by auto note sig_trans = subsetD[OF srstep_monp[OF mono]] + {fix s t u assume ass: "(s, t) \ srstep \ \" "(s, u) \ srstep \ \" + and root: "(s, t) \ sig_step \ (rrstep \) \ (s, u) \ sig_step \ (rrstep \)" + from ass have funas: "funas_term s \ \" "funas_term t \ \" "funas_term u \ \" + by (force dest: sig_stepE)+ + from root have gr: "ground t \ ground u" using ass llrg llrg_rrsteps_groundness + unfolding srstep_converse_dist trancl_converse by blast + have *: "ground (s \ ?\)" "ground (t \ ?\)" "ground (u \ ?\)" by auto + from this scr obtain v where v: "(t \ ?\, v) \ (gsrstep ?\ \)\<^sup>= \ (u \ ?\, v) \ (gsrstep ?\ \)\<^sup>*" + using srstep_subst_closed[OF sig_trans[OF ass(1)], of ?\] + using srstep_subst_closed[OF sig_trans[OF ass(2)], of ?\] + using ass unfolding SCR_on_def + by auto (metis (no_types, lifting) * ) + then have fv: "funas_term v \ \" using gr llrg_funas_term_step_pres[OF llrg, of _ v] + using llrg_funas_term_steps_pres[OF llrg, of _ v] funas sig + by (auto simp: ground_subst_apply elim!: sig_stepE dest!: gsrsteps_eq_to_rsteps_eq) blast+ + then have c_free: "(c, 0) \ funas_term v" using fresh by blast + then have "v = t \ const_subst c \ ground t" using arg_cong[of v "t \ ?\" funas_term] + by (auto simp: funas_term_subst vars_term_empty_ground split: if_splits) + from this v have "(t, v) \ (srstep \ \)\<^sup>=" "(u, v) \ (srstep \ \)\<^sup>*" + using remove_const_subst_steps_eq_lhs[OF llrg_linear_sys[OF llrg] fresh_sys c_free, of u, + THEN rsteps_eq_srsteps_eqI[OF sig funas(3) fv]] + using remove_const_subst_step_lhs[OF llrg_linear_sys[OF llrg] fresh_sys c_free, of t, + THEN sig_stepI[OF funas(2) fv]] + by (auto simp: ground_subst_apply dest: srstepD gsrsteps_eq_to_rsteps_eq) + then have "SCRp \ \ t u" by blast} + then show ?thesis by (intro SCR_rrstep_intro) (metis srrstep_to_srestep)+ +qed + +lemma llrg_WCR: + assumes sig: "funas_rel \ \ \" and fresh: "(c, 0) \ \" + and llrg: "llrg \" + and wcr: "WCR (gsrstep (insert (c, 0) \) \)" + shows "WCR (srstep \ \)" +proof - + let ?\ = "const_subst c" let ?\ = "insert (c, 0) \" + from fresh have fresh_sys: "(c, 0) \ funas_rel \" "(c, 0) \ funas_rel (\\)" using sig + by (auto simp: funas_rel_def) + have lin: "linear_sys \" "linear_sys (\\)" using llrg unfolding llrg_def by auto + have mono: "\ \ ?\" by auto note sig_trans = subsetD[OF srstep_monp[OF mono]] + {fix s t u assume ass: "(s, t) \ sig_step \ (rrstep \)" "(s, u) \ srstep \ \" + from ass have funas: "funas_term s \ \" "funas_term t \ \" "funas_term u \ \" + by blast+ + then have c_free: "(c, 0) \ funas_term t" using fresh by blast + from ass have gr: "ground t" using ass llrg llrg_rrsteps_groundness by blast + have *: "ground (s \ ?\)" "ground (u \ ?\)" by auto + from this wcr have w: "(t, u \ ?\) \ (gsrstep ?\ \)\<^sup>\" + using srstep_subst_closed[OF sig_trans[OF srrstep_to_srestep[OF ass(1)]], of ?\] + using srstep_subst_closed[OF sig_trans[OF ass(2)], of ?\] + using ass unfolding WCR_on_def + by auto (metis * gr ground_subst_apply) + have "(t, u) \ (srstep \ \)\<^sup>\" unfolding join_def + using remove_const_subst_relcomp_rhs[OF lin fresh_sys c_free + gsrsteps_eq_relcomp_to_rsteps_relcomp[OF w[unfolded join_def rew_converse_inwards]], + THEN rsteps_eq_relcomp_srsteps_eq_relcompI[OF sig funas_rel_converse[OF sig] funas(2-)]] + by (metis (no_types, lifting) srstep_converse_dist)} + then show ?thesis by (intro WCR_rrstep_intro) simp +qed + + +lemma llrg_UNF: + assumes sig: "funas_rel \ \ \" and fresh: "(c, 0) \ \" + and llrg: "llrg \" + and unf: "UNF (gsrstep (insert (c, 0) \) \)" + shows "UNF (srstep \ \)" +proof - + let ?\ = "const_subst c" let ?\ = "insert (c, 0) \" + from fresh have fresh_sys: "(c, 0) \ funas_rel \" using sig + by (auto simp: funas_rel_def) + have mono: "\ \ ?\" by auto + {fix s t assume ass: "(s, t) \ comp_rrstep_rel' \ (\\) \" + from ass have funas: "funas_term s \ \" "funas_term t \ \" + by (metis Un_iff relcomp.cases srstepsD srsteps_with_root_step_srstepsD)+ + from ass have m: "(s, t) \ (srstep ?\ (\\))\<^sup>* O (srstep ?\ \)\<^sup>*" + using rtrancl_mono[OF sig_step_mono[OF mono]] + by (auto dest!: srsteps_with_root_step_sresteps_eqD trancl_into_rtrancl) + have gr: "ground s \ ground t" using ass llrg + unfolding srstep_converse_dist trancl_converse + by (auto simp: llrg_srsteps_with_root_step_inv_ground llrg_srsteps_with_root_step_ground) + have wit: "s \ ?\ \ NF (gsrstep ?\ \) \ t \ ?\ \ NF (gsrstep ?\ \) \ s \ ?\ = t \ ?\" using unf + using srsteps_eq_subst_relcomp_closed[OF m, THEN srsteps_eq_relcomp_gsrsteps_relcomp, of ?\] + by (auto simp: UNF_on_def rew_converse_outwards normalizability_def) + from funas NF_to_fresh_const_subst_NF[OF llrg_linear_sys[OF llrg] fresh_sys sig(1)] + have "s \ NF (srstep \ \) \ s \ ?\ \ NF (gsrstep ?\ \)" "t \ NF (srstep \ \) \ t \ ?\ \ NF (gsrstep ?\ \)" + by auto + moreover have "s \ ?\ = t \ ?\ \ s = t" using gr funas fresh + by (cases "ground s") (auto simp: ground_subst_apply funas_term_subst vars_term_empty_ground split: if_splits) + ultimately have "UN_redp \ \ s t" using wit unfolding UN_redp_def + by auto} + then show ?thesis by (intro UNF_rrstep_intro) simp +qed + + +lemma llrg_NFP: + assumes sig: "funas_rel \ \ \" and fresh: "(c, 0) \ \" + and llrg: "llrg \" + and nfp: "NFP (gsrstep (insert (c, 0) \) \)" + shows "NFP (srstep \ \)" +proof - + let ?\ = "const_subst c" let ?\ = "insert (c, 0) \" + from fresh have fresh_sys: "(c, 0) \ funas_rel \" + using sig by (auto simp: funas_rel_def) + have mono: "\ \ ?\" by auto + {fix s t assume ass: "(s, t) \ comp_rrstep_rel' \ (\\) \" + from ass have funas: "funas_term s \ \" "funas_term t \ \" + by (metis Un_iff relcomp.cases srstepsD srsteps_with_root_step_srstepsD)+ + from ass have m: "(s, t) \ (srstep ?\ (\\))\<^sup>* O (srstep ?\ \)\<^sup>*" + using rtrancl_mono[OF sig_step_mono[OF mono]] + by (auto dest!: srsteps_with_root_step_sresteps_eqD trancl_into_rtrancl) + have gr: "ground s \ ground t" using ass llrg + unfolding srstep_converse_dist trancl_converse + by (auto simp: llrg_srsteps_with_root_step_inv_ground llrg_srsteps_with_root_step_ground) + have wit: "t \ ?\ \ NF (gsrstep ?\ \) \ (s \ ?\, t \ ?\) \ (gsrstep (insert (c, 0) \) \)\<^sup>*" + using NFP_stepD[OF nfp] + using srsteps_eq_subst_relcomp_closed[OF m, THEN srsteps_eq_relcomp_gsrsteps_relcomp, of ?\] + by (auto simp: rew_converse_outwards) + from funas NF_to_fresh_const_subst_NF[OF llrg_linear_sys[OF llrg] fresh_sys(1) sig(1)] + have "t \ NF (srstep \ \) \ t \ ?\ \ NF (gsrstep ?\ \)" by auto + moreover have "(s \ ?\, t \ ?\) \ (rstep \)\<^sup>* \ (s, t) \ (srstep \ \)\<^sup>*" using gr funas fresh + using remove_const_subst_steps_eq_lhs[OF llrg_linear_sys[OF llrg] fresh_sys, THEN rsteps_eq_srsteps_eqI[OF sig funas]] + using remove_const_subst_steps_eq_rhs[OF llrg_linear_sys[OF llrg] fresh_sys, THEN rsteps_eq_srsteps_eqI[OF sig funas]] + by (cases "ground s") (auto simp: ground_subst_apply) + ultimately have "NFP_redp \ \ s t" using wit unfolding NFP_redp_def + by (auto dest: gsrsteps_eq_to_rsteps_eq)} + then show ?thesis by (intro NFP_rrstep_intro) simp +qed + + + +lemma llrg_NE_aux: + assumes "(s, t) \ srsteps_with_root_step \ \" + and sig: "funas_rel \ \ \" "funas_rel \ \ \" and fresh: "(c, 0) \ \" + and llrg: "llrg \" "llrg \" + and ne: "NE (gsrstep (insert (c, 0) \) \) (gsrstep (insert (c, 0) \) \)" + shows "NE_redp \ \ \ s t" +proof - + from fresh have fresh_sys: "(c, 0) \ funas_rel \" "(c, 0) \ funas_rel \" + using sig by (auto simp: funas_rel_def) + let ?\ = "const_subst c" let ?\ = "insert (c, 0) \" + let ?\ = "insert (c, 0) \" have mono: "\ \ ?\" by auto + from assms(1) have gr: "ground t" and funas: "funas_term s \ \" "funas_term t \ \" + using llrg_srsteps_with_root_step_ground[OF llrg(1)] + by (meson srstepsD srsteps_with_root_step_srstepsD)+ + from funas have fresh_t: "(c, 0) \ funas_term t" using fresh by auto + from srsteps_subst_closed[OF srsteps_monp[OF mono, THEN subsetD, OF srsteps_with_root_step_srstepsD[OF assms(1)]], of ?\] + have "(s \ ?\, t) \ (gsrstep?\ \)\<^sup>+" using gr + by (auto simp: ground_subst_apply intro!: ground_srsteps_gsrsteps) + then have "t \ NF (srstep \ \) \ (s \ ?\, t) \ (gsrstep (insert (c, 0) \) \)\<^sup>*" + using NF_to_fresh_const_subst_NF[OF llrg_linear_sys[OF llrg(1)] fresh_sys(1) sig(1) funas(2), of ?\] + using gr NE_NF_eq[OF ne, symmetric] ne unfolding NE_on_def + by (auto simp: normalizability_def ground_subst_apply dest!: trancl_into_rtrancl) + then show "NE_redp \ \ \ s t" unfolding NE_redp_def + using remove_const_subst_steps_eq_lhs[OF llrg_linear_sys[OF llrg(2)] fresh_sys(2) fresh_t, + THEN rsteps_eq_srsteps_eqI[OF sig(2) funas]] + by (auto dest: gsrsteps_eq_to_rsteps_eq) +qed + +lemma llrg_NE: + assumes sig: "funas_rel \ \ \" "funas_rel \ \ \" and fresh: "(c, 0) \ \" + and llrg: "llrg \" "llrg \" + and ne: "NE (gsrstep (insert (c, 0) \) \) (gsrstep (insert (c, 0) \) \)" + shows "NE (srstep \ \) (srstep \ \)" +proof - + have f: "(c, 0) \ funas_rel \" "(c, 0) \ funas_rel \" using fresh sig + by (auto simp: funas_rel_def) + {fix s t assume "(s, t) \ srsteps_with_root_step \ \" + from llrg_NE_aux[OF this sig fresh llrg ne] have "NE_redp \ \ \ s t" + by simp} + moreover + {fix s t assume "(s, t) \ srsteps_with_root_step \ \" + from llrg_NE_aux[OF this sig(2, 1) fresh llrg(2, 1) NE_symmetric[OF ne]] + have "NE_redp \ \ \ s t" by simp} + ultimately show ?thesis using linear_sys_gNF_eq_NF_eq[OF llrg_linear_sys[OF llrg(1)] + llrg_linear_sys[OF llrg(2)] sig f _ _ NE_NF_eq[OF ne]] + by (intro NE_rrstep_intro) auto +qed + +subsection \Specialized for monadic signature\ + +lemma monadic_commute: + assumes "llrg \" "llrg \" "monadic \" + and com: "commute (gsrstep \ \) (gsrstep \ \)" + shows "commute (srstep \ \) (srstep \ \)" +proof - + {fix s t assume ass: "(s, t) \ comp_rrstep_rel' \ (\\) \" + then obtain u where steps: "(s, u) \ (srstep \ (\\))\<^sup>+" "(u, t) \ (srstep \ \)\<^sup>+" + by (auto simp: sig_step_converse_rstep dest: srsteps_with_root_step_srstepsD) + have gr: "ground s" "ground t" using steps assms(1 - 3) + unfolding rew_converse_outwards + by (auto simp: llrg_srsteps_with_root_step_ground llrg_monadic_rsteps_groundness) + from steps(1) have f: "funas_term s \ \" using srstepsD by blast + let ?\ = "\ _. s" + from steps gr have "(s, u \ ?\) \ (gsrstep \ (\\))\<^sup>+" "(u \ ?\, t) \ (gsrstep \ \)\<^sup>+" + unfolding rew_converse_outwards + using srsteps_subst_closed[where ?\ = ?\ and ?s = u, of _ \] f + by (force simp: ground_subst_apply intro: ground_srsteps_gsrsteps)+ + then have "(s, t) \ (gsrstep \ \)\<^sup>* O (gsrstep \ (\\))\<^sup>*" using com + unfolding commute_def rew_converse_inwards + by (meson relcomp.relcompI subsetD trancl_into_rtrancl) + from gsrsteps_eq_relcomp_srsteps_relcompD[OF this] + have "commute_redp \ \ \ s t" unfolding commute_redp_def + by (simp add: rew_converse_inwards)} + then show ?thesis by (intro commute_rrstep_intro) simp +qed + +lemma monadic_CR: + assumes "llrg \" "monadic \" + and "CR (gsrstep \ \)" + shows "CR (srstep \ \)" using monadic_commute assms + unfolding CR_iff_self_commute + by blast + + +lemma monadic_SCR: + assumes sig: "funas_rel \ \ \" "monadic \" + and llrg: "llrg \" + and scr: "SCR (gsrstep \ \)" + shows "SCR (srstep \ \)" +proof - + {fix s t u assume ass: "(s, t) \ srstep \ \" "(s, u) \ srstep \ \" + and root: "(s, t) \ sig_step \ (rrstep \) \ (s, u) \ sig_step \ (rrstep \)" + from ass have funas: "funas_term s \ \" "funas_term t \ \" "funas_term u \ \" by blast+ + from root have gr: "ground t" "ground u" using ass sig(2) llrg + by (metis llrg_monadic_rstep_pres_groundness)+ + let ?\ = "\ _. t" have grs: "ground (s \ ?\)" using gr by auto + from this scr obtain v where v: "(t, v) \ (gsrstep \ \)\<^sup>= \ (u, v) \ (gsrstep \ \)\<^sup>*" + using srstep_subst_closed[OF ass(1), of ?\] + using srstep_subst_closed[OF ass(2), of ?\] + using gr unfolding SCR_on_def + by (metis Int_iff UNIV_I funas(2) ground_subst_apply mem_Collect_eq mem_Sigma_iff) + then have "SCRp \ \ t u" + by (metis Int_iff Un_iff gsrsteps_eq_to_srsteps_eq)} + then show ?thesis by (intro SCR_rrstep_intro) (metis srrstep_to_srestep)+ +qed + +lemma monadic_WCR: + assumes sig: "funas_rel \ \ \" "monadic \" + and llrg: "llrg \" + and wcr: "WCR (gsrstep \ \)" + shows "WCR (srstep \ \)" +proof - + {fix s t u assume ass: "(s, t) \ sig_step \ (rrstep \)" "(s, u) \ srstep \ \" + from ass have funas: "funas_term s \ \" "funas_term t \ \" "funas_term u \ \" by blast+ + from srrstep_to_srestep ass have gr: "ground t" "ground u"using ass sig(2) llrg + by (metis llrg_monadic_rstep_pres_groundness)+ + let ?\ = "\ _. t" have grs: "ground (s \ ?\)" using gr by auto + from this wcr have w: "(t, u) \ (gsrstep \ \)\<^sup>\" using gr ass(2) funas + using srstep_subst_closed[OF srrstep_to_srestep[OF ass(1)], of ?\] + using srstep_subst_closed[OF ass(2), of ?\] + unfolding WCR_on_def + by (metis IntI SigmaI UNIV_I ground_subst_apply mem_Collect_eq) + then have "(t, u) \ (srstep \ \)\<^sup>\" unfolding join_def + by (metis gsrsteps_eq_to_srsteps_eq joinD joinI join_def)} + then show ?thesis by (intro WCR_rrstep_intro) simp +qed + +lemma monadic_UNF: + assumes "llrg \" "monadic \" + and unf: "UNF (gsrstep \ \)" + shows "UNF (srstep \ \)" +proof - + {fix s t assume ass: "(s, t) \ comp_rrstep_rel' \ (\\) \" + then obtain u where steps: "(s, u) \ (srstep \ (\\))\<^sup>+" "(u, t) \ (srstep \ \)\<^sup>+" + by (auto simp: sig_step_converse_rstep dest: srsteps_with_root_step_srstepsD) + have gr: "ground s" "ground t" using steps assms(1, 2) + unfolding rew_converse_outwards + by (auto simp: llrg_srsteps_with_root_step_ground llrg_monadic_rsteps_groundness) + from steps(1) have f: "funas_term s \ \" using srstepsD by blast + let ?\ = "\ _. s" + from steps gr have "(s, u \ ?\) \ (gsrstep \ (\\))\<^sup>+" "(u \ ?\, t) \ (gsrstep \ \)\<^sup>+" + unfolding rew_converse_outwards + using srsteps_subst_closed[where ?\ = ?\ and ?s = u, of _ \] f + by (force simp: ground_subst_apply intro: ground_srsteps_gsrsteps)+ + then have "UN_redp \ \ s t" using unf ground_NF_srstep_gsrstep[OF gr(1), of \ \] + using ground_NF_srstep_gsrstep[OF gr(2), of \ \] + by (auto simp: UNF_on_def UN_redp_def normalizability_def rew_converse_outwards) + (meson trancl_into_rtrancl)} + then show ?thesis by (intro UNF_rrstep_intro) simp +qed + + +lemma monadic_UNC: + assumes "llrg \" "monadic \" + and well: "funas_rel \ \ \" + and unc: "UNC (gsrstep \ \)" + shows "UNC (srstep \ \)" +proof - + {fix s t assume ass: "(s, t) \ (srstep \ \)\<^sup>\\<^sup>*" "s \ NF (srstep \ \)" "t \ NF (srstep \ \)" + then have "s = t" + proof (cases "s = t") + case False + then have "\ s' t'. (s, t) \ (srstep \ \)\<^sup>\\<^sup>* \ (s', s) \ (srstep \ \) \ (t', t) \ (srstep \ \)" + using ass by (auto simp: conversion_def rtrancl_eq_or_trancl dest: tranclD tranclD2) + then obtain s' t' where split: "(s, t) \ (srstep \ \)\<^sup>\\<^sup>*" "(s', s) \ (srstep \ \)" "(t', t) \ (srstep \ \)" by blast + from split(2, 3) have gr: "ground s" "ground t" using llrg_monadic_rstep_pres_groundness[OF assms(1, 2)] + by blast+ + from ground_srsteps_eq_gsrsteps_eq[OF this ass(1)[unfolded sig_step_conversion_dist]] + have "(s, t) \ (gsrstep \ \)\<^sup>\\<^sup>*" + unfolding conversion_def Restr_smycl_dist + by (simp add: rstep_converse_dist srstep_symcl_dist) + then show ?thesis using ass(2-) unc gr + by (auto simp: UNC_def ground_NF_srstep_gsrstep) + qed auto} + then show ?thesis by (auto simp: UNC_def UN_redp_def) +qed + + +lemma monadic_NFP: + assumes "llrg \" "monadic \" + and nfp: "NFP (gsrstep \ \)" + shows "NFP (srstep \ \)" +proof - + {fix s t u assume ass: "(s, t) \ (srstep \ \)\<^sup>*" "(s, u) \ (srstep \ \)\<^sup>*" "u \ NF (srstep \ \)" + have "(t, u) \ (srstep \ \)\<^sup>*" + proof (cases "s = u \ s = t") + case [simp]: True show ?thesis using ass + by (metis NF_not_suc True rtrancl.rtrancl_refl) + next + case False + then have steps:"(s, t) \ (srstep \ \)\<^sup>+" "(s, u) \ (srstep \ \)\<^sup>+" using ass(1, 2) + by (auto simp add: rtrancl_eq_or_trancl) + then have gr: "ground t" "ground u" using assms(1, 2) llrg_monadic_rsteps_groundness + by blast+ + let ?\ = "\ _. t" from steps gr have "(s \ ?\, t) \ (gsrstep \ \)\<^sup>+" "(s \ ?\, u) \ (gsrstep \ \)\<^sup>+" + by (auto intro!: ground_srsteps_gsrsteps) + (metis ground_subst_apply srstepsD srsteps_subst_closed)+ + then have "(t, u) \ (gsrstep \ \)\<^sup>*" using nfp ass(3) gr + by (auto simp: NFP_on_def) (metis ground_NF_srstep_gsrstep normalizability_I trancl_into_rtrancl) + then show ?thesis by (auto dest: gsrsteps_eq_to_srsteps_eq) + qed} + then show ?thesis unfolding NFP_on_def + by auto +qed + + +end \ No newline at end of file diff --git a/thys/Rewrite_Properties_Reduction/Ground_Reduction_on_LV.thy b/thys/Rewrite_Properties_Reduction/Ground_Reduction_on_LV.thy new file mode 100644 --- /dev/null +++ b/thys/Rewrite_Properties_Reduction/Ground_Reduction_on_LV.thy @@ -0,0 +1,489 @@ +section \Reducing Rewrite Properties to Properties on Ground Terms over Linear Variable-Separated Systems\ +theory Ground_Reduction_on_LV + imports + Rewriting_Properties + Rewriting_LLRG_LV_Mondaic +begin + +lemma lv_linear_sys: "lv \ \ linear_sys \" + by (auto simp: lv_def) + +lemma comp_rrstep_rel'_sig_mono: + "\ \ \ \ comp_rrstep_rel' \ \ \ \ comp_rrstep_rel' \ \ \" + by (meson Un_mono relcomp_mono srsteps_monp srsteps_with_root_step_sig_mono) + +lemma srsteps_eqD: "(s, t) \ (srstep \ \)\<^sup>* \ (s, t) \ (rstep \)\<^sup>*" + by (metis rtrancl_eq_or_trancl srstepsD) + +section \Linear-variable separated results\ + +locale open_terms_two_const_lv = + fixes \ :: "('f, 'v) term rel" and \ c d + assumes lv: "lv \" and sig: "funas_rel \ \ \" + and fresh: "(c, 0) \ \" "(d, 0) \ \" + and diff: "c \ d" +begin + +abbreviation "\ \ insert (c, 0) (insert (d,0) \)" +abbreviation "\\<^sub>c \ const_subst c" +abbreviation "\\<^sub>d \ const_subst d" + +lemma sig_mono: "\ \ \" by auto +lemma fresh_sym_c: "(c, 0) \ funas_rel \" using sig fresh + by (auto simp: funas_rel_def) +lemma fresh_sym_d: "(d, 0) \ funas_rel \" using sig fresh + by (auto simp: funas_rel_def) +lemma fresh_sym_c_inv: "(c, 0) \ funas_rel (\\)" using sig fresh + by (auto simp: funas_rel_def) +lemma fresh_sym_d_inv: "(d, 0) \ funas_rel (\\)" using sig fresh + by (auto simp: funas_rel_def) + +lemmas all_fresh = fresh_sym_c fresh_sym_d fresh_sym_c_inv fresh_sym_d_inv + + +lemma sig_inv: "funas_rel (\\) \ \" using sig unfolding funas_rel_def by auto +lemma lv_inv: "lv (\\)" using lv unfolding lv_def by auto +lemma well_subst: + "\x. funas_term ((const_subst c) x) \ \" + "\x. funas_term ((const_subst d) x) \ \" + by auto + +lemma srsteps_with_root_step_to_grsteps: + assumes "(s, t) \ srsteps_with_root_step \ \" + shows "(s \ \\<^sub>c, t \ \\<^sub>d) \ (gsrstep \ \)\<^sup>*" +proof - + from assms have lift: "(s, t) \ srsteps_with_root_step \ \" + using srsteps_with_root_step_sig_mono[OF sig_mono] + by blast + note [dest!] = lv_srsteps_with_root_step_idep_subst[OF lv _ well_subst, THEN srsteps_with_root_step_sresteps_eqD] + have "(s \ \\<^sub>c, t \ \\<^sub>d) \ (srstep \ \)\<^sup>*" using lift + using srsteps_eq_subst_closed[OF _ well_subst(1)] + using srsteps_eq_subst_closed[OF _ well_subst(2)] + by (auto dest: trancl_into_rtrancl) + then show ?thesis + by (intro ground_srsteps_eq_gsrsteps_eq) auto +qed + +lemma comp_rrstep_rel'_to_grsteps: + assumes "(s, t) \ comp_rrstep_rel' \ (\\) \" + shows "(s \ \\<^sub>c, t \ \\<^sub>d) \ (gsrstep \ (\\))\<^sup>* O (gsrstep \ \)\<^sup>*" +proof - + from assms have lift: "(s, t) \ comp_rrstep_rel' \ (\\) \" using sig_mono + by (meson in_mono relcomp_mono srsteps_monp srsteps_with_root_step_sig_mono sup_mono) + note [dest!] = lv_srsteps_with_root_step_idep_subst[OF lv _ well_subst, THEN srsteps_with_root_step_sresteps_eqD] + note [dest!] = lv_srsteps_with_root_step_idep_subst[OF lv_inv _ well_subst, THEN srsteps_with_root_step_sresteps_eqD] + have "(s \ \\<^sub>c, t \ \\<^sub>d) \ (srstep \ (\\))\<^sup>* O (srstep \ \)\<^sup>*" using lift + using srsteps_eq_subst_closed[OF _ well_subst(1)] + using srsteps_eq_subst_closed[OF _ well_subst(2)] + by (auto dest!: trancl_into_rtrancl) blast + then show ?thesis + by (intro srsteps_eq_relcomp_gsrsteps_relcomp) auto +qed + +lemma gsrsteps_eq_to_srsteps: + assumes "(s \ \\<^sub>c, t \ \\<^sub>d) \ (gsrstep \ \)\<^sup>*" + and funas: "funas_term s \ \" "funas_term t \ \" + shows "(s, t) \ (srstep \ \)\<^sup>*" +proof - + from funas have d: "(d, 0) \ funas_term s" and c: "(c, 0) \ funas_term (t \ \\<^sub>d)" + using fresh diff by (auto simp: funas_term_subst) + have "(s, t) \ (rstep \)\<^sup>*" using c gsrsteps_eq_to_rsteps_eq[OF assms(1)] + using remove_const_subst_steps_eq_lhs[OF lv_linear_sys[OF lv] fresh_sym_c, + THEN remove_const_subst_steps_eq_rhs[OF lv_linear_sys[OF lv] fresh_sym_d d]] + by auto + then show ?thesis using funas sig by blast +qed + +lemma convert_NF_to_GNF: + "funas_term t \ \ \ t \ NF (srstep \ \) \ t \ \\<^sub>c \ NF (gsrstep \ \)" + "funas_term t \ \ \ t \ NF (srstep \ \) \ t \ \\<^sub>d \ NF (gsrstep \ \)" + using NF_to_fresh_const_subst_NF[OF lv_linear_sys[OF lv] fresh_sym_c sig] + using NF_to_fresh_const_subst_NF[OF lv_linear_sys[OF lv] fresh_sym_d sig] + by blast+ + + +lemma convert_GNF_to_NF: + "funas_term t \ \ \ t \ \\<^sub>c \ NF (gsrstep \ \) \ t \ NF (srstep \ \)" + "funas_term t \ \ \ t \ \\<^sub>d \ NF (gsrstep \ \) \ t \ NF (srstep \ \)" + using fresh_const_subst_NF_pres[OF fresh_sym_c sig] + using fresh_const_subst_NF_pres[OF fresh_sym_d sig] + using sig_mono by blast+ + + +lemma lv_CR: + assumes cr: "CR (gsrstep \ \)" + shows "CR (srstep \ \)" +proof - + {fix s t assume ass: "(s, t) \ (srstep \ (\\))\<^sup>+ O srsteps_with_root_step \ \" + from ass have funas: "funas_term s \ \" "funas_term t \ \" + by (metis Pair_inject ass relcompE srstepsD srsteps_with_root_step_srstepsD)+ + have "(s \ \\<^sub>c, t \ \\<^sub>d) \ (gsrstep \ (\\))\<^sup>* O (gsrstep \ \)\<^sup>*" + using ass comp_rrstep_rel'_to_grsteps by auto + then have s: "(s \ \\<^sub>c, t \ \\<^sub>d) \ (gsrstep \ \)\<^sup>* O (gsrstep \ (\\))\<^sup>*" + using cr unfolding CR_on_def + by (auto simp: join_def rew_converse_outwards) + from gsrsteps_eq_relcomp_to_rsteps_relcomp[OF this] + have "commute_redp \ \ \ s t" unfolding commute_redp_def using funas fresh + using remove_const_subst_relcomp[OF lv_linear_sys[OF lv] lv_linear_sys[OF lv_inv] + all_fresh diff, THEN rsteps_eq_relcomp_srsteps_eq_relcompI[OF sig sig_inv funas]] + by (metis srstep_converse_dist subsetD)} + then show ?thesis by (intro CR_rrstep_intro) simp +qed + +lemma lv_WCR: + assumes wcr: "WCR (gsrstep \ \)" + shows "WCR (srstep \ \)" +proof - + note sig_trans_root = subsetD[OF srrstep_monp[OF sig_mono]] + note sig_trans = subsetD[OF srstep_monp[OF sig_mono]] + {fix s t u assume ass: "(s, t) \ sig_step \ (rrstep \)" "(s, u) \ srstep \ \" + from ass have funas: "funas_term s \ \" "funas_term t \ \" "funas_term u \ \" by blast+ + then have free: "(d, 0) \ funas_term u" "(c, 0) \ funas_term t" using fresh by blast+ + have *: "ground (s \ \\<^sub>c)" "ground (t \ \\<^sub>d)" "ground (u \ \\<^sub>c)" by auto + moreover have "(s \ \\<^sub>c, t \ \\<^sub>d) \ srstep \ \" using lv sig_trans_root[OF ass(1)] + by (intro lv_root_step_idep_subst[THEN srrstep_to_srestep]) auto + moreover have "(s \ \\<^sub>c, u \ \\<^sub>c) \ srstep \ \" + using srstep_subst_closed[OF sig_trans[OF ass(2)], of \\<^sub>c] + by auto + ultimately have w: "(t \ \\<^sub>d, u \ \\<^sub>c) \ (gsrstep \ \)\<^sup>\" using wcr unfolding WCR_on_def + by auto (metis (no_types, lifting) * ) + note join_unfolded = w[unfolded join_def rew_converse_inwards] + have "(t, u) \ (srstep \ \)\<^sup>\" unfolding join_def + using remove_const_subst_relcomp[OF lv_linear_sys[OF lv] lv_linear_sys[OF lv_inv] + fresh_sym_d fresh_sym_c fresh_sym_d_inv fresh_sym_c_inv diff[symmetric] free + gsrsteps_eq_relcomp_to_rsteps_relcomp[OF join_unfolded], + THEN rsteps_eq_relcomp_srsteps_eq_relcompI[OF sig sig_inv funas(2-)]] + by (metis (no_types, lifting) srstep_converse_dist)} + then show ?thesis by (intro WCR_rrstep_intro) simp +qed + +lemma lv_NFP: + assumes nfp: "NFP (gsrstep \ \)" + shows "NFP (srstep \ \)" +proof - + {fix s t assume ass: "(s, t) \ comp_rrstep_rel' \ (\\) \" + from ass have funas: "funas_term s \ \" "funas_term t \ \" + by (metis Un_iff ass relcompEpair srstepsD srsteps_with_root_step_srstepsD)+ + from comp_rrstep_rel'_to_grsteps[OF ass] + have " (s \ \\<^sub>c, t \ \\<^sub>d) \ (gsrstep \ (\\))\<^sup>* O (gsrstep \ \)\<^sup>*" by simp + then have "t \ \\<^sub>d \ NF (gsrstep \ \) \ (s \ \\<^sub>c, t \ \\<^sub>d) \ (gsrstep \ \)\<^sup>*" using NFP_stepD[OF nfp] + by (auto simp: rew_converse_outwards) + from gsrsteps_eq_to_srsteps[OF this funas] + have "NFP_redp \ \ s t" unfolding NFP_redp_def + using convert_NF_to_GNF(2)[OF funas(2)] + by simp} + then show ?thesis by (intro NFP_rrstep_intro) simp +qed + +lemma lv_UNF: + assumes unf: "UNF (gsrstep \ \)" + shows "UNF (srstep \ \)" +proof - + {fix s t assume ass: "(s, t) \ comp_rrstep_rel' \ (\\) \" + from ass have funas: "funas_term s \ \" "funas_term t \ \" + by (metis Un_iff ass relcompEpair srstepsD srsteps_with_root_step_srstepsD)+ + from comp_rrstep_rel'_to_grsteps[OF ass] + have " (s \ \\<^sub>c, t \ \\<^sub>d) \ (gsrstep \ (\\))\<^sup>* O (gsrstep \ \)\<^sup>*" by simp + then have "s \ \\<^sub>c \ NF (gsrstep \ \) \ t \ \\<^sub>d \ NF (gsrstep \ \) \ s \ \\<^sub>c = t \ \\<^sub>d" + using unf unfolding UNF_on_def + by (auto simp: normalizability_def rew_converse_outwards) + then have "UN_redp \ \ s t" unfolding UN_redp_def + using convert_NF_to_GNF(1)[OF funas(1)] + using convert_NF_to_GNF(2)[OF funas(2)] + by (metis NF_not_suc funas gsrsteps_eq_to_srsteps rtrancl_eq_or_trancl)} + then show ?thesis by (intro UNF_rrstep_intro) simp +qed + +lemma lv_UNC: + assumes unc: "UNC (gsrstep \ \)" + shows "UNC (srstep \ \)" +proof - + have lv_conv: "lv (\\<^sup>\)" using lv by (auto simp: lv_def) + {fix s t assume ass: "(s, t) \ srsteps_with_root_step \ (\\<^sup>\)" + from ass have funas: "funas_term s \ \" "funas_term t \ \" + by (metis Un_iff ass relcompEpair srstepsD srsteps_with_root_step_srstepsD)+ + have "(s \ \\<^sub>c, t \ \\<^sub>d) \ (gsrstep \ \)\<^sup>\\<^sup>*" + using lv_srsteps_with_root_step_idep_subst[OF lv_conv srsteps_with_root_step_sig_mono[OF sig_mono, THEN subsetD, OF ass] + well_subst,THEN srsteps_with_root_step_sresteps_eqD] + unfolding conversion_def Restr_smycl_dist srstep_symcl_dist + by (intro ground_srsteps_eq_gsrsteps_eq) auto + then have "s \ \\<^sub>c \ NF (gsrstep \ \) \ t \ \\<^sub>d \ NF (gsrstep \ \) \ s \ \\<^sub>c = t \ \\<^sub>d" + using unc unfolding UNC_def + by (auto simp: normalizability_def sig_step_converse_rstep rtrancl_converse Restr_converse) + then have "UN_redp \ \ s t" unfolding UN_redp_def + using convert_NF_to_GNF(1)[OF funas(1)] + using convert_NF_to_GNF(2)[OF funas(2)] + by (metis NF_not_suc funas gsrsteps_eq_to_srsteps rtrancl_eq_or_trancl)} + then show ?thesis by (intro UNC_rrstep_intro) simp +qed + + +lemma lv_SCR: + assumes scr: "SCR (gsrstep \ \)" + shows "SCR (srstep \ \)" +proof - + note sig_trans_root = subsetD[OF srrstep_monp[OF sig_mono]] + note sig_trans = subsetD[OF srstep_monp[OF sig_mono]] + note cl_on_c = lin_fresh_rstep_const_replace_closed[OF lv_linear_sys[OF lv] fresh_sym_c] + lin_fresh_rstep_const_replace_closed[OF lv_linear_sys[OF lv_inv] fresh_sym_c_inv] + note cl_on_d = lin_fresh_rstep_const_replace_closed[OF lv_linear_sys[OF lv] fresh_sym_d] + lin_fresh_rstep_const_replace_closed[OF lv_linear_sys[OF lv_inv] fresh_sym_d_inv] + {fix s t u assume ass: "(s, t) \ srstep \ \" "(s, u) \ srstep \ \" + and root: "(s, t) \ sig_step \ (rrstep \) \ (s, u) \ sig_step \ (rrstep \)" + from ass have funas: "funas_term s \ \" "funas_term t \ \" "funas_term u \ \" + by (force dest: sig_stepE)+ + then have fresh_c_t:"(c, 0) \ funas_term (t \ \\<^sub>d)" and fresh_d_u:"(d, 0) \ funas_term u" using fresh diff + by (auto simp: funas_term_subst) + have *: "(s, t) \ sig_step \ (rrstep \) \ (s \ \\<^sub>c, t \ \\<^sub>d) \ gsrstep \ \ \ (s \ \\<^sub>c, u \ \\<^sub>c) \ gsrstep \ \" + "(s, u) \ sig_step \ (rrstep \) \ (s \ \\<^sub>d, t \ \\<^sub>d) \ gsrstep \ \ \ (s \ \\<^sub>d, u \ \\<^sub>c) \ gsrstep \ \" + using srstep_subst_closed[OF sig_trans[OF ass(2)] well_subst(1)] + using srstep_subst_closed[OF sig_trans[OF ass(2)] well_subst(2)] + using lv_root_step_idep_subst[OF lv] sig_trans_root[of "(s, t)" \] sig_trans_root[of "(s, u)" \] + by (simp_all add: ass(1) sig_trans srstep_subst_closed srrstep_to_srestep) + from this scr have "(u \ \\<^sub>c, t \ \\<^sub>d) \ (gsrstep \ \)\<^sup>* O ((gsrstep \ \)\<^sup>=)\" + using root unfolding SCR_on_def by (meson UNIV_I converse_iff relcomp.simps) + then have v: "(u \ \\<^sub>c, t \ \\<^sub>d) \ (srstep \ \)\<^sup>* O ((srstep \ \)\<^sup>=)\" + by (auto dest: gsrsteps_eq_to_srsteps_eq) + have [simp]: "funas_term v \ \ \ term_to_sig \ x v = v" for x v + by (simp add: subset_insertI2) + have "(u, t) \ (srstep \ \)\<^sup>* O ((srstep \ \)\<^sup>=)\" + proof - + from v have "(u, t \ \\<^sub>d) \ (rstep \)\<^sup>* O (rstep (\\))\<^sup>=" + using const_replace_closed_relcomp[THEN const_replace_closed_remove_subst_lhs, OF + const_replace_closed_rtrancl[OF cl_on_c(1)] + const_replace_closed_symcl[OF cl_on_c(2)] fresh_c_t, of u] + by (auto simp: relcomp.relcompI srstepD simp flip: rstep_converse_dist dest: srsteps_eqD) + then have "(u, t) \ (rstep \)\<^sup>* O (rstep (\\))\<^sup>=" + using const_replace_closed_relcomp[THEN const_replace_closed_remove_subst_lhs, OF + const_replace_closed_symcl[OF cl_on_d(1)] + const_replace_closed_rtrancl[OF cl_on_d(2)] fresh_d_u, of t] + using converse_relcomp[where ?s = "(rstep (\\))\<^sup>=" and ?r = "(rstep \)\<^sup>*"] + by (metis (no_types, lifting) converseD converse_Id converse_Un converse_converse rstep_converse_dist rtrancl_converse) + then obtain v where "(u, v) \ (rstep \)\<^sup>*" "(v, t) \ (rstep (\\))\<^sup>=" by auto + then have "(u, term_to_sig \ x v) \ (srstep \ \)\<^sup>*" "(term_to_sig \ x v, t) \ (srstep \ (\\))\<^sup>=" + using funas(2, 3) sig fresh + by (auto simp: rtrancl_eq_or_trancl rstep_trancl_sig_step_r subset_insertI2 + rew_converse_outwards dest: fuans_term_term_to_sig[THEN subsetD] + intro!: rstep_term_to_sig_r rstep_srstepI rsteps_eq_srsteps_eqI) + then show ?thesis + by (metis converse_Id converse_Un relcomp.relcompI srstep_converse_dist) + qed + then have "SCRp \ \ t u" + by auto} + then show ?thesis by (intro SCR_rrstep_intro) (metis srrstep_to_srestep)+ +qed + + +end + + +locale open_terms_two_const_lv_two_sys = + open_terms_two_const_lv \ + for \ :: "('f, 'v) term rel" + + fixes \ :: "('f, 'v) term rel" + assumes lv_S: "lv \" and sig_S: "funas_rel \ \ \" +begin + +lemma fresh_sym_c_S: "(c, 0) \ funas_rel \" using sig_S fresh + by (auto simp: funas_rel_def) +lemma fresh_sym_d_S: "(d, 0) \ funas_rel \" using sig_S fresh + by (auto simp: funas_rel_def) + +lemma lv_commute: + assumes com: "commute (gsrstep \ \) (gsrstep \ \)" + shows "commute (srstep \ \) (srstep \ \)" +proof - + have linear: "linear_sys \" "linear_sys (\\)" using lv lv_S unfolding lv_def by auto + {fix s t assume ass: "(s, t) \ comp_rrstep_rel' \ (\\) \" + from ass have funas: "funas_term s \ \" "funas_term t \ \" + by (metis Un_iff ass relcompEpair srstepsD srsteps_with_root_step_srstepsD)+ + have "(s \ \\<^sub>c, t \ \\<^sub>d) \ (gsrstep \ (\\))\<^sup>* O (gsrstep \ \)\<^sup>*" + using comp_rrstep_rel'_sig_mono[OF sig_mono, THEN subsetD, OF ass] + using srsteps_eq_subst_closed[OF _ well_subst(1)] srsteps_eq_subst_closed[OF _ well_subst(2)] + by (auto simp: rew_converse_inwards dest!: trancl_into_rtrancl + lv_srsteps_with_root_step_idep_subst[OF lv_inv _ well_subst, THEN srsteps_with_root_step_sresteps_eqD] + lv_srsteps_with_root_step_idep_subst[OF lv_S _ well_subst, THEN srsteps_with_root_step_sresteps_eqD] + intro!: srsteps_eq_relcomp_gsrsteps_relcomp) blast + then have w: "(s \ \\<^sub>c, t \ \\<^sub>d) \ (gsrstep \ \)\<^sup>* O (gsrstep \ (\\))\<^sup>*" using com + unfolding commute_def Restr_converse srstep_converse_dist + by blast + have "(s, t) \ (srstep \ \)\<^sup>* O (srstep \ (\\))\<^sup>*" using funas sig_S sig_inv fresh + using remove_const_subst_relcomp[OF linear fresh_sym_c_S fresh_sym_d_S fresh_sym_c_inv fresh_sym_d_inv diff _ _ + gsrsteps_eq_relcomp_to_rsteps_relcomp[OF w]] + by (intro rsteps_eq_relcomp_srsteps_eq_relcompI) auto + then have "commute_redp \ \ \ s t" unfolding commute_redp_def + by (simp add: rew_converse_inwards)} + then show ?thesis by (intro commute_rrstep_intro) simp +qed + + + +lemma lv_NE: + assumes ne: "NE (gsrstep \ \) (gsrstep \ \)" + shows "NE (srstep \ \) (srstep \ \)" +proof - + from NE_NF_eq[OF ne] have ne_eq: "NF (srstep \ \) = NF (srstep \ \)" + using lv lv_S sig sig_S fresh_sym_c fresh_sym_c_S + by (intro linear_sys_gNF_eq_NF_eq) (auto dest: lv_linear_sys) + {fix s t assume step: "(s, t) \ srsteps_with_root_step \ \" + then have funas: "funas_term s \ \" "funas_term t \ \" + by (metis Un_iff step relcompEpair srstepsD srsteps_with_root_step_srstepsD)+ + then have fresh: "(c, 0) \ funas_term t" "(d, 0) \ funas_term s" using fresh by auto + from srsteps_with_root_step_sig_mono[OF sig_mono, THEN subsetD, OF step] + have "(s \ \\<^sub>c, t \ \\<^sub>d) \ (gsrstep \ \)\<^sup>*" + using lv_srsteps_with_root_step_idep_subst[OF lv _ well_subst, THEN srsteps_with_root_step_sresteps_eqD] + by (intro ground_srsteps_eq_gsrsteps_eq) auto + then have "t \ \\<^sub>d \ NF (gsrstep \ \) \ (s \ \\<^sub>c, t \ \\<^sub>d) \ (gsrstep \ \)\<^sup>*" + using ne NE_NF_eq[OF ne] unfolding NE_on_def + by (auto simp: normalizability_def) + from this[THEN gsrsteps_eq_to_rsteps_eq, THEN remove_const_subst_steps[OF lv_linear_sys[OF lv_S] fresh_sym_c_S fresh_sym_d_S diff fresh]] + have "NE_redp \ \ \ s t" using NF_to_fresh_const_subst_NF[OF lv_linear_sys[OF lv_S] fresh_sym_d_S sig_S funas(2)] + using funas sig_S unfolding NE_redp_def ne_eq + by (auto intro: rsteps_eq_srsteps_eqI)} + moreover + {fix s t assume step: "(s, t) \ srsteps_with_root_step \ \" + then have funas: "funas_term s \ \" "funas_term t \ \" + by (metis sig_S sig_stepE sig_step_rsteps_dist srsteps_with_root_step_srstepsD)+ + then have fresh: "(c, 0) \ funas_term t" "(d, 0) \ funas_term s" using fresh by auto + from srsteps_with_root_step_sig_mono[OF sig_mono, THEN subsetD, OF step] + have "(s \ \\<^sub>c, t \ \\<^sub>d) \ (gsrstep \ \)\<^sup>*" + using lv_srsteps_with_root_step_idep_subst[OF lv_S _ well_subst, THEN srsteps_with_root_step_sresteps_eqD] + by (intro ground_srsteps_eq_gsrsteps_eq) auto + then have "t \ \\<^sub>d \ NF (gsrstep \ \) \ (s \ \\<^sub>c, t \ \\<^sub>d) \ (gsrstep \ \)\<^sup>*" + using ne NE_NF_eq[OF ne] unfolding NE_on_def + by (auto simp: normalizability_def) + from this[THEN gsrsteps_eq_to_rsteps_eq, THEN remove_const_subst_steps[OF lv_linear_sys[OF lv] fresh_sym_c fresh_sym_d diff fresh]] + have "NE_redp \ \ \ s t" using NF_to_fresh_const_subst_NF[OF lv_linear_sys[OF lv] fresh_sym_d sig funas(2), of \] + using funas sig unfolding NE_redp_def ne_eq + by (auto intro: rsteps_eq_srsteps_eqI)} + ultimately show ?thesis using ne_eq + by (intro NE_rrstep_intro) auto +qed + +end + +\ \CE is special as it only needs one additional constant therefore not + included in the locale\ +lemma lv_CE_aux: + assumes "(s, t) \ srsteps_with_root_step \ (\\<^sup>\)" + and sig: "funas_rel \ \ \" "funas_rel \ \ \" + and fresh: "(c, 0) \ \" and const: "(a, 0) \ \" + and lv: "lv \" "lv \" + and ce: "CE (gsrstep (insert (c, 0) \) \) (gsrstep (insert (c, 0) \) \)" + shows "(s, t) \ (srstep \ \)\<^sup>\\<^sup>*" +proof - + let ?\ = "insert (c, 0) \" have mono: "\ \ ?\" by auto + have lv_conv: "lv (\\<^sup>\)" "lv (\\<^sup>\)" using lv by (auto simp: lv_def) + have sig_conv: "funas_rel (\\<^sup>\) \ \" using sig(2) by (auto simp: funas_rel_def) + from fresh have fresh_sys: "(c, 0) \ funas_rel \" "(c, 0) \ funas_rel \" "(c, 0) \ funas_rel (\\<^sup>\)" + using sig by (auto simp: funas_rel_def) + from assms(1) have lift: "(s, t) \ srsteps_with_root_step ?\ (\\<^sup>\)" + unfolding srsteps_with_root_step_def + by (meson in_mono mono relcomp_mono rtrancl_mono srrstep_monp srstep_monp) + from assms(1) have funas: "funas_term s \ \" "funas_term t \ \" + by (meson srstepsD srsteps_with_root_step_srstepsD)+ + from srsteps_with_root_step_sresteps_eqD[OF assms(1), THEN subsetD[OF srsteps_eq_monp[OF mono]]] + have "(s \ const_subst c, t \ const_subst c) \ (srstep ?\ \)\<^sup>\\<^sup>*" + by (auto simp: sig_step_conversion_dist intro: srsteps_eq_subst_closed) + moreover have "(s \ const_subst c, t \ const_subst a) \ (srstep ?\ \)\<^sup>\\<^sup>*" + unfolding sig_step_conversion_dist using const + by (intro lv_srsteps_with_root_step_idep_subst[OF lv_conv(1) lift, THEN srsteps_with_root_step_sresteps_eqD]) auto + moreover have "ground (s \ const_subst c)" "ground (t \ const_subst a)" "ground (t \ const_subst a)" + by auto + ultimately have toS:"(s \ const_subst c, t \ const_subst c) \ (gsrstep ?\ \)\<^sup>\\<^sup>*" + "(s \ const_subst c, t \ const_subst a) \ (gsrstep ?\ \)\<^sup>\\<^sup>*" + using ground_srsteps_eq_gsrsteps_eq[where ?\ = ?\ and ?\ = "\\<^sup>\"] + using ce unfolding CE_on_def + by (auto simp: Restr_smycl_dist conversion_def srstep_symcl_dist) + then have *: "(t \ const_subst a, t \ const_subst c) \ (gsrstep ?\ \)\<^sup>\\<^sup>*" + by (metis (no_types, lifting) conversion_inv conversion_rtrancl rtrancl.rtrancl_into_rtrancl) + have "(t \ const_subst a, t) \ (srstep \ \)\<^sup>\\<^sup>*" using const + using funas(2) fresh + using remove_const_subst_steps_eq_rhs[OF lv_linear_sys[OF lv_conv(2)] fresh_sys(3) _ + gsrsteps_eq_to_rsteps_eq[OF *[unfolded gsrstep_conversion_dist]]] + by (cases "vars_term t = {}") + (auto simp: funas_term_subst sig_step_conversion_dist split: if_splits intro!: rsteps_eq_srsteps_eqI[OF sig_conv]) + moreover have "(s, t \ const_subst a) \ (srstep \ \)\<^sup>\\<^sup>*" using const + using funas fresh + using remove_const_subst_steps_eq_lhs[OF lv_linear_sys[OF lv_conv(2)] fresh_sys(3) _ + gsrsteps_eq_to_rsteps_eq[OF toS(2)[unfolded gsrstep_conversion_dist]]] + by (cases "vars_term t = {}") + (auto simp: sig_step_conversion_dist funas_term_subst split: if_splits intro!: rsteps_eq_srsteps_eqI[OF sig_conv]) + ultimately show "(s, t) \ (srstep \ \)\<^sup>\\<^sup>*" + by (meson conversionE conversionI rtrancl_trans) +qed + + +lemma lv_CE: + assumes sig: "funas_rel \ \ \" "funas_rel \ \ \" + and fresh: "(c, 0) \ \" and const: "(a, 0) \ \" + and lv: "lv \" "lv \" + and ce: "CE (gsrstep (insert (c, 0) \) \) (gsrstep (insert (c, 0) \) \)" + shows "CE (srstep \ \) (srstep \ \)" +proof - + {fix s t assume "(s, t) \ srsteps_with_root_step \ (\\<^sup>\)" + from lv_CE_aux[OF this assms] have "(s, t) \ (srstep \ \)\<^sup>\\<^sup>*" by simp} + moreover + {fix s t assume "(s, t) \ srsteps_with_root_step \ (\\<^sup>\)" + from lv_CE_aux[OF this sig(2, 1) fresh const lv(2, 1) CE_symmetric[OF ce]] + have "(s, t) \ (srstep \ \)\<^sup>\\<^sup>*" by simp} + ultimately show ?thesis + by (intro CE_rrstep_intro) auto +qed + + +subsection \Specialized for monadic signature\ + +lemma lv_NE_aux: + assumes "(s, t) \ srsteps_with_root_step \ \" and fresh: "(c, 0) \ \" + and sig: "funas_rel \ \ \" "funas_rel \ \ \" + and lv: "lv \" "lv \" + and mon: "monadic \" + and ne: "NE (gsrstep (insert (c, 0) \) \) (gsrstep (insert (c, 0) \) \)" + shows "NE_redp \ \ \ s t" +proof - + let ?\ = "const_subst c" let ?\ = "insert (c, 0) \" + have mono: "\ \ ?\" by auto + from mon have mh: "monadic ?\" by (auto simp: monadic_def) + from fresh have fresh_sys: "(c, 0) \ funas_rel \" "(c, 0) \ funas_rel \" using sig + by (auto simp: funas_rel_def) + from assms have funas: "funas_term s \ \" "funas_term t \ \" + by (meson srstepsD srsteps_with_root_step_srstepsD)+ + from funas have fresh_t: "(c, 0) \ funas_term t" using fresh by auto + from srsteps_subst_closed[OF srsteps_monp[OF mono, THEN subsetD, OF srsteps_with_root_step_srstepsD[OF assms(1)]], of ?\] + have gstep: "(s \ ?\, t \ ?\) \ (gsrstep (insert (c, 0) \) \)\<^sup>+" + by (auto simp: ground_subst_apply intro!: ground_srsteps_gsrsteps) + then have neq: "t \ NF (srstep \ \) \ s \ ?\ \ t \ ?\" + using NF_to_fresh_const_subst_NF[OF lv_linear_sys[OF lv(1)] fresh_sys(1) sig(1) funas(2), of ?\] + by (metis NF_no_trancl_step) + then have "t \ NF (srstep \ \) \ (s \ ?\, t \ ?\) \ (gsrstep (insert (c, 0) \) \)\<^sup>+" using gstep + using NF_to_fresh_const_subst_NF[OF lv_linear_sys[OF lv(1)] fresh_sys(1) sig(1) funas(2), of ?\] + using NE_NF_eq[OF ne, symmetric] ne unfolding NE_on_def + by (auto simp: normalizability_def ground_subst_apply) (meson rtrancl_eq_or_trancl) + then show ?thesis unfolding NE_redp_def + using remove_const_lv_mondaic_steps[OF lv(2) fresh_sys(2) mh, THEN srstepsD[THEN conjunct1], + THEN rsteps_srstepsI[OF sig(2) funas]] + by (auto dest!: gsrsteps_to_srsteps) +qed + +lemma lv_NE: + assumes sig: "funas_rel \ \ \" "funas_rel \ \ \" + and mon: "monadic \" and fresh: "(c, 0) \ \" + and lv: "lv \" "lv \" + and ne: "NE (gsrstep (insert (c, 0) \) \) (gsrstep (insert (c, 0) \) \)" + shows "NE (srstep \ \) (srstep \ \)" +proof - + from fresh have fresh_sys: "(c, 0) \ funas_rel \" "(c, 0) \ funas_rel \" + using sig by (auto simp: funas_rel_def) + from NE_NF_eq[OF ne] have ne_eq: "NF (srstep \ \) = NF (srstep \ \)" using lv sig fresh_sys + by (intro linear_sys_gNF_eq_NF_eq) (auto dest: lv_linear_sys) + {fix s t assume "(s, t) \ srsteps_with_root_step \ \" + from lv_NE_aux[OF this fresh sig lv mon ne] have "NE_redp \ \ \ s t" by simp} + moreover + {fix s t assume ass: "(s, t) \ srsteps_with_root_step \ \" + from lv_NE_aux[OF this fresh sig(2, 1) lv(2, 1) mon NE_symmetric[OF ne]] have "NE_redp \ \ \ s t" by simp} + ultimately show ?thesis using ne_eq + by (intro NE_rrstep_intro) auto +qed + +end \ No newline at end of file diff --git a/thys/Rewrite_Properties_Reduction/ROOT b/thys/Rewrite_Properties_Reduction/ROOT new file mode 100644 --- /dev/null +++ b/thys/Rewrite_Properties_Reduction/ROOT @@ -0,0 +1,25 @@ +chapter AFP + +session Rewrite_Properties_Reduction (AFP) = "HOL-Library" + + options + [timeout = 600,document = pdf] + sessions + "Regular_Tree_Relations" + directories + "Util" + "Rewriting" + theories + "Util/Terms_Positions" + theories + "Rewriting/Rewriting" + "Rewriting/Replace_Constant" + "Rewriting/Rewriting_Properties" + "Rewriting/Rewriting_LLRG_LV_Mondaic" + "Rewriting/Rewriting_GTRS" + theories + "Ground_Reduction_on_LLRG" + "Ground_Reduction_on_GTRS" + "Ground_Reduction_on_LV" + document_files + "root.tex" + "root.bib" diff --git a/thys/Rewrite_Properties_Reduction/Rewriting/Replace_Constant.thy b/thys/Rewrite_Properties_Reduction/Rewriting/Replace_Constant.thy new file mode 100644 --- /dev/null +++ b/thys/Rewrite_Properties_Reduction/Rewriting/Replace_Constant.thy @@ -0,0 +1,370 @@ +theory Replace_Constant + imports Rewriting +begin + +subsection \Removing/Replacing constants in a rewrite sequence that do not appear in the rewrite system\ +lemma funas_term_const_subst_conv: + "(c, 0) \ funas_term l \ \ (l \ constT c)" +proof (induct l) + case (Fun f ts) then show ?case + by auto (metis Fun_supt supteq_supt_conv term.inject(2))+ +qed (auto simp add: supteq_var_imp_eq) + +lemma fresh_const_single_step_replace: + assumes lin: "linear_sys \" and fresh: "(c, 0) \ funas_rel \" + and occ: "p \ poss_of_term (constT c) s" and step: "(s, t) \ rstep \" + shows "(s[p \ u], t) \ rstep \ \ + (\ q. q \ poss_of_term (constT c) t \ (s[p \ u], t[q \ u]) \ rstep \)" +proof - + from occ have const: "p \ poss s \ s |_ p = constT c" by auto + from step obtain C l r \ where t [simp]: "s = C\l \ \\" "t = C\r \ \\" + and rule: "(l, r) \ \" by blast + from rule lin have lin: "linear_term l" "linear_term r" by fastforce+ + from fresh rule have nt_lhs: "(c, 0) \ funas_term l" by (auto simp: funas_rel_def) + consider (par) "p \ (hole_pos C)" | (below) "hole_pos C \\<^sub>p p" using occ + by (auto dest: poss_of_term_const_ctxt_apply) + then show ?thesis + proof cases + case par + then have possc: "p \ possc C" using const t possc_def by blast + then have "p \ poss_of_term (constT c) t" "(s[p \ u], t[p \ u]) \ rstep \" + using const par_hole_pos_replace_term_context_at[OF par] + using possc_subt_at_ctxt_apply[OF possc par, of "r \ \" "l \ \"] rule + by auto (metis par par_pos_replace_pres replace_at_hole_pos) + then show ?thesis by blast + next + case below + then obtain q where [simp]:"p = hole_pos C @ q" and poss: "q \ poss (l \ \)" + using const position_less_eq_def + by (metis (full_types) ctxt_at_pos_hole_pos ctxt_at_pos_subt_at_pos poss_append_poss t(1)) + have const: "l \ \ |_ q = constT c" using const by auto + from nt_lhs have "\ r. r \ varposs l \ r \\<^sub>p q" using const poss + proof (induct l arbitrary: q) + case (Var x) + then show ?case by auto + next + case (Fun f ts) + from Fun(1)[OF nth_mem, of "hd q" "tl q"] Fun(2-) obtain r where + "r \ varposs (ts ! hd q) \ r \\<^sub>p tl q" + by (cases q) auto + then show ?case using Fun(2- 4) + by (intro exI[of _ "hd q # r"]) auto + qed + then obtain x v where varposs: "v \ varposs l" "v \\<^sub>p q" "l |_ v = Var x" + unfolding varposs_def by blast + let ?\ = "\x. if Var x = l |_ v then (\ x)[q -\<^sub>p v \ u] else \ x" + show ?thesis + proof (cases "x \ vars_term r") + case True + then obtain q' where varposs_r: "q' \ varposs r" "r |_ q' = Var x" + by (metis vars_term_varposs_iff) + have "(s[p \ u], t[(hole_pos C) @ q' @ (q -\<^sub>p v) \ u]) \ rstep \" + using lin varposs rule varposs_r + by (auto simp: linear_term_varposs_subst_replace_term intro!: rstep_ctxtI) + (smt (verit, ccfv_SIG) pos_diff_append_itself rrstep.intros rrstep_rstep_mono subset_eq term_subst_eq) + moreover have "(hole_pos C) @ q' @ q -\<^sub>p v \ poss_of_term (constT c) t" + using varposs_r varposs poss const poss_pos_diffI[OF varposs(2) poss] + using subt_at_append_dist[of q' "q -\<^sub>p v" "r \ \"] + by (auto simp: poss_append_poss varposs_imp_poss[THEN subst_subt_at_dist] varposs_imp_poss[THEN subsetD[OF subst_poss_mono]]) + (metis pos_les_eq_append_diff subst_apply_term.simps(1) subst_subt_at_dist subt_at_append_dist varposs_imp_poss) + ultimately show ?thesis by auto + next + case False + then have [simp]: "r \ \ = r \ ?\" using varposs + by (auto simp add: term_subst_eq_conv) + have "(s[p \ u], t) \ rstep \" using rule varposs lin + by (auto simp: linear_term_varposs_subst_replace_term) + then show ?thesis by auto + qed + qed +qed + +lemma fresh_const_steps_replace: + assumes lin: "linear_sys \" and fresh: "(c, 0) \ funas_rel \" + and occ: "p \ poss_of_term (constT c) s" and steps: "(s, t) \ (rstep \)\<^sup>+" + shows "(s[p \ u], t) \ (rstep \)\<^sup>+ \ + (\ q. q \ poss_of_term (constT c) t \ (s[p \ u], t[q \ u]) \ (rstep \)\<^sup>+)" + using steps occ +proof (induct arbitrary: p rule: converse_trancl_induct) + case (base s) + from fresh_const_single_step_replace[OF lin fresh base(2, 1)] show ?case + by (meson r_into_trancl') +next + case (step s t) + from fresh_const_single_step_replace[OF lin fresh step(4, 1)] + consider (a) "(s[p \ u], t) \ rstep \" | (b) "\q. q \ poss_of_term (constT c) t \ (s[p \ u], t[q \ u]) \ rstep \" by blast + then show ?case + proof cases + case a then show ?thesis using step(2) + by auto + next + case b + then obtain q where "q \ poss_of_term (constT c) t" "(s[p \ u], t[q \ u]) \ rstep \" by blast + from step(3)[OF this(1)] this(2) show ?thesis + by (metis trancl_into_trancl2) + qed +qed + +lemma remove_const_lhs_steps: + assumes lin: "linear_sys \" and fresh: "(c, 0) \ funas_rel \" + and const: "(c, 0) \ funas_term t" + and pos: "p \ poss_of_term (constT c) s" + and steps: "(s, t) \ (rstep \)\<^sup>+" + shows "(s[p \ u], t) \ (rstep \)\<^sup>+" using steps pos const fresh_const_steps_replace + by (metis fresh funas_term_const_subst_conv lin poss_of_termE subt_at_imp_supteq) + + +text \Now we can show that we may remove a constant substitution\ + +definition const_replace_closed where + "const_replace_closed c U = (\ s t u p. + p \ poss_of_term (constT c) s \ (s, t) \ U \ + (\ q. q \ poss_of_term (constT c) t \ (s[p \ u], t[q \ u]) \ U) \ (s[p \ u], t) \ U)" + +lemma const_replace_closedD: + assumes "const_replace_closed c U" "p \ poss_of_term (constT c) s" "(s, t) \ U" + shows "(s[p \ u], t) \ U \ (\ q. q \ poss_of_term (constT c) t \ (s[p \ u], t[q \ u]) \ U)" using assms + unfolding const_replace_closed_def by blast + +lemma const_replace_closedI: + assumes "\ s t u p. p \ poss_of_term (constT c) s \ (s, t) \ U \ + (\ q. q \ poss_of_term (constT c) t \ (s[p \ u], t[q \ u]) \ U) \ (s[p \ u], t) \ U" + shows "const_replace_closed c U" using assms + unfolding const_replace_closed_def + by auto + +abbreviation const_subst :: "'f \ 'v \ ('f, 'v) Term.term" where + "const_subst c \ (\ x. Fun c [])" + +lemma lin_fresh_rstep_const_replace_closed: + "linear_sys \ \ (c, 0) \ funas_rel \ \ const_replace_closed c (rstep \)" + using fresh_const_single_step_replace[of \ c] + by (intro const_replace_closedI) (auto simp: constT_nfunas_term_poss_of_term_empty, blast) + +lemma const_replace_closed_symcl: + "const_replace_closed c U \ const_replace_closed c (U\<^sup>=)" + unfolding const_replace_closed_def + by (metis Un_iff pair_in_Id_conv) + +lemma const_replace_closed_trancl: + "const_replace_closed c U \ const_replace_closed c (U\<^sup>+)" +proof (intro const_replace_closedI) + fix s t u p + assume const: "const_replace_closed c U" and wit: "p \ poss_of_term (constT c) s" + and steps :"(s, t) \ U\<^sup>+" + show "(\q. q \ poss_of_term (constT c) t \ (s[p \ u], t[q \ u]) \ U\<^sup>+) \ (s[p \ u], t) \ U\<^sup>+" using steps wit + proof (induct arbitrary: p rule: converse_trancl_induct) + case (base s) + show ?case using const_replace_closedD[OF const base(2, 1)] + by blast + next + case (step s v) + from const_replace_closedD[OF const step(4, 1)] + consider (a) "(s[p \ u], v) \ U" | (b) "\ q. q \ poss_of_term (constT c) v \ (s[p \ u], v[q \ u]) \ U" by auto + then show ?case + proof cases + case a then show ?thesis using step(2) + by (meson trancl_into_trancl2) + next + case b + then show ?thesis using step(3, 4) by (meson trancl_into_trancl2) + qed + qed +qed + +lemma const_replace_closed_rtrancl: + "const_replace_closed c U \ const_replace_closed c (U\<^sup>*)" +proof (intro const_replace_closedI) + fix s t u p + assume const: "const_replace_closed c U" and wit: "p \ poss_of_term (constT c) s" + and steps :"(s, t) \ U\<^sup>*" + show "(\q. q \ poss_of_term (constT c) t \ (s[p \ u], t[q \ u]) \ U\<^sup>*) \ (s[p \ u], t) \ U\<^sup>*" + using const_replace_closed_trancl[OF const] wit steps + by (metis const_replace_closedD rtrancl_eq_or_trancl) +qed + +lemma const_replace_closed_relcomp: + "const_replace_closed c U \ const_replace_closed c V \ const_replace_closed c (U O V)" +proof (intro const_replace_closedI) + fix s t u p + assume const: "const_replace_closed c U" "const_replace_closed c V" + and wit: "p \ poss_of_term (constT c) s" and step: "(s, t) \ U O V" + from step obtain w where w: "(s, w) \ U" "(w, t) \ V" by auto + from const_replace_closedD[OF const(1) wit this(1)] + consider (a) "(s[p \ u], w) \ U" | (b) "(\q. q \ poss_of_term (constT c) w \ (s[p \ u], w[q \ u]) \ U)" + by auto + then show "(\q. q \ poss_of_term (constT c) t \ (s[p \ u], t[q \ u]) \ U O V) \ (s[p \ u], t) \ U O V" + proof cases + case a + then show ?thesis using w(2) by auto + next + case b + then show ?thesis using const_replace_closedD[OF const(2) _ w(2)] + by (meson relcomp.simps) + qed +qed + + +text \@{const const_replace_closed} allow the removal of a fresh constant substitution\ +lemma const_replace_closed_remove_subst_lhs: + assumes repcl: "const_replace_closed c U" + and const: "(c, 0) \ funas_term t" + and steps: "(s \ const_subst c, t) \ U" + shows "(s, t) \ U" using steps +proof (induct "card (varposs s)" arbitrary: s) + case (Suc n) + obtain p ps where vl: "varposs s = insert p ps" "p \ ps" using Suc(2) + by (metis card_le_Suc_iff dual_order.refl) + let ?s = "s[p \ Fun c []]" have vp: "p \ varposs s" using vl by auto + then have [simp]: "?s \ const_subst c = s \ const_subst c" + by (induct s arbitrary: p) (auto simp: nth_list_update map_update intro!: nth_equalityI) + have "varposs ?s = ps" using vl varposs_ground_replace_at[of p s "constT c"] + by auto + then have "n = card (varposs ?s)" using vl Suc(2) by (auto simp: card_insert_if finite_varposs) + from Suc(1)[OF this] have IH: "(s[p \ constT c], t) \ U" "p \ poss_of_term (constT c) s[p \ constT c]" + using Suc(2, 3) vl poss_of_term_replace_term_at varposs_imp_poss vp + using \s[p \ constT c] \ const_subst c = s \ const_subst c\ + by fastforce+ + show ?case using const_replace_closedD[OF repcl] const IH(2, 1) + by (metis constT_nfunas_term_poss_of_term_empty empty_iff replace_term_at_same_pos replace_term_at_subt_at_id) +qed (auto simp: ground_subst_apply card_eq_0_iff finite_varposs varposs_empty_gound) + + +subsubsection \Removal lemma applied to various rewrite relations\ + +lemma remove_const_subst_step_lhs: + assumes lin: "linear_sys \" and fresh: "(c, 0) \ funas_rel \" + and const: "(c, 0) \ funas_term t" + and step: "(s \ const_subst c, t) \ (rstep \)" + shows "(s, t) \ (rstep \)" + using lin_fresh_rstep_const_replace_closed[OF lin fresh, THEN const_replace_closed_remove_subst_lhs] const step + by blast + +lemma remove_const_subst_steps_lhs: + assumes lin: "linear_sys \" and fresh: "(c, 0) \ funas_rel \" + and const: "(c, 0) \ funas_term t" + and steps: "(s \ const_subst c, t) \ (rstep \)\<^sup>+" + shows "(s, t) \ (rstep \)\<^sup>+" + using lin_fresh_rstep_const_replace_closed[THEN const_replace_closed_trancl, + OF lin fresh, THEN const_replace_closed_remove_subst_lhs] + using const steps + by blast + +lemma remove_const_subst_steps_eq_lhs: + assumes lin: "linear_sys \" and fresh: "(c, 0) \ funas_rel \" + and const: "(c, 0) \ funas_term t" + and steps: "(s \ const_subst c, t) \ (rstep \)\<^sup>*" + shows "(s, t) \ (rstep \)\<^sup>*" using steps const + by (cases "s = t") (auto simp: rtrancl_eq_or_trancl funas_term_subst ground_subst_apply vars_term_empty_ground + dest: remove_const_subst_steps_lhs[OF lin fresh const] split: if_splits) + +lemma remove_const_subst_steps_rhs: + assumes lin: "linear_sys \" and fresh: "(c, 0) \ funas_rel \" + and const: "(c, 0) \ funas_term s" + and steps: "(s, t \ const_subst c) \ (rstep \)\<^sup>+" + shows "(s, t) \ (rstep \)\<^sup>+" +proof - + from steps have revs: "(t \ const_subst c, s) \ (rstep (\\))\<^sup>+" + unfolding rew_converse_outwards by auto + have "(t, s) \ (rstep (\\))\<^sup>+" using assms + by (intro remove_const_subst_steps_lhs[OF _ _ _ revs]) (auto simp: funas_rel_def) + then show ?thesis unfolding rew_converse_outwards by auto +qed + +lemma remove_const_subst_steps_eq_rhs: + assumes lin: "linear_sys \" and fresh: "(c, 0) \ funas_rel \" + and const: "(c, 0) \ funas_term s" + and steps: "(s, t \ const_subst c) \ (rstep \)\<^sup>*" + shows "(s, t) \ (rstep \)\<^sup>*" + using steps const + by (cases "s = t") (auto simp: rtrancl_eq_or_trancl funas_term_subst ground_subst_apply vars_term_empty_ground + dest!: remove_const_subst_steps_rhs[OF lin fresh const] split: if_splits) + + +text \Main lemmas\ +lemma const_subst_eq_ground_eq: + assumes "s \ const_subst c = t \ const_subst d" "c \ d" + and "(c, 0) \ funas_term t" "(d, 0) \ funas_term s" + shows "s = t" using assms +proof (induct s arbitrary: t) + case (Var x) then show ?case by (cases t) auto +next + case (Fun f ts) + from Fun(2-) obtain g us where [simp]: "t = Fun g us" by (cases t) auto + have [simp]: "g = f" and l: "length ts = length us" using Fun(2) + by (auto intro: map_eq_imp_length_eq) + have "i < length ts \ ts ! i = us ! i" for i + using Fun(1)[OF nth_mem, of i "us ! i" for i] Fun(2-) l + by (auto simp: map_eq_conv') + then show ?case using l + by (auto intro: nth_equalityI) +qed + + +lemma remove_const_subst_steps: + assumes "linear_sys \" and "(c, 0) \ funas_rel \" and "(d, 0) \ funas_rel \" + and "c \ d" "(c, 0) \ funas_term t" "(d, 0) \ funas_term s" + and "(s \ const_subst c, t \ const_subst d) \ (rstep \)\<^sup>*" + shows "(s, t) \ (rstep \)\<^sup>*" +proof (cases "s \ const_subst c = t \ const_subst d") + case True + from const_subst_eq_ground_eq[OF this] assms(4 - 6) show ?thesis by auto +next + case False + then have step: "(s \ const_subst c, t \ const_subst d) \ (rstep \)\<^sup>+" using assms(7) + by (auto simp: rtrancl_eq_or_trancl) + then have "(s, t \ const_subst d) \ (rstep \)\<^sup>+" using assms + by (intro remove_const_subst_steps_lhs[OF _ _ _ step]) (auto simp: funas_term_subst) + from remove_const_subst_steps_rhs[OF _ _ _ this] show ?thesis using assms + by auto +qed + +lemma remove_const_subst_relcomp_lhs: + assumes sys: "linear_sys \" "linear_sys \" + and fr: "(c, 0) \ funas_rel \" and fs:"(c, 0) \ funas_rel \" + and funas: "(c, 0) \ funas_term t" + and seq: "(s \ const_subst c, t) \ (rstep \)\<^sup>* O (rstep \)\<^sup>*" + shows "(s, t) \ (rstep \)\<^sup>* O (rstep \)\<^sup>*" using seq + using lin_fresh_rstep_const_replace_closed[OF sys(1) fr, THEN const_replace_closed_rtrancl] + using lin_fresh_rstep_const_replace_closed[OF sys(2) fs, THEN const_replace_closed_rtrancl] + using const_replace_closed_relcomp + by (intro const_replace_closed_remove_subst_lhs[OF _ funas seq]) force + +lemma remove_const_subst_relcomp_rhs: + assumes sys: "linear_sys \" "linear_sys \" + and fr: "(c, 0) \ funas_rel \" and fs:"(c, 0) \ funas_rel \" + and funas: "(c, 0) \ funas_term s" + and seq: "(s, t \ const_subst c) \ (rstep \)\<^sup>* O (rstep \)\<^sup>*" + shows "(s, t) \ (rstep \)\<^sup>* O (rstep \)\<^sup>*" +proof - + from seq have "(t \ const_subst c,s) \ ((rstep \)\<^sup>* O (rstep \)\<^sup>*)\" + by auto + then have "(t \ const_subst c,s) \ ((rstep \)\<^sup>*)\ O ((rstep \)\<^sup>*)\" + using converse_relcomp by blast + note seq = this[unfolded rtrancl_converse[symmetric] rew_converse_inwards] + from sys fr fs have "linear_sys (\\)" "linear_sys (\\)" "(c, 0) \ funas_rel (\\)" "(c, 0) \ funas_rel (\\)" + by (auto simp: funas_rel_def) + from remove_const_subst_relcomp_lhs[OF this funas seq] + have "(t, s) \ (rstep (\\))\<^sup>* O (rstep (\\))\<^sup>*" by simp + then show ?thesis + unfolding rew_converse_outwards converse_relcomp[symmetric] + by simp +qed + + +lemma remove_const_subst_relcomp: + assumes sys: "linear_sys \" "linear_sys \" + and fr: "(c, 0) \ funas_rel \" "(d, 0) \ funas_rel \" + and fs:"(c, 0) \ funas_rel \" "(d, 0) \ funas_rel \" + and diff: "c \ d" and funas: "(c, 0) \ funas_term t" "(d, 0) \ funas_term s" + and seq: "(s \ const_subst c, t \ const_subst d) \ (rstep \)\<^sup>* O (rstep \)\<^sup>*" + shows "(s, t) \ (rstep \)\<^sup>* O (rstep \)\<^sup>*" +proof - + from diff funas(1) have *: "(c, 0) \ funas_term (t \ const_subst d)" + by (auto simp: funas_term_subst) + show ?thesis using remove_const_subst_relcomp_rhs[OF sys fr(2) fs(2) funas(2) + remove_const_subst_relcomp_lhs[OF sys fr(1) fs(1) * seq]] + by blast +qed + +end \ No newline at end of file diff --git a/thys/Rewrite_Properties_Reduction/Rewriting/Rewriting.thy b/thys/Rewrite_Properties_Reduction/Rewriting/Rewriting.thy new file mode 100644 --- /dev/null +++ b/thys/Rewrite_Properties_Reduction/Rewriting/Rewriting.thy @@ -0,0 +1,450 @@ +section \Rewriting\ +theory Rewriting + imports Terms_Positions +begin + +subsection \Basic rewrite definitions\ + +subsubsection \Rewrite steps with implicit signature declaration (encoded in the type)\ + +inductive_set rrstep :: "('f, 'v) term rel \ ('f, 'v) term rel" for \ where + [intro]: "(l, r) \ \ \ (l \ \, r \ \) \ rrstep \" + +inductive_set rstep :: "('f, 'v) term rel \ ('f, 'v) term rel" for \ where + "(s, t) \ rrstep \ \ (C\s\, C\t\) \ rstep \" + + +subsubsection \Restrict relations to terms induced by a given signature\ + +definition "sig_step \ \ = Restr \ (Collect (\ s. funas_term s \ \))" + +subsubsection \Rewriting under a given signature/restricted to ground terms\ + +abbreviation "srrstep \ \ \ sig_step \ (rrstep \)" +abbreviation "srstep \ \ \ sig_step \ (rstep \)" +abbreviation "gsrstep \ \ \ Restr (sig_step \ (rstep \)) (Collect ground)" + + +subsubsection \Rewriting sequences involving a root step\ + +abbreviation (input) relto :: "'a rel \ 'a rel \ 'a rel" where + "relto R S \ S^* O R O S^*" +definition "srsteps_with_root_step \ \ \ relto (sig_step \ (rrstep \)) (srstep \ \)" + + +subsection \Monotonicity laws\ + +lemma Restr_mono: "Restr r A \ r" by auto + +lemma Restr_trancl_mono_set: "(Restr r A)\<^sup>+ \ A \ A" + by (simp add: trancl_subset_Sigma) + +lemma rrstep_rstep_mono: "rrstep \ \ rstep \" + by (auto intro: rstep.intros[where ?C = \, simplified]) + +lemma sig_step_mono: + "\ \ \ \ sig_step \ \ \ sig_step \ \" + by (auto simp: sig_step_def) + +lemma sig_step_mono2: + "\ \ \ \ sig_step \ \ \ sig_step \ \" + by (auto simp: sig_step_def) + +lemma srrstep_monp: + "\ \ \ \ srrstep \ \ \ srrstep \ \" + by (simp add: sig_step_mono) + +lemma srstep_monp: + "\ \ \ \ srstep \ \ \ srstep \ \" + by (simp add: sig_step_mono) + +lemma srsteps_monp: + "\ \ \ \ (srstep \ \)\<^sup>+ \ (srstep \ \)\<^sup>+" + by (simp add: sig_step_mono trancl_mono_set) + +lemma srsteps_eq_monp: + "\ \ \ \ (srstep \ \)\<^sup>* \ (srstep \ \)\<^sup>*" + by (meson rtrancl_mono sig_step_mono subrelI subsetD trancl_into_rtrancl) + +lemma srsteps_with_root_step_sig_mono: + "\ \ \ \ srsteps_with_root_step \ \ \ srsteps_with_root_step \ \" + unfolding srsteps_with_root_step_def + by (simp add: relcomp_mono srrstep_monp srsteps_eq_monp) + + +subsection \Introduction, elimination, and destruction rules for @{const sig_step}, @{const rstep}, @{const rrstep}, + @{const srrstep}, and @{const srstep}\ + +lemma sig_stepE [elim, consumes 1]: + "(s, t) \ sig_step \ \ \ \(s, t) \ \ \ funas_term s \ \ \ funas_term t \ \ \ P\ \ P" + by (auto simp: sig_step_def) + +lemma sig_stepI [intro]: + "funas_term s \ \ \ funas_term t \ \ \ (s, t) \ \ \ (s, t) \ sig_step \ \" + by (auto simp: sig_step_def) + +lemma rrstep_subst [elim, consumes 1]: + assumes "(s, t) \ rrstep \" + obtains l r \ where "(l, r) \ \" "s = l \ \" "t = r \ \" using assms + by (meson rrstep.simps) + +lemma rstep_imp_C_s_r: + assumes "(s, t) \ rstep \" + shows "\C \ l r. (l,r) \ \ \ s = C\l\\\ \ t = C\r\\\"using assms + by (metis rrstep.cases rstep.simps) + + +lemma rstep_imp_C_s_r' [elim, consumes 1]: + assumes "(s, t) \ rstep \" + obtains C l r \ where "(l,r) \ \" "s = C\l\\\" "t = C\r\\\" using assms + using rstep_imp_C_s_r by blast + +lemma rrstep_basicI [intro]: + "(l, r) \ \ \ (l, r) \ rrstep \" + by (metis rrstepp.intros rrstepp_rrstep_eq subst_apply_term_empty) + +lemma rstep_ruleI [intro]: + "(l, r) \ \ \ (l, r) \ rstep \" + using rrstep_rstep_mono by blast + +lemma rstepI [intro]: + "(l, r) \ \ \ s = C\l \ \\ \ t = C\r \ \\ \ (s, t) \ rstep \" + by (simp add: rrstep.intros rstep.intros) + +lemma rstep_substI [intro]: + "(s, t) \ rstep \ \ (s \ \, t \ \) \ rstep \" + by (auto elim!: rstep_imp_C_s_r' simp flip: subst_subst_compose) + +lemma rstep_ctxtI [intro]: + "(s, t) \ rstep \ \ (C\s\, C\t\) \ rstep \" + by (auto elim!: rstep_imp_C_s_r' simp flip: ctxt_ctxt_compose) + +lemma srrstepD: + "(s, t) \ srrstep \ \ \ (s, t) \ rrstep \ \ funas_term s \ \ \ funas_term t \ \" + by (auto simp: sig_step_def) + +lemma srstepD: + "(s, t) \ (srstep \ \) \ (s, t) \ rstep \ \ funas_term s \ \ \ funas_term t \ \" + by (auto simp: sig_step_def) + +lemma srstepsD: + "(s, t) \ (srstep \ \)\<^sup>+ \ (s, t) \ (rstep \)\<^sup>+ \ funas_term s \ \ \ funas_term t \ \" + unfolding sig_step_def using trancl_mono_set[OF Restr_mono] + by (auto simp: sig_step_def dest: subsetD[OF Restr_trancl_mono_set]) + + +subsubsection \Transitive and relfexive closure distribution over @{const sig_step}\ + +lemma funas_rel_converse: + "funas_rel \ \ \ \ funas_rel (\\) \ \" unfolding funas_rel_def + by auto + +lemma rstep_term_to_sig_r: + assumes "(s, t) \ rstep \" and "funas_rel \ \ \" and "funas_term s \ \" + shows "(s, term_to_sig \ v t) \ rstep \" +proof - + from assms(1) obtain C l r \ where + *: "s = C\l \ \\" "t = C\r \ \\" "(l, r) \ \" by auto + from assms(2, 3) *(3) have "funas_ctxt C \ \" "funas_term l \ \" "funas_term r \ \" + by (auto simp: *(1) funas_rel_def funas_term_subst subset_eq) + then have "(term_to_sig \ v s, term_to_sig \ v t) \ rstep \" using *(3) + by (auto simp: *(1, 2) funas_ctxt_ctxt_well_def_hole_path) + then show ?thesis using assms(3) by auto +qed + +lemma rstep_term_to_sig_l: + assumes "(s, t) \ rstep \" and "funas_rel \ \ \" and "funas_term t \ \" + shows "(term_to_sig \ v s, t) \ rstep \" +proof - + from assms(1) obtain C l r \ where + *: "s = C\l \ \\" "t = C\r \ \\" "(l, r) \ \" by auto + from assms(2, 3) *(3) have "funas_ctxt C \ \" "funas_term l \ \" "funas_term r \ \" + by (auto simp: *(2) funas_rel_def funas_term_subst subset_eq) + then have "(term_to_sig \ v s, term_to_sig \ v t) \ rstep \" using *(3) + by (auto simp: *(1, 2) funas_ctxt_ctxt_well_def_hole_path) + then show ?thesis using assms(3) by auto +qed + +lemma rstep_trancl_sig_step_r: + assumes "(s, t) \ (rstep \)\<^sup>+" and "funas_rel \ \ \" and "funas_term s \ \" + shows "(s, term_to_sig \ v t) \ (srstep \ \)\<^sup>+" using assms +proof (induct) + case (base t) + then show ?case using subsetD[OF fuans_term_term_to_sig, of _ \ v] + by (auto simp: rstep_term_to_sig_r sig_step_def intro!: r_into_trancl) +next + case (step t u) + then have st: "(s, term_to_sig \ v t) \ (srstep \ \)\<^sup>+" by auto + from step(2) obtain C l r \ where + *: "t = C\l \ \\" "u = C\r \ \\" "(l, r) \ \" by auto + show ?case + proof (cases "ctxt_well_def_hole_path \ C") + case True + from *(3) step(4) have "funas_term l \ \" "funas_term r \ \" by (auto simp: funas_rel_def) + then have "(term_to_sig \ v t, term_to_sig \ v u) \ rstep \" + using True step(2) *(3) unfolding * + by auto + then have "(term_to_sig \ v t, term_to_sig \ v u) \ srstep \ \" + by (auto simp:_ sig_step_def) + then show ?thesis using st by auto + next + case False + then have "term_to_sig \ v t = term_to_sig \ v u" unfolding * by auto + then show ?thesis using st by auto + qed +qed + +lemma rstep_trancl_sig_step_l: + assumes "(s, t) \ (rstep \)\<^sup>+" and "funas_rel \ \ \" and "funas_term t \ \" + shows "(term_to_sig \ v s, t) \ (srstep \ \)\<^sup>+" using assms +proof (induct rule: converse_trancl_induct) + case (base t) + then show ?case using subsetD[OF fuans_term_term_to_sig, of _ \ v] + by (auto simp: rstep_term_to_sig_l sig_step_def intro!: r_into_trancl) +next + case (step s u) + then have st: "(term_to_sig \ v u, t) \ (srstep \ \)\<^sup>+" by auto + from step(1) obtain C l r \ where + *: "s = C\l \ \\" "u = C\r \ \\" "(l, r) \ \" by auto + show ?case + proof (cases "ctxt_well_def_hole_path \ C") + case True + from *(3) step(4) have "funas_term l \ \" "funas_term r \ \" by (auto simp: funas_rel_def) + then have "(term_to_sig \ v s, term_to_sig \ v u) \ rstep \" + using True step(2) *(3) unfolding * + by auto + then have "(term_to_sig \ v s, term_to_sig \ v u) \ srstep \ \" + by (auto simp:_ sig_step_def) + then show ?thesis using st by auto + next + case False + then have "term_to_sig \ v s = term_to_sig \ v u" unfolding * by auto + then show ?thesis using st by auto + qed +qed + +lemma rstep_srstepI [intro]: + "funas_rel \ \ \ \ funas_term s \ \ \ funas_term t \ \ \ (s, t) \ rstep \ \ (s, t) \ srstep \ \" + by blast + +lemma rsteps_srstepsI [intro]: + "funas_rel \ \ \ \ funas_term s \ \ \ funas_term t \ \ \ (s, t) \ (rstep \)\<^sup>+ \ (s, t) \ (srstep \ \)\<^sup>+" + using rstep_trancl_sig_step_r[of s t \ \] + by auto + + +lemma rsteps_eq_srsteps_eqI [intro]: + "funas_rel \ \ \ \ funas_term s \ \ \ funas_term t \ \ \ (s, t) \ (rstep \)\<^sup>* \ (s, t) \ (srstep \ \)\<^sup>*" + by (auto simp add: rtrancl_eq_or_trancl) + +lemma rsteps_eq_relcomp_srsteps_eq_relcompI [intro]: + assumes "funas_rel \ \ \" "funas_rel \ \ \" + and funas: "funas_term s \ \" "funas_term t \ \" + and steps: "(s, t) \ (rstep \)\<^sup>* O (rstep \)\<^sup>*" + shows "(s, t) \ (srstep \ \)\<^sup>* O (srstep \ \)\<^sup>*" +proof - + from steps obtain u where "(s, u) \ (rstep \)\<^sup>*" "(u, t) \ (rstep \)\<^sup>*" by auto + then have "(s, term_to_sig \ v u) \ (srstep \ \)\<^sup>*" "(term_to_sig \ v u, t) \ (srstep \ \)\<^sup>*" + using rstep_trancl_sig_step_l[OF _ assms(2) funas(2), of u v] + using rstep_trancl_sig_step_r[OF _ assms(1) funas(1), of u v] funas + by (auto simp: rtrancl_eq_or_trancl) + then show ?thesis by auto +qed + + +subsubsection \Distributivity laws\ + +lemma rstep_smycl_dist: + "(rstep \)\<^sup>\ = rstep (\\<^sup>\)" + by (auto simp: sig_step_def) + +lemma sig_step_symcl_dist: + "(sig_step \ \)\<^sup>\ = sig_step \ (\\<^sup>\)" + by (auto simp: sig_step_def) + +lemma srstep_symcl_dist: + "(srstep \ \)\<^sup>\ = srstep \ (\\<^sup>\)" + by (auto simp: sig_step_def) + +lemma Restr_smycl_dist: + "(Restr \ \)\<^sup>\ = Restr (\\<^sup>\) \" + by auto + +lemmas rew_symcl_inwards = rstep_smycl_dist sig_step_symcl_dist srstep_symcl_dist Restr_smycl_dist +lemmas rew_symcl_outwards = rew_symcl_inwards[symmetric] + +lemma rstep_converse_dist: + "(rstep \)\ = rstep (\\)" + by auto + +lemma srrstep_converse_dist: + "(srrstep \ \)\ = srrstep \ (\\)" + by (fastforce simp: sig_step_def) + +lemma sig_step_converse_rstep: + "(srstep \ \)\ = sig_step \ ((rstep \)\)" + by (meson converse.simps set_eq_subset sig_stepE(1) sig_stepE sig_stepI subrelI) + +lemma srstep_converse_dist: + "(srstep \ \)\ = srstep \ (\\)" + by (auto simp: sig_step_def) + +lemma Restr_converse: "(Restr \ A)\ = Restr (\\) A" + by auto + +lemmas rew_converse_inwards = rstep_converse_dist srrstep_converse_dist sig_step_converse_rstep + srstep_converse_dist Restr_converse trancl_converse[symmetric] rtrancl_converse[symmetric] +lemmas rew_converse_outwards = rew_converse_inwards[symmetric] + +lemma sig_step_rsteps_dist: + "funas_rel \ \ \ \ sig_step \ ((rstep \)\<^sup>+) = (srstep \ \)\<^sup>+" + by (auto elim!: sig_stepE dest: srstepsD) + +lemma sig_step_rsteps_eq_dist: + "funas_rel \ \ \ \ sig_step \ ((rstep \)\<^sup>+) \ Id = (srstep \ \)\<^sup>*" + by (auto simp: rtrancl_eq_or_trancl sig_step_rsteps_dist) + +lemma sig_step_conversion_dist: + "(srstep \ \)\<^sup>\\<^sup>* = (srstep \ (\\<^sup>\))\<^sup>*" + by (auto simp: rtrancl_eq_or_trancl sig_step_rsteps_dist conversion_def srstep_symcl_dist) + +lemma gsrstep_conversion_dist: + "(gsrstep \ \)\<^sup>\\<^sup>* = (gsrstep \ (\\<^sup>\))\<^sup>*" + by (auto simp: conversion_def rew_symcl_inwards) + +lemma sig_step_grstep_dist: + "gsrstep \ \ = sig_step \ (Restr (rstep \) (Collect ground))" + by (auto simp: sig_step_def) + +subsection \Substitution closure of @{const srstep}\ + +lemma srstep_subst_closed: + assumes "(s, t) \ srstep \ \" "\ x. funas_term (\ x) \ \" + shows "(s \ \, t \ \) \ srstep \ \" using assms + by (auto simp: sig_step_def funas_term_subst) + +lemma srsteps_subst_closed: + assumes "(s, t) \ (srstep \ \)\<^sup>+" "\ x. funas_term (\ x) \ \" + shows "(s \ \, t \ \) \ (srstep \ \)\<^sup>+" using assms(1) +proof (induct rule: trancl.induct) + case (r_into_trancl s t) show ?case + using srstep_subst_closed[OF r_into_trancl assms(2)] + by auto +next + case (trancl_into_trancl s t u) + from trancl_into_trancl(2) show ?case + using srstep_subst_closed[OF trancl_into_trancl(3) assms(2)] + by (meson rtrancl_into_trancl1 trancl_into_rtrancl) +qed + +lemma srsteps_eq_subst_closed: + assumes "(s, t) \ (srstep \ \)\<^sup>*" "\ x. funas_term (\ x) \ \" + shows "(s \ \, t \ \) \ (srstep \ \)\<^sup>*" using assms srsteps_subst_closed + by (metis rtrancl_eq_or_trancl) + +lemma srsteps_eq_subst_relcomp_closed: + assumes "(s, t) \ (srstep \ \)\<^sup>* O (srstep \ \)\<^sup>*" "\ x. funas_term (\ x) \ \" + shows "(s \ \, t \ \) \ (srstep \ \)\<^sup>* O (srstep \ \)\<^sup>*" +proof - + from assms(1) obtain u where "(s, u) \ (srstep \ \)\<^sup>*" "(u, t) \ (srstep \ \)\<^sup>*" by auto + then have "(s \ \, u \ \) \ (srstep \ \)\<^sup>*" "(u \ \, t \ \) \ (srstep \ \)\<^sup>*" + using assms srsteps_eq_subst_closed + by metis+ + then show ?thesis by auto +qed + + +subsection \Context closure of @{const srstep}\ + +lemma srstep_ctxt_closed: + assumes "funas_ctxt C \ \" and "(s, t) \ srstep \ \" + shows "(C\s\, C\t\) \ srstep \ \" using assms + by (intro sig_stepI) (auto dest: srstepD) + +lemma srsteps_ctxt_closed: + assumes "funas_ctxt C \ \" and "(s, t) \ (srstep \ \)\<^sup>+" + shows "(C\s\, C\t\) \ (srstep \ \)\<^sup>+" using assms(2) srstep_ctxt_closed[OF assms(1)] + by (induct) force+ + +lemma srsteps_eq_ctxt_closed: + assumes "funas_ctxt C \ \" and "(s, t) \ (srstep \ \)\<^sup>*" + shows "(C\s\, C\t\) \ (srstep \ \)\<^sup>*" using srsteps_ctxt_closed[OF assms(1)] assms(2) + by (metis rtrancl_eq_or_trancl) + +lemma sig_steps_join_ctxt_closed: + assumes "funas_ctxt C \ \" and "(s, t) \ (srstep \ \)\<^sup>\" + shows "(C\s\, C\t\) \ (srstep \ \)\<^sup>\" using srsteps_eq_ctxt_closed[OF assms(1)] assms(2) + unfolding join_def rew_converse_inwards + by auto + + +text \The following lemma shows that every rewrite sequence either contains a root step or is root stable\ + +lemma nsrsteps_with_root_step_step_on_args: + assumes "(s, t) \ (srstep \ \)\<^sup>+" "(s, t) \ srsteps_with_root_step \ \" + shows "\ f ss ts. s = Fun f ss \ t = Fun f ts \ length ss = length ts \ + (\ i < length ts. (ss ! i, ts ! i) \ (srstep \ \)\<^sup>*)" using assms +proof (induct) + case (base t) + obtain C l r \ where [simp]: "s = C\l \ \\" "t = C\r \ \\" and r: "(l, r) \ \" + using base(1) unfolding sig_step_def + by blast + then have funas: "funas_ctxt C \ \" "funas_term (l \ \) \ \" "funas_term (r \ \) \ \" + using base(1) by (auto simp: sig_step_def) + from funas(2-) r have "(l \ \, r \ \) \ srrstep \ \" + by (auto simp: sig_step_def) + then have "C = Hole \ False" using base(2) r + by (auto simp: srsteps_with_root_step_def) + then obtain f ss D ts where [simp]: "C = More f ss D ts" by (cases C) auto + have "(D\l \ \\, D\r \ \\) \ (srstep \ \)" using base(1) r funas + by (auto simp: sig_step_def) + then show ?case using funas by (auto simp: nth_append_Cons) +next + case (step t u) show ?case + proof (cases "(s, t) \ srsteps_with_root_step \ \ \ (t, u) \ sig_step \ (rrstep \)") + case True then show ?thesis using step(1, 2, 4) + by (auto simp add: relcomp3_I rtrancl.rtrancl_into_rtrancl srsteps_with_root_step_def) + next + case False + obtain C l r \ where *[simp]: "t = C\l \ \\" "u = C\r \ \\" and r: "(l, r) \ \" + using step(2) unfolding sig_step_def by blast + then have funas: "funas_ctxt C \ \" "funas_term (l \ \) \ \" "funas_term (r \ \) \ \" + using step(2) by (auto simp: sig_step_def) + from False have "C \ Hole" using funas r by (force simp: sig_step_def) + then obtain f ss D ts where c[simp]: "C = More f ss D ts" by (cases C) auto + from step(3, 1) False obtain g sss tss where + **[simp]: "s = Fun g sss" "t = Fun g tss" and l: "length sss = length tss" and + inv: "\ i < length tss. (sss ! i, tss ! i) \ (srstep \ \)\<^sup>*" + by auto + have [simp]: "g = f" and lc: "Suc (length ss + length ts) = length sss" + using l *(1) unfolding c using **(2) by auto + then have "\ i < Suc (length ss + length ts). ((ss @ D\l \ \\ # ts) ! i, (ss @ D\r \ \\ # ts) ! i) \ (srstep \ \)\<^sup>*" + using * funas r by (auto simp: nth_append_Cons r_into_rtrancl rstep.intros rstepI sig_stepI) + then have "i < length tss \ (sss ! i, (ss @ D\r \ \\ # ts) ! i) \ (srstep \ \)\<^sup>*" for i + using inv * l lc funas ** + by (auto simp: nth_append_Cons simp del: ** * split!: if_splits) + then show ?thesis using inv l lc * unfolding c + by auto + qed +qed + +lemma rstep_to_pos_replace: + assumes "(s, t) \ rstep \" + shows "\ p l r \. p \ poss s \ (l, r) \ \ \ s |_ p = l \ \ \ t = s[p \ r \ \]" +proof - + from assms obtain C l r \ where st: "(l, r) \ \" "s = C\l \ \\" "t = C\r \ \\" + using rstep_imp_C_s_r by fastforce + from st(2, 3) have *: "t = s[hole_pos C \ r \ \]" by simp + from this st show ?thesis unfolding * + by (intro exI[of _ "hole_pos C"]) auto +qed + +lemma pos_replace_to_rstep: + assumes "p \ poss s" "(l, r) \ \" + and "s |_ p = l \ \" "t = s[p \ r \ \]" + shows "(s, t) \ rstep \" + using assms(1, 3-) replace_term_at_subt_at_id [of s p] + by (intro rstepI[OF assms(2), of s "ctxt_at_pos s p" \]) + (auto simp add: ctxt_of_pos_term_apply_replace_at_ident) + +end \ No newline at end of file diff --git a/thys/Rewrite_Properties_Reduction/Rewriting/Rewriting_GTRS.thy b/thys/Rewrite_Properties_Reduction/Rewriting/Rewriting_GTRS.thy new file mode 100644 --- /dev/null +++ b/thys/Rewrite_Properties_Reduction/Rewriting/Rewriting_GTRS.thy @@ -0,0 +1,117 @@ +theory Rewriting_GTRS + imports Rewriting + Replace_Constant +begin + +subsection \Specific results about rewriting under a ground system\ +abbreviation "ground_sys \ \ (\ (s, t) \ \. ground s \ ground t)" + +lemma srrstep_ground: + assumes "ground_sys \" + and "(s, t) \ srrstep \ \" + shows "ground s" "ground t" using assms + by (auto simp: sig_step_def ground_subst_apply vars_term_subst elim!: rrstep_subst) + +lemma srstep_pres_ground_l: + assumes "ground_sys \" "ground s" + and "(s, t) \ srstep \ \" + shows "ground t" using assms + by (auto simp: sig_step_def ground_subst_apply dest!: rstep_imp_C_s_r) + +lemma srstep_pres_ground_r: + assumes "ground_sys \" "ground t" + and "(s, t) \ srstep \ \" + shows "ground s" using assms + by (auto simp: ground_vars_term_empty vars_term_subst sig_step_def vars_term_ctxt_apply ground_subst_apply dest!: rstep_imp_C_s_r) + +lemma srsteps_pres_ground_l: + assumes "ground_sys \" "ground s" + and "(s, t) \ (srstep \ \)\<^sup>+" + shows "ground t" using assms(3, 2) srstep_pres_ground_l[OF assms(1)] + by (induct rule: converse_trancl_induct) auto + +lemma srsteps_pres_ground_r: + assumes "ground_sys \" "ground t" + and "(s, t) \ (srstep \ \)\<^sup>+" + shows "ground s" using assms(3, 2) srstep_pres_ground_r[OF assms(1)] + by (induct rule: converse_trancl_induct) auto + + +lemma srsteps_eq_pres_ground_l: + assumes "ground_sys \" "ground s" + and "(s, t) \ (srstep \ \)\<^sup>*" + shows "ground t" using srsteps_pres_ground_l[OF assms(1, 2)] assms(2, 3) + by (auto simp: rtrancl_eq_or_trancl) + +lemma srsteps_eq_pres_ground_r: + assumes "ground_sys \" "ground t" + and "(s, t) \ (srstep \ \)\<^sup>*" + shows "ground s" using srsteps_pres_ground_r[OF assms(1, 2)] assms(2, 3) + by (auto simp: rtrancl_eq_or_trancl) + +lemma srsteps_with_root_step_ground: + assumes "ground_sys \" + and "(s, t) \ srsteps_with_root_step \ \" + shows "ground s" "ground t" using srrstep_ground[OF assms(1)] + using srsteps_eq_pres_ground_l[OF assms(1)] + using srsteps_eq_pres_ground_r[OF assms(1)] + using assms(2) unfolding srsteps_with_root_step_def + by (meson relcomp.cases)+ + +subsection \funas\ + +lemma srrstep_funas: + assumes "ground_sys \" + and "(s, t) \ srrstep \ \" + shows "funas_term s \ funas_rel \" "funas_term t \ funas_rel \" using assms + by (auto simp: sig_step_def funas_term_subst ground_vars_term_empty funas_rel_def split: prod.splits elim!: rrstep_subst) + +lemma srstep_funas_l: + assumes "ground_sys \" + and "(s, t) \ srstep \ \" + shows "funas_term t \ funas_term s \ funas_rel \" using assms + by (auto simp: ground_vars_term_empty vars_term_subst sig_step_def vars_term_ctxt_apply + funas_term_subst funas_rel_def split: prod.splits dest!: rstep_imp_C_s_r) + +lemma srstep_funas_r: + assumes "ground_sys \" + and "(s, t) \ srstep \ \" + shows "funas_term s \ funas_term t \ funas_rel \" using assms + by (auto simp: ground_vars_term_empty vars_term_subst sig_step_def vars_term_ctxt_apply + funas_term_subst funas_rel_def split: prod.splits dest!: rstep_imp_C_s_r) + +lemma srsteps_funas_l: + assumes "ground_sys \" + and "(s, t) \ (srstep \ \)\<^sup>+" + shows "funas_term t \ funas_term s \ funas_rel \" using assms(2) + by (induct rule: converse_trancl_induct) (auto dest: srstep_funas_l[OF assms(1)]) + +lemma srsteps_funas_r: + assumes "ground_sys \" + and "(s, t) \ (srstep \ \)\<^sup>+" + shows "funas_term s \ funas_term t \ funas_rel \" using assms(2) + by (induct rule: converse_trancl_induct) (auto dest: srstep_funas_r[OF assms(1)]) + +lemma srsteps_eq_funas_l: + assumes "ground_sys \" + and "(s, t) \ (srstep \ \)\<^sup>*" + shows "funas_term t \ funas_term s \ funas_rel \" using srsteps_funas_l[OF assms(1)] assms(2) + by (auto simp: rtrancl_eq_or_trancl) + +lemma srsteps_eq_funas_r: + assumes "ground_sys \" + and "(s, t) \ (srstep \ \)\<^sup>*" + shows "funas_term s \ funas_term t \ funas_rel \" using srsteps_funas_r[OF assms(1)] assms(2) + by (auto simp: rtrancl_eq_or_trancl) + +lemma srsteps_with_root_step_funas: + assumes "ground_sys \" + and "(s, t) \ srsteps_with_root_step \ \" + shows "funas_term s \ funas_rel \" "funas_term t \ funas_rel \" + using srrstep_funas[OF assms(1)] + using srsteps_eq_funas_l[OF assms(1)] + using srsteps_eq_funas_r[OF assms(1)] + using assms(2) unfolding srsteps_with_root_step_def + by (metis relcompEpair sup_absorb2)+ + +end \ No newline at end of file diff --git a/thys/Rewrite_Properties_Reduction/Rewriting/Rewriting_LLRG_LV_Mondaic.thy b/thys/Rewrite_Properties_Reduction/Rewriting/Rewriting_LLRG_LV_Mondaic.thy new file mode 100644 --- /dev/null +++ b/thys/Rewrite_Properties_Reduction/Rewriting/Rewriting_LLRG_LV_Mondaic.thy @@ -0,0 +1,508 @@ +theory Rewriting_LLRG_LV_Mondaic + imports Rewriting + Replace_Constant +begin + + + +subsection \Specific results about rewriting under a linear variable-separated system\ +(***************** AUX ********************) + +lemma card_varposs_ground: + "card (varposs s) = 0 \ ground s" + by (simp add: finite_varposs varposs_empty_gound) + +lemma poss_of_term_subst_apply_varposs: + assumes "p \ poss_of_term (constT c) (s \ \)" "(c, 0) \ funas_term s" + shows "\ q. q \ varposs s \ q \\<^sub>p p" using assms +proof (induct p arbitrary: s) + case Nil + then show ?case by (cases s) (auto simp: poss_of_term_def) +next + case (Cons i p) + show ?case using Cons(1)[of "args s ! i"] Cons(2-) + apply (cases s) + apply (auto simp: poss_of_term_def) + apply (metis position_less_eq_Cons)+ + done +qed + +lemma poss_of_term_hole_poss: + assumes "p \ poss_of_term t C\s\" and "hole_pos C \\<^sub>p p" + shows "p -\<^sub>p hole_pos C \ poss_of_term t s" using assms +proof (induct C arbitrary: p) + case (More f ss C ts) + from More(3) obtain ps where [simp]: "p = length ss # ps" and h: "hole_pos C \\<^sub>p ps" + by (metis append_Cons hole_pos.simps(2) less_eq_poss_append_itself pos_les_eq_append_diff) + show ?case using More(1)[OF _ h] More(2) + by (auto simp: poss_of_term_def) +qed auto + +lemma remove_const_subst_from_match: + assumes "s \ const_subst c = C\l \ \\" "(c, 0) \ funas_term l" "linear_term l" + shows "\ D \. s = D\l \ \\" using assms +proof (induct "card (varposs s)" arbitrary: s) + case (Suc x) + from Suc(2) obtain p ps where varposs: "varposs s = insert p ps" "p \ ps" + by (metis card_Suc_eq) + let ?s = "s[p \ Fun c []]" have vp: "p \ varposs s" using varposs by auto + then have *: "?s \ const_subst c = s \ const_subst c" + by (induct s arbitrary: p) (auto simp: nth_list_update map_update intro!: nth_equalityI) + have "varposs ?s = ps" using varposs varposs_ground_replace_at[of p s "constT c"] + by auto + from Suc(1)[of ?s] Suc(2-) varposs obtain D \ where split: "s[p \ constT c] = D\l \ \\" + by (metis "*" \varposs s[p \ constT c] = ps\ card_insert_if diff_Suc_1 finite_varposs) + have wit: "s = D\l \ \\[p \ s |_ p]" unfolding arg_cong[OF split, of "\ t. t[p \ s |_ p]", symmetric] + using vp by simp + from vp split have cases: "p \ hole_pos D \ hole_pos D \\<^sub>p p" + by auto (metis poss_of_term_const_ctxt_apply poss_of_term_replace_term_at varposs_imp_poss) + show ?case + proof (cases "p \ hole_pos D") + case True then show ?thesis using wit + by (auto simp: par_hole_pos_replace_term_context_at) + next + case False + then have hole: "hole_pos D \\<^sub>p p" using cases by auto + from vp split have "p \ poss_of_term (constT c) s[p \ constT c]" + using poss_of_term_replace_term_at varposs_imp_poss by blast + from poss_of_term_hole_poss[OF this[unfolded split] hole] + have "p -\<^sub>p hole_pos D \ poss_of_term (constT c) (l \ \)" + by simp + from poss_of_term_subst_apply_varposs[OF this Suc(4)] obtain q where + q: "q \ varposs l" "q \\<^sub>p (p -\<^sub>p (hole_pos D))" by blast + show ?thesis using wit Suc(5) hole + using linear_term_varposs_subst_replace_term[OF Suc(5) q, of \ "s |_ p"] + by auto + qed +qed (auto simp: card_varposs_ground ground_subst_apply) + + + + +(***************** end AUX ********************) + +definition "llrg \ \ (\ (l, r) \ \. linear_term l \ ground r)" + +definition "lv \ \ (\ (l, r) \ \. linear_term l \ linear_term r \ vars_term l \ vars_term r = {})" + +definition "monadic \ \ (\ (f, n) \ \. n \ Suc 0)" + +\ \NF of ground terms\ + +lemma ground_NF_srstep_gsrstep: + "ground s \ s \ NF (srstep \ \) \ s \ NF (gsrstep \ \)" + by blast + +lemma NF_to_fresh_const_subst_NF: + assumes lin: "linear_sys \" and fresh_const: "(c, 0) \ funas_rel \" "funas_rel \ \ \" + and nf_f: "funas_term s \ \" "s \ NF (srstep \ \)" + shows "s \ const_subst c \ NF (gsrstep \ \)" +proof (rule ccontr) + assume "s \ const_subst c \ NF (Restr (srstep \ \) (Collect ground))" + then obtain C l r \ where step: "(l, r) \ \" "s \ const_subst c = C\l \ \\" by fastforce + from step(1) have l: "(c, 0) \ funas_term l" "linear_term l" using lin fresh_const + by (auto simp: funas_rel_def) + obtain D \ where "s = D\l \ \\" using remove_const_subst_from_match[OF step(2) l] by blast + then show False using step(1) nf_f + by (meson NF_no_trancl_step fresh_const(2) r_into_trancl' rstepI rstep_trancl_sig_step_r) +qed + + +lemma fresh_const_subst_NF_pres: + assumes fresh_const: "(c, 0) \ funas_rel \" "funas_rel \ \ \" + and nf_f: "funas_term s \ \" "\ \ \" "(c, 0) \ \" "s \ const_subst c \ NF (gsrstep \ \)" + shows "s \ NF (srstep \ \)" +proof (rule ccontr) + assume "s \ NF (srstep \ \)" + then obtain C l r \ where step: "(l, r) \ \" "s = C\l \ \\" by fastforce + let ?\ = "\ x. if x \ vars_term l then (\ x) \ const_subst c else Fun c []" + define D where "D = (C \\<^sub>c const_subst c)" + have s: "s \ const_subst c = D\l \ ?\\" unfolding D_def step(2) + by (auto simp: subst_compose simp flip: subst_subst_compose intro!: term_subst_eq) + have funas: "funas_ctxt D \ \" "funas_term (l \ ?\) \ \" "funas_term (r \ ?\) \ \" + using step nf_f(1 - 3) fresh_const(2) unfolding D_def + by (auto simp: funas_ctxt_subst_apply_ctxt funas_term_subst funas_rel_def split: if_splits) + moreover have "ground_ctxt D" "ground (l \ ?\)" "ground (r \ ?\)" using arg_cong[OF s, of ground] unfolding D_def + by (auto intro!: ground_substI) + ultimately have "(D\l \ ?\\, D\r \ ?\\) \ gsrstep \ \" using step(1) + by (simp add: rstepI sig_stepI) + then show False using nf_f(4) unfolding s[symmetric] + by blast +qed + +lemma linear_sys_gNF_eq_NF_eq: + assumes lin: "linear_sys \" "linear_sys \" + and well: "funas_rel \ \ \" "funas_rel \ \ \" + and fresh: "(c, 0) \ funas_rel \" "(c, 0) \ funas_rel \" + and lift: "\ \ \" "(c, 0) \ \" + and nf: "NF (gsrstep \ \) = NF (gsrstep \ \)" + shows "NF (srstep \ \) = NF (srstep \ \)" +proof - + have [simp]: "\ funas_term s \ \ \ s \ NF (srstep \ \)" for s \ by (meson NF_I sig_stepE(1)) + have d1: "s \ NF (gsrstep \ \) \ s \ NF (gsrstep \ \)" for s using nf by auto + have d2: "s \ NF (gsrstep \ \) \ s \ NF (gsrstep \ \)" for s using nf by auto + {fix s assume n: "s \ NF (srstep \ \)" then have "s \ NF (srstep \ \)" + using NF_to_fresh_const_subst_NF[OF lin(1) fresh(1) well(1) _ n, THEN d1] + using fresh_const_subst_NF_pres[OF fresh(2) well(2) _ lift, of s] + by (cases "funas_term s \ \") simp_all} + moreover + {fix s assume n: "s \ NF (srstep \ \)" then have "s \ NF (srstep \ \)" + using NF_to_fresh_const_subst_NF[OF lin(2) fresh(2) well(2) _ n, THEN d2] + using fresh_const_subst_NF_pres[OF fresh(1) well(1) _ lift, of s] + by (cases "funas_term s \ \") simp_all} + ultimately show ?thesis by blast +qed + + +\ \Steps of ground\ +lemma gsrsteps_to_srsteps: + "(s, t) \ (gsrstep \ \)\<^sup>+ \ (s, t) \ (srstep \ \)\<^sup>+" + by (meson inf_le1 trancl_mono) + +lemma gsrsteps_eq_to_srsteps_eq: + "(s, t) \ (gsrstep \ \)\<^sup>* \ (s, t) \ (srstep \ \)\<^sup>*" + by (metis gsrsteps_to_srsteps rtrancl_eq_or_trancl) + + +lemma gsrsteps_to_rsteps: + "(s, t) \ (gsrstep \ \)\<^sup>+ \ (s, t) \ (rstep \)\<^sup>+" + using gsrsteps_to_srsteps srstepsD by blast + +lemma gsrsteps_eq_to_rsteps_eq: + "(s, t) \ (gsrstep \ \)\<^sup>* \ (s, t) \ (rstep \)\<^sup>*" + by (metis gsrsteps_eq_to_srsteps_eq rtrancl_eq_or_trancl srstepsD) + + +lemma gsrsteps_eq_relcomp_srsteps_relcompD: + "(s, t) \ (gsrstep \ \)\<^sup>* O (gsrstep \ \)\<^sup>* \ (s, t) \ (srstep \ \)\<^sup>* O (srstep \ \)\<^sup>*" + using gsrsteps_eq_to_srsteps_eq by blast + +lemma gsrsteps_eq_relcomp_to_rsteps_relcomp: + "(s, t) \ (gsrstep \ \)\<^sup>* O (gsrstep \ \)\<^sup>* \ (s, t) \ (rstep \)\<^sup>* O (rstep \)\<^sup>*" + using gsrsteps_eq_relcomp_srsteps_relcompD + using gsrsteps_eq_to_rsteps_eq by blast + + +lemma ground_srsteps_gsrsteps: + assumes "ground s" "ground t" + and "(s, t) \ (srstep \ \)\<^sup>+" + shows "(s, t) \ (gsrstep \ \)\<^sup>+" +proof - + let ?\ = "\ _. s" + from assms(3) have f: "funas_term s \ \" using srstepsD by blast + have "(s \ ?\, t \ ?\) \ (gsrstep \ \)\<^sup>+" using assms(3, 1) f + proof (induct) + case (base t) + then have "(s \ ?\, t \ ?\) \ gsrstep \ \" + by (auto intro: srstep_subst_closed) + then show ?case by auto + next + case (step t u) + from step(2, 4, 5) have "(t \ ?\, u \ ?\) \ gsrstep \ \" + by (auto intro: srstep_subst_closed) + then show ?case using step(3 - 5) + by (meson Transitive_Closure.trancl_into_trancl) + qed + then show ?thesis using assms(1, 2) + by (simp add: ground_subst_apply) +qed + +lemma ground_srsteps_eq_gsrsteps_eq: + assumes "ground s" "ground t" + and "(s, t) \ (srstep \ \)\<^sup>*" + shows "(s, t) \ (gsrstep \ \)\<^sup>*" + using ground_srsteps_gsrsteps + by (metis assms rtrancl_eq_or_trancl) + +lemma srsteps_eq_relcomp_gsrsteps_relcomp: + assumes "(s, t) \ (srstep \ \)\<^sup>* O (srstep \ \)\<^sup>*" + and "ground s" "ground t" + shows "(s, t) \ (gsrstep \ \)\<^sup>* O (gsrstep \ \)\<^sup>*" +proof - + from assms(1) obtain u where steps: "(s, u) \ (srstep \ \)\<^sup>*" "(u, t) \ (srstep \ \)\<^sup>*" + by blast + let ?\ = "\ x. s" + have "(s \ ?\, u \ ?\) \ (srstep \ \)\<^sup>*" "(u \ ?\, t \ ?\) \ (srstep \ \)\<^sup>*" using steps + using srsteps_eq_subst_closed[OF steps(1), of ?\] + using srsteps_eq_subst_closed[OF steps(2), of ?\] + by (metis rtrancl_eq_or_trancl srstepsD)+ + then have "(s \ ?\, u \ ?\) \ (gsrstep \ \)\<^sup>*" "(u \ ?\, t \ ?\) \ (gsrstep \ \)\<^sup>*" + using assms(2) + by (auto intro: ground_srsteps_eq_gsrsteps_eq) + then show ?thesis using assms(2, 3) + by (auto simp: ground_subst_apply) +qed + +\ \Steps of llrg systems\ + +lemma llrg_ground_rhs: + "llrg \ \ (l, r) \ \ \ ground r" + unfolding llrg_def by auto + +lemma llrg_rrsteps_groundness: + assumes "llrg \" and "(s, t) \ (srrstep \ \)" + shows "ground t" using assms(2) ground_vars_term_empty + by (fastforce simp: llrg_def sig_step_def dest!: llrg_ground_rhs[OF assms(1)] split: prod.splits) + +lemma llrg_rsteps_pres_groundness: + assumes "llrg \" "ground s" + and "(s, t) \ (srstep \ \)\<^sup>*" + shows "ground t" using assms(3, 2) +proof (induct rule: rtrancl.induct) + case (rtrancl_into_rtrancl s t u) + then have "ground t" by auto + then show ?case using rtrancl_into_rtrancl(3) + by (auto simp: sig_step_def vars_term_ctxt_apply ground_vars_term_empty ground_subst_apply + dest!: llrg_ground_rhs[OF assms(1)] rstep_imp_C_s_r split: prod.splits) +qed simp + +lemma llrg_srsteps_with_root_step_ground: + assumes "llrg \" and "(s, t) \ srsteps_with_root_step \ \" + shows "ground t" using assms llrg_rrsteps_groundness llrg_rsteps_pres_groundness + unfolding srsteps_with_root_step_def + by blast + +lemma llrg_srsteps_with_root_step_inv_ground: + assumes "llrg \" and "(s, t) \ srsteps_with_root_step \ (\\)" + shows "ground s" using assms llrg_rrsteps_groundness llrg_rsteps_pres_groundness + unfolding srsteps_with_root_step_def + by (metis (no_types, lifting) converseD relcomp.cases rtrancl_converseD srrstep_converse_dist srstep_converse_dist) + +lemma llrg_funas_term_step_pres: + assumes "llrg \" and "(s, t) \ (rstep \)" + shows "funas_term t \ funas_rel \ \ funas_term s" +proof - + have [simp]: "(l, r) \ \ \ r \ \ = r" for l r \ using assms(1) unfolding llrg_def + by(auto split: prod.splits intro: ground_subst_apply) + show ?thesis using assms + by (auto simp: llrg_def funas_rel_def dest!: rstep_imp_C_s_r) +qed + +lemma llrg_funas_term_steps_pres: + assumes "llrg \" and "(s, t) \ (rstep \)\<^sup>*" + shows "funas_term t \ funas_rel \ \ funas_term s" + using assms(2) llrg_funas_term_step_pres[OF assms(1)] + by (induct) auto + +\ \Steps of monadic llrg systems\ + + +lemma monadic_ground_ctxt_apply: + "monadic \ \ funas_ctxt C \ \ \ ground r \ ground C\r\" + by (induct C) (auto simp: monadic_def) + +lemma llrg_monadic_rstep_pres_groundness: + assumes "llrg \" "monadic \" + and "(s, t) \ srstep \ \" + shows "ground t" using assms(3) +proof - + from assms(3) obtain C l r \ where r: "(l, r) \ \" and t:"t = C\r \ \\" + using rstep_imp_C_s_r unfolding sig_step_def by blast + from assms(1, 3) have funas: "funas_term t \ \" "ground r" + by (auto simp: llrg_ground_rhs[OF assms(1) r(1)] dest: srstepD) + then have *: "r \ \ = r" by (simp add: ground_subst_apply) + show ?thesis using funas assms(2) unfolding t * + by (intro monadic_ground_ctxt_apply) auto +qed + +lemma llrg_monadic_rsteps_groundness: + assumes "llrg \" "monadic \" + and "(s, t) \ (srstep \ \)\<^sup>+" + shows "ground t" using assms(3) + using llrg_monadic_rstep_pres_groundness[OF assms(1 ,2)] + by (induct rule: trancl.induct) auto + +\ \Steps in monadic lv system\ + +fun monadic_term where + "monadic_term (Var x) = True" +| "monadic_term (Fun f []) = True" +| "monadic_term (Fun f ts) = (length ts = Suc 0 \ monadic_term (hd ts))" + +fun monadic_get_leave where + "monadic_get_leave (Var x) = (Var x)" +| "monadic_get_leave (Fun f []) = Fun f []" +| "monadic_get_leave (Fun f ts) = monadic_get_leave (hd ts)" + +fun monadic_replace_leave where + "monadic_replace_leave t (Var x) = t" +| "monadic_replace_leave t (Fun f []) = t" +| "monadic_replace_leave t (Fun f ts) = Fun f [monadic_replace_leave t (hd ts)]" + + +lemma monadic_replace_leave_undo_const_subst: + assumes "monadic_term s" + shows "monadic_replace_leave (monadic_get_leave s) (s \ const_subst c) = s" using assms +proof (induct s) + case (Fun f ts) then show ?case + by (cases ts) auto +qed auto + +lemma monadic_replace_leave_context: + assumes "monadic_term C\s\" + shows "monadic_replace_leave t C\s\ = C\monadic_replace_leave t s\" using assms +proof (induct C) + case (More f ss C ts) then show ?case + by (cases ss; cases ts) auto +qed simp + +lemma monadic_replace_leave_subst: + assumes "monadic_term (s \ \)" "\ ground s" + shows "monadic_replace_leave t (s \ \) = s \ (\ x. monadic_replace_leave t (\ x))" using assms +proof (induct s) + case (Fun f ts) then show ?case + by (cases ts) auto +qed auto + +lemma monadic_sig: + "monadic \ \ (f, length ts) \ \ \ length ts \ Suc 0" + by (auto simp: monadic_def) + +lemma monadic_sig_funas_term_mt: + "monadic \ \ funas_term s \ \ \ monadic_term s" +proof (induct s) + case (Fun f ts) then show ?case unfolding monadic_def + by (cases ts) auto +qed simp + +lemma monadic_term_const_pres [intro]: + "monadic_term s \ monadic_term (s \ const_subst c)" +proof (induct s) + case (Fun f ts) then show ?case + by (cases ts) auto +qed simp + +lemma remove_const_lv_mondaic_step_lhs: + assumes lv: "lv \" and fresh: "(c, 0) \ funas_rel \" + and mon: "monadic \" + and step: "(s \ const_subst c, t) \ (srstep \ \)" + shows "(s, t) \ (srstep \ \)" +proof - + from step obtain C l r \ where s: "(l, r) \ \" "s \ const_subst c = C\l \ \\" "t = C\r \ \\" + by fastforce + have lv: "x \ vars_term l \ x \ vars_term r" for x using s(1) lv + by (auto simp: lv_def) + from s(1) fresh have cl: "(c, 0) \ funas_term l" by (auto simp: funas_rel_def) + have funas: "funas_term s \ \" "(c, 0) \ funas_term l" "funas_term t \ \" using s(1) fresh + using step mon funas_term_subst unfolding funas_rel_def + by (auto dest!: srstepD) blast + then have mt: "monadic_term s" "monadic_term (s \ const_subst c)" + using monadic_sig_funas_term_mt[OF mon] by auto + then have ml: "monadic_term (l \ \)" unfolding s(2) + by (metis funas_ctxt_apply le_sup_iff step mon monadic_sig_funas_term_mt s(2) sig_stepE(1)) + show ?thesis + proof (cases "ground s") + case True then show ?thesis using step + by (auto simp: ground_subst_apply) + next + case False note ng = this + then have cs: "(c, 0) \ funas_term (s \ const_subst c)" + by (auto simp: funas_term_subst vars_term_empty_ground) + have ngrl: "\ ground l" using s(2) cs mt ng + proof (induct s arbitrary: C) + case (Var x) then show ?case using cl cs + by (cases C) (auto simp: funas_rel_def ground_subst_apply) + next + case (Fun f ts) + from Fun(5-) obtain t where [simp]: "ts = [t]" by (cases ts) auto + show ?case + proof (cases "C = Hole") + case True then show ?thesis using Fun(2, 3) cl + by (auto simp: ground_subst_apply) + next + case False + from this Fun(2, 3) obtain D where [simp]: "C = More f [] D []" + by (cases C) (auto simp: Cons_eq_append_conv) + show ?thesis using Fun(1)[of t D] Fun(2-) + by simp + qed + qed + let ?\ = "\ x. if x \ vars_term l then monadic_replace_leave (monadic_get_leave s) (\ x) else (\ x)" + have "C\l \ (\ x. monadic_replace_leave (monadic_get_leave s) (\ x))\ = C\l \ ?\\" + by (auto intro: term_subst_eq) + then have "s = C\l \ ?\\" using arg_cong[OF s(2), of "monadic_replace_leave (monadic_get_leave s)", + unfolded monadic_replace_leave_undo_const_subst[OF mt(1), of c], + unfolded monadic_replace_leave_context[OF mt(2)[unfolded s(2)]], + unfolded monadic_replace_leave_subst[OF ml ngrl]] + by presburger + moreover have "t = C\r \ ?\\" using lv unfolding s(3) + by (auto intro!: term_subst_eq) + ultimately show ?thesis using s(1) funas(1, 3) + by blast + qed +qed + +lemma remove_const_lv_mondaic_step_rhs: + assumes lv: "lv \" and fresh: "(c, 0) \ funas_rel \" + and mon: "monadic \" + and step: "(s, t \ const_subst c) \ (srstep \ \)" + shows "(s, t) \ (srstep \ \)" +proof - + have inv_v: "lv (\\)""(c, 0) \ funas_rel (\\)" using fresh lv + by (auto simp: funas_rel_def lv_def) + have "(t \ const_subst c, s) \ (srstep \ (\\))" using step + by (auto simp: rew_converse_outwards) + from remove_const_lv_mondaic_step_lhs[OF inv_v mon this] + have "(t, s) \ (srstep \ (\\))" by simp + then show ?thesis by (auto simp: rew_converse_outwards) +qed + +lemma remove_const_lv_mondaic_steps_lhs: + assumes lv: "lv \" and fresh: "(c, 0) \ funas_rel \" + and mon: "monadic \" + and steps: "(s \ const_subst c, t) \ (srstep \ \)\<^sup>+" + shows "(s, t) \ (srstep \ \)\<^sup>+" + using remove_const_lv_mondaic_step_lhs[OF lv fresh mon] steps + by (meson converse_tranclE r_into_trancl trancl_into_trancl2) + +lemma remove_const_lv_mondaic_steps_rhs: + assumes lv: "lv \" and fresh: "(c, 0) \ funas_rel \" + and mon: "monadic \" + and steps: "(s, t \ const_subst c) \ (srstep \ \)\<^sup>+" + shows "(s, t) \ (srstep \ \)\<^sup>+" + using remove_const_lv_mondaic_step_rhs[OF lv fresh mon] steps + by (meson trancl.simps) + + +lemma remove_const_lv_mondaic_steps: + assumes lv: "lv \" and fresh: "(c, 0) \ funas_rel \" + and mon: "monadic \" + and steps: "(s \ const_subst c, t \ const_subst c) \ (srstep \ \)\<^sup>+" + shows "(s, t) \ (srstep \ \)\<^sup>+" + using remove_const_lv_mondaic_steps_rhs[OF lv fresh mon remove_const_lv_mondaic_steps_lhs[OF assms]] + by simp + +\ \Steps on lv trs\ + +lemma lv_root_step_idep_subst: + assumes "lv \" + and "(s, t) \ srrstep \ \" + and well: "\ x. funas_term (\ x) \ \" "\ x. funas_term (\ x) \ \" + shows "(s \ \, t \ \) \ srrstep \ \" +proof - + from assms(2) obtain l r \ where mid: "s = l \ \" "t = r \ \" "(l, r) \ \" + by (auto simp: sig_step_def) + from mid(3) assms(1) have vs: "x \ vars_term l \ x \ vars_term r" for x + by (auto simp: lv_def) + let ?\ = "\ x. if x \ vars_term l then (\ x) \ \ else (\ x) \ \" + have subst: "s \ \ = l \ ?\" "t \ \ = r \ ?\" + unfolding mid subst_subst_compose[symmetric] + unfolding term_subst_eq_conv + by (auto simp: subst_compose_def vs) + then show ?thesis unfolding subst + using assms(2) mid(3) well unfolding mid(1, 2) + by (auto simp: sig_step_def funas_term_subst) +qed + + +lemma lv_srsteps_with_root_step_idep_subst: + assumes "lv \" + and "(s, t) \ srsteps_with_root_step \ \" + and well: "\ x. funas_term (\ x) \ \" "\ x. funas_term (\ x) \ \" + shows "(s \ \, t \ \) \ srsteps_with_root_step \ \" using assms(2) + using lv_root_step_idep_subst[OF assms(1) _ well, where ?x1 = id and ?x2 = id] + using srsteps_eq_subst_closed[OF _ well(1), where ?x1 = id and ?\ = \] + using srsteps_eq_subst_closed[OF _ well(2), where ?x1 = id and ?\ = \] + by (auto simp: srsteps_with_root_step_def) (metis (full_types) relcomp3_I) + +end \ No newline at end of file diff --git a/thys/Rewrite_Properties_Reduction/Rewriting/Rewriting_Properties.thy b/thys/Rewrite_Properties_Reduction/Rewriting/Rewriting_Properties.thy new file mode 100644 --- /dev/null +++ b/thys/Rewrite_Properties_Reduction/Rewriting/Rewriting_Properties.thy @@ -0,0 +1,729 @@ +section \Confluence related rewriting properties\ +theory Rewriting_Properties + imports Rewriting + "Abstract-Rewriting.Abstract_Rewriting" +begin + +subsection \Confluence related ARS properties\ +definition "SCR_on r A \ (\a \ A. \ b c. (a, b) \ r \ (a, c) \ r \ + (\ d. (b, d) \ r\<^sup>= \ (c, d) \ r\<^sup>*))" + +abbreviation SCR :: "'a rel \ bool" where "SCR r \ SCR_on r UNIV" + +definition NFP_on :: "'a rel \ 'a set \ bool" where + "NFP_on r A \ (\a\A. \b c. (a, b) \ r\<^sup>* \ (a, c) \ r\<^sup>! \ (b, c) \ r\<^sup>*)" + +abbreviation NFP :: "'a rel \ bool" where "NFP r \ NFP_on r UNIV" + +definition CE_on :: "'a rel \ 'a rel \ 'a set \ bool" where + "CE_on r s A \ (\a\A. \b. (a, b) \ r\<^sup>\\<^sup>* \ (a, b) \ s\<^sup>\\<^sup>*)" + +abbreviation CE :: "'a rel \ 'a rel \ bool" where "CE r s \ CE_on r s UNIV" + +definition NE_on :: "'a rel \ 'a rel \ 'a set \ bool" where + "NE_on r s A \ (\a\A. \b. (a, b) \ r\<^sup>! \ (a, b) \ s\<^sup>!)" + +abbreviation NE :: "'a rel \ 'a rel \ bool" where "NE r s \ NE_on r s UNIV" + +subsection \Signature closure of relation to model multihole context closure\ + +(* AUX lemmas *) + +lemma all_ctxt_closed_sig_rsteps [intro]: + fixes \ :: "('f,'v) term rel" + shows "all_ctxt_closed \ ((srstep \ \)\<^sup>*)" (is "all_ctxt_closed _ (?R\<^sup>*)") +proof (rule trans_ctxt_sig_imp_all_ctxt_closed) + fix C :: "('f,'v) ctxt" and s t :: "('f,'v)term" + assume C: "funas_ctxt C \ \" + and s: "funas_term s \ \" + and t: "funas_term t \ \" + and steps: "(s,t) \ ?R\<^sup>*" + from steps + show "(C \ s \, C \ t \) \ ?R\<^sup>*" + proof (induct) + case (step t u) + from step(2) have tu: "(t,u) \ rstep \" and t: "funas_term t \ \" and u: "funas_term u \ \" + by (auto dest: srstepD) + have "(C \ t \, C \ u \) \ ?R" by (rule sig_stepI[OF _ _ rstep_ctxtI[OF tu]], insert C t u, auto) + with step(3) show ?case by auto + qed auto +qed (auto intro: trans_rtrancl) + +lemma sigstep_trancl_funas: + "(s, t) \ (srstep \ \)\<^sup>* \ s \ t \ funas_term s \ \" + "(s, t) \ (srstep \ \)\<^sup>* \ s \ t \ funas_term t \ \" + by (auto simp: rtrancl_eq_or_trancl dest: srstepsD) + +lemma srrstep_to_srestep: + "(s, t) \ srrstep \ \ \ (s, t) \ srstep \ \" + by (meson in_mono rrstep_rstep_mono sig_step_mono2) + +lemma srsteps_with_root_step_srstepsD: + "(s, t) \ srsteps_with_root_step \ \ \ (s, t) \ (srstep \ \)\<^sup>+" + by (auto dest: srrstep_to_srestep simp: srsteps_with_root_step_def) + +lemma srsteps_with_root_step_sresteps_eqD: + "(s, t) \ srsteps_with_root_step \ \ \ (s, t) \ (srstep \ \)\<^sup>*" + by (auto dest: srrstep_to_srestep simp: srsteps_with_root_step_def) + +lemma symcl_srstep_conversion: + "(s, t) \ srstep \ (\\<^sup>\) \ (s, t) \ (srstep \ \)\<^sup>\\<^sup>*" + by (simp add: conversion_def rstep_converse_dist srstep_symcl_dist) + +lemma symcl_srsteps_conversion: + "(s, t) \ (srstep \ (\\<^sup>\))\<^sup>* \ (s, t) \ (srstep \ \)\<^sup>\\<^sup>*" + by (simp add: conversion_def rstep_converse_dist srstep_symcl_dist) + + + +lemma NF_srstep_args: + assumes "Fun f ss \ NF (srstep \ \)" "funas_term (Fun f ss) \ \" "i < length ss" + shows "ss ! i \ NF (srstep \ \)" +proof (rule ccontr) + assume "ss ! i \ NF (srstep \ \)" + then obtain t where step: "(ss ! i, t) \ rstep \" "funas_term t \ \" + by (auto simp: NF_def sig_step_def) + from assms(3) have [simp]: "Suc (length ss - Suc 0) = length ss" by auto + from rstep_ctxtI[OF step(1), where ?C = "ctxt_at_pos (Fun f ss)[i]"] + have "(Fun f ss, Fun f (ss[i := t])) \ srstep \ \" using step(2) assms(2, 3) + by (auto simp: sig_step_def upd_conv_take_nth_drop min_def UN_subset_iff + dest: in_set_takeD in_set_dropD simp flip: id_take_nth_drop) + then show False using assms(1) + by (auto simp: NF_def) +qed + +lemma all_ctxt_closed_srstep_conversions [simp]: + "all_ctxt_closed \ ((srstep \ \)\<^sup>\\<^sup>*)" + by (simp add: all_ctxt_closed_sig_rsteps sig_step_conversion_dist) + +(* END AUX *) + +lemma NFP_stepD: + "NFP r \ (a, b) \ r\<^sup>* \ (a, c) \ r\<^sup>* \ c \ NF r \ (b, c) \ r\<^sup>*" + by (auto simp: NFP_on_def) + +lemma NE_symmetric: "NE r s \ NE s r" + unfolding NE_on_def by auto + +lemma CE_symmetric: "CE r s \ CE s r" + unfolding CE_on_def by auto + +text \Reducing the quantification over rewrite sequences for properties @{const CR} ... to +rewrite sequences containing at least one root step\ +lemma all_ctxt_closed_sig_reflE: + "all_ctxt_closed \ \ \ funas_term t \ \ \ (t, t) \ \" +proof (induct t) + case (Fun f ts) + from Fun(1)[OF nth_mem Fun(2)] Fun(3) + have "i < length ts \ funas_term (ts ! i) \ \" "i < length ts \ (ts ! i, ts ! i) \ \" for i + by (auto simp: SUP_le_iff) + then show ?case using all_ctxt_closedD[OF Fun(2)] Fun(3) + by simp +qed (simp add: all_ctxt_closed_def) + + +lemma all_ctxt_closed_relcomp [intro]: + "(\ s t. (s, t) \ \ \ s \ t \ funas_term s \ \ \ funas_term t \ \) \ + (\ s t. (s, t) \ \ \ s \ t \ funas_term s \ \ \ funas_term t \ \) \ + all_ctxt_closed \ \ \ all_ctxt_closed \ \ \ all_ctxt_closed \ (\ O \)" +proof - + assume funas:"(\ s t. (s, t) \ \ \ s \ t \ funas_term s \ \ \ funas_term t \ \)" + "(\ s t. (s, t) \ \ \ s \ t \ funas_term s \ \ \ funas_term t \ \)" + and ctxt_cl: "all_ctxt_closed \ \" "all_ctxt_closed \ \" + {fix f ss ts assume ass: "(f, length ss) \ \" "length ss = length ts" "\ i. i < length ts \ (ss ! i, ts ! i) \ (\ O \)" + "\ i . i < length ts \ funas_term (ts ! i) \ \" "\i. i < length ts \ funas_term (ss ! i) \ \" + from ass(2, 3) obtain us where us: "length us = length ts" "\ i. i < length ts \ (ss ! i, us ! i) \ \" + "\ i. i < length ts \ (us ! i, ts ! i) \ \" + using Ex_list_of_length_P[of "length ts" "\ x i. (ss ! i, x) \ \ \ (x, ts ! i) \ \"] + by auto + from funas have fu: "\ i . i < length us \ funas_term (us ! i) \ \" using us ass(4, 5) + by (auto simp: funas_rel_def) (metis in_mono) + have "(Fun f ss, Fun f us) \ \" using ass(1, 2, 5) us(1, 2) fu + by (intro all_ctxt_closedD[OF ctxt_cl(1), of f]) auto + moreover have "(Fun f us, Fun f ts) \ \" using ass(1, 2, 4) us(1, 3) fu + by (intro all_ctxt_closedD[OF ctxt_cl(2), of f]) auto + ultimately have "(Fun f ss, Fun f ts) \ \ O \" by auto} + moreover + {fix x have "(Var x, Var x) \ \" "(Var x, Var x) \ \" using ctxt_cl + by (auto simp: all_ctxt_closed_def) + then have "(Var x, Var x) \ \ O \" by auto} + ultimately show ?thesis by (auto simp: all_ctxt_closed_def) +qed + + +abbreviation "prop_to_rel P \ {(s, t)| s t. P s t}" + +abbreviation "prop_mctxt_cl \ P \ all_ctxt_closed \ (prop_to_rel P)" + +lemma prop_mctxt_cl_Var: + "prop_mctxt_cl \ P \ P (Var x) (Var x)" + by (simp add: all_ctxt_closed_def) + +lemma prop_mctxt_cl_refl_on: + "prop_mctxt_cl \ P \ funas_term t \ \ \ P t t" + using all_ctxt_closed_sig_reflE by blast + +lemma prop_mctxt_cl_reflcl_on: + "prop_mctxt_cl \ P \ funas_term s \ \ \ P s s" + using all_ctxt_closed_sig_reflE by blast + +lemma reduction_relations_to_root_step: + assumes "\ s t. (s, t) \ srsteps_with_root_step \ \ \ P s t" + and cl: "prop_mctxt_cl \ P" + and well: "funas_term s \ \" "funas_term t \ \" + and steps: "(s, t) \ (srstep \ \)\<^sup>*" + shows "P s t" using steps well +proof (induct s arbitrary: t) + case (Var x) + have "(Var x, t) \ (srstep \ \)\<^sup>+ \ (Var x, t) \ srsteps_with_root_step \ \" + using nsrsteps_with_root_step_step_on_args by blast + from assms(1)[OF this] show ?case using Var cl + by (auto simp: rtrancl_eq_or_trancl dest: all_ctxt_closed_sig_reflE) +next + case (Fun f ss) note IH = this show ?case + proof (cases "Fun f ss = t") + case True show ?thesis using IH(2, 4) unfolding True + by (intro prop_mctxt_cl_reflcl_on[OF cl]) auto + next + case False + then have step: "(Fun f ss, t) \ (srstep \ \)\<^sup>+" using IH(2) + by (auto simp: refl rtrancl_eq_or_trancl) + show ?thesis + proof (cases "(Fun f ss, t) \ srsteps_with_root_step \ \") + case False + from nsrsteps_with_root_step_step_on_args[OF step this] obtain ts + where *[simp]: "t = Fun f ts" and inv: "length ss = length ts" + "\ i < length ts. (ss ! i, ts ! i) \ (srstep \ \)\<^sup>*" + by auto + have funas: "(f, length ts) \ \" "\i \ \ funas_term (ts ! i) \ \" + using IH(3, 4) step inv(1) by (auto simp: UN_subset_iff) + then have t: "\ i < length ts. P (ss ! i) (ts ! i)" + using prop_mctxt_cl_reflcl_on[OF cl] IH(1) inv + by (auto simp: rtrancl_eq_or_trancl) + then show ?thesis unfolding * using funas inv(1) all_ctxt_closedD[OF cl] + by auto + qed (auto simp add: assms(1)) + qed +qed + + + +abbreviation "comp_rrstep_rel \ \ \ \ srsteps_with_root_step \ \ O (srstep \ \)\<^sup>* \ + (srstep \ \)\<^sup>* O srsteps_with_root_step \ \" + +abbreviation "comp_rrstep_rel' \ \ \ \ srsteps_with_root_step \ \ O (srstep \ \)\<^sup>+ \ + (srstep \ \)\<^sup>+ O srsteps_with_root_step \ \" + +lemma reduction_join_relations_to_root_step: + assumes "\ s t. (s, t) \ comp_rrstep_rel \ \ \ \ P s t" + and cl: "prop_mctxt_cl \ P" + and well: "funas_term s \ \" "funas_term t \ \" + and steps: "(s, t) \ (srstep \ \)\<^sup>* O (srstep \ \)\<^sup>*" + shows "P s t" using steps well +proof (induct s arbitrary: t) + case (Var x) + have f: "(Var x, t) \ (srstep \ \)\<^sup>+ \ (Var x, t) \ comp_rrstep_rel \ \ \" + using nsrsteps_with_root_step_step_on_args[of "Var x" _ \ \] unfolding srsteps_with_root_step_def + by (metis (no_types, lifting) Term.term.simps(4) UnI1 relcomp.relcompI rtrancl_eq_or_trancl) + have s: "(Var x, t) \ (srstep \ \)\<^sup>+ \ (Var x, t) \ comp_rrstep_rel \ \ \" + using nsrsteps_with_root_step_step_on_args[of "Var x" _ \ \] unfolding srsteps_with_root_step_def + by (metis (no_types, lifting) Term.term.simps(4) UnI2 relcomp.simps rtrancl.simps) + have t: "(Var x, u) \ (srstep \ \)\<^sup>+ \ (u, t) \ (srstep \ \)\<^sup>+ \ (Var x, t) \ comp_rrstep_rel \ \ \" for u + using nsrsteps_with_root_step_step_on_args[of "Var x" u \ \] unfolding srsteps_with_root_step_def + by auto (meson relcomp.simps trancl_into_rtrancl) + show ?case using Var f[THEN assms(1)] s[THEN assms(1)] t[THEN assms(1)] cl + by (auto simp: rtrancl_eq_or_trancl prop_mctxt_cl_Var) +next + case (Fun f ss) note IH = this show ?case + proof (cases "Fun f ss = t") + case True show ?thesis using IH(2, 3, 4) cl + by (auto simp: True prop_mctxt_cl_refl_on) + next + case False + obtain u where u: "(Fun f ss, u) \ (srstep \ \)\<^sup>*" "(u, t) \ (srstep \ \)\<^sup>*" using IH(2) by auto + show ?thesis + proof (cases "(Fun f ss, u) \ srsteps_with_root_step \ \") + case True + then have "(Fun f ss, t) \ comp_rrstep_rel \ \ \" using u + by (auto simp: srsteps_with_root_step_def) + from assms(1)[OF this] show ?thesis by simp + next + case False note nt_fst = this show ?thesis + proof (cases "(u, t) \ srsteps_with_root_step \ \") + case True + then have "(Fun f ss, t) \ comp_rrstep_rel \ \ \" using u unfolding srsteps_with_root_step_def + by blast + from assms(1)[OF this] show ?thesis by simp + next + case False note no_root = False nt_fst + show ?thesis + proof (cases "Fun f ss = u \ u = t") + case True + from assms(1) have f: "\ s t. (s, t) \ srsteps_with_root_step \ \ \ P s t" + and s: "\ s t. (s, t) \ srsteps_with_root_step \ \ \ P s t" unfolding srsteps_with_root_step_def + by blast+ + have "u = t \ ?thesis" using u cl IH(3, 4) + by (intro reduction_relations_to_root_step[OF f]) auto + moreover have "Fun f ss = u \ ?thesis" using u cl IH(3, 4) + by (intro reduction_relations_to_root_step[OF s]) auto + ultimately show ?thesis using True by auto + next + case False + then have steps: "(Fun f ss, u) \ (srstep \ \)\<^sup>+" "(u, t) \ (srstep \ \)\<^sup>+" using u + by (auto simp: rtrancl_eq_or_trancl) + obtain ts us + where [simp]: "u = Fun f us" and inv_u: "length ss = length us" "\ i < length ts. (ss ! i, us ! i) \ (srstep \ \)\<^sup>*" + and [simp]: "t = Fun f ts" and inv_t: "length us = length ts" "\ i < length ts. (us ! i, ts ! i) \ (srstep \ \)\<^sup>*" + using nsrsteps_with_root_step_step_on_args[OF steps(1) no_root(2)] + using nsrsteps_with_root_step_step_on_args[OF steps(2) no_root(1)] + by auto + from inv_u inv_t cl IH(3, 4) have t: "\ i < length ts. P (ss ! i) (ts ! i)" + by (auto simp: UN_subset_iff intro!: IH(1)[OF nth_mem, of i "ts ! i" for i]) + moreover have "(f, length ts) \ \" using IH(4) by auto + ultimately show ?thesis using IH(3, 4) inv_u inv_t all_ctxt_closedD[OF cl] + by (auto simp: UN_subset_iff) + qed + qed + qed + qed +qed + +\ \Reducing search space for @{const commute} to conversions involving root steps\ + +definition "commute_redp \ \ \ s t \ (s, t) \ ((srstep \ \)\<^sup>* O ((srstep \ \)\)\<^sup>*)" + +declare subsetI[rule del] +lemma commute_redp_mctxt_cl: + "prop_mctxt_cl \ (commute_redp \ \ \)" + by (auto simp: commute_redp_def rew_converse_inwards + dest: sigstep_trancl_funas intro!: all_ctxt_closed_relcomp) +declare subsetI[intro!] + +lemma commute_rrstep_intro: + assumes "\ s t. (s, t) \ comp_rrstep_rel' \ (\\) \ \ commute_redp \ \ \ s t" + shows "commute (srstep \ \) (srstep \ \)" +proof - + have [simp]: "x \ srsteps_with_root_step \ \ \ x \ (srstep \ \)\<^sup>* O \\<^sup>*" for x \ \ + by (cases x) (auto dest!: srsteps_with_root_step_sresteps_eqD) + have [simp]: "x \ srsteps_with_root_step \ \ \ x \ \\<^sup>* O (srstep \ \)\<^sup>*" for x \ \ + by (cases x) (auto dest!: srsteps_with_root_step_sresteps_eqD) + have red: "\ s t. (s, t) \ comp_rrstep_rel \ (\\) \ \ commute_redp \ \ \ s t" using assms + unfolding commute_redp_def srstep_converse_dist + by (auto simp: rtrancl_eq_or_trancl) blast+ + have comI: "(\ s t. (s, t) \ ((srstep \ (\\))\<^sup>*) O (srstep \ \)\<^sup>* \ commute_redp \ \ \ s t) \ + commute (srstep \ \) (srstep \ \)" + by (auto simp: commute_redp_def commute_def subsetD rew_converse_inwards) + show ?thesis + using reduction_join_relations_to_root_step[OF red commute_redp_mctxt_cl, of "\\" \] + by (intro comI, auto) (metis (no_types, lifting) commute_redp_def relcompI rew_converse_inwards sigstep_trancl_funas srstep_converse_dist) +qed + +lemma commute_to_rrstep: + assumes "commute (srstep \ \) (srstep \ \)" + shows "\ s t. (s, t) \ comp_rrstep_rel \ (\\) \ \ commute_redp \ \ \ s t" using assms + unfolding commute_def commute_redp_def srstep_converse_dist + by (auto simp: srstep_converse_dist dest: srsteps_with_root_step_sresteps_eqD) + +\ \Reducing search space for @{const CR} to conversions involving root steps\ + +lemma CR_Aux: + assumes "\ s t. (s, t) \ (srstep \ (\\))\<^sup>* O srsteps_with_root_step \ \ \ commute_redp \ \ \ s t" + shows "\ s t. (s, t) \ comp_rrstep_rel \ (\\) \ \ commute_redp \ \ \ s t" +proof - + have sym: "commute_redp \ \ \ s t \ commute_redp \ \ \ t s" for s t + by (auto simp: commute_redp_def) (metis converseI relcomp.relcompI rtrancl_converse rtrancl_converseD) + {fix s t assume "(s, t) \ (srstep \ \)\<^sup>* O srsteps_with_root_step \ (\\)" + then have "commute_redp \ \ \ s t" unfolding commute_redp_def + by (auto simp: srsteps_with_root_step_def rew_converse_inwards dest!: srrstep_to_srestep)} + note * = this + {fix s t assume ass: "(s, t) \ srsteps_with_root_step \ (\\) O (srstep \ \)\<^sup>*" + have [dest!]: "(u, t) \ (srstep \ \)\<^sup>* \ (t, u) \ (sig_step \ ((rstep \)\))\<^sup>*" for u + by (metis rew_converse_outwards rtrancl_converseI srstep_converse_dist) + from ass have "(t, s) \ (srstep \ (\\))\<^sup>* O srsteps_with_root_step \ \" + unfolding srsteps_with_root_step_def rstep_converse_dist + by (metis (mono_tags, lifting) O_assoc converse.simps converse_converse converse_inward(1) converse_relcomp rew_converse_outwards(1, 2) sig_step_converse_rstep) + from assms[OF this] have "commute_redp \ \ \ s t" using sym by blast} + then show "\ s t. (s, t) \ comp_rrstep_rel \ (\\) \ \ commute_redp \ \ \ s t" unfolding srsteps_with_root_step_def + by (metis UnE assms srsteps_with_root_step_def) +qed + +lemma CR_rrstep_intro: + assumes "\ s t. (s, t) \ (srstep \ (\\))\<^sup>+ O srsteps_with_root_step \ \ \ commute_redp \ \ \ s t" + shows "CR (srstep \ \)" +proof - + {fix s u assume "(s, u) \ (srstep \ (\\))\<^sup>* O srsteps_with_root_step \ \" + then obtain t where a: "(s, t) \ (srstep \ (\\))\<^sup>*" "(t, u) \ srsteps_with_root_step \ \" by blast + have "commute_redp \ \ \ s u" + proof (cases "s = t") + case [simp]: True + from srsteps_with_root_step_srstepsD[OF a(2)] show ?thesis + by (auto simp: commute_redp_def) + next + case False + then have "(s, t) \ (srstep \ (\\))\<^sup>+" using a(1) unfolding rtrancl_eq_or_trancl + by simp + then show ?thesis using assms a(2) by blast + qed} + from commute_rrstep_intro[OF CR_Aux[OF this]] + show ?thesis unfolding CR_iff_self_commute + by (metis Un_iff reflcl_trancl relcomp_distrib relcomp_distrib2) +qed + +lemma CR_to_rrstep: + assumes "CR (srstep \ \)" + shows "\ s t. (s, t) \ comp_rrstep_rel \ (\\) \ \ commute_redp \ \ \ s t" using assms + using commute_to_rrstep[OF assms[unfolded CR_iff_self_commute]] + by simp + +\ \Reducing search space for @{const NFP} to conversions involving root steps\ + +definition NFP_redp where + "NFP_redp \ \ s t \ t \ NF (srstep \ \) \ (s, t) \ (srstep \ \)\<^sup>*" + +lemma prop_mctxt_cl_NFP_redp: + "prop_mctxt_cl \ (NFP_redp \ \)" +proof - + {fix f ts ss assume sig: "(f, length ss) \ \" "length ts = length ss" + and steps: "\ i < length ss. ss ! i \ NF (srstep \ \) \ (ts ! i, ss ! i) \ (srstep \ \)\<^sup>*" + and funas: "\ i < length ss. funas_term (ts ! i) \ \ \ funas_term (ss ! i) \ \" + and NF: "Fun f ss \ NF (srstep \ \)" + from steps have steps: "i < length ss \ (ts ! i, ss ! i) \ (srstep \ \)\<^sup>*" for i + using sig funas NF_srstep_args[OF NF] + by (auto simp: UN_subset_iff) (metis in_set_idx) + then have "(Fun f ts, Fun f ss) \ (srstep \ \)\<^sup>*" using sig + by (metis all_ctxt_closed_def all_ctxt_closed_sig_rsteps funas le_sup_iff)} + then show ?thesis + by (auto simp: NFP_redp_def all_ctxt_closed_def) +qed + +lemma NFP_rrstep_intro: + assumes "\ s t. (s, t) \ comp_rrstep_rel' \ (\\) \\ NFP_redp \ \ s t" + shows "NFP (srstep \ \)" +proof - + from assms have red: "\ t u. (t, u) \ comp_rrstep_rel \ (\\) \ \ NFP_redp \ \ t u" + apply (auto simp: NFP_redp_def rtrancl_eq_or_trancl) + apply (metis NF_no_trancl_step converseD srstep_converse_dist srsteps_with_root_step_srstepsD trancl_converse) + apply blast + apply (meson NF_no_trancl_step srsteps_with_root_step_srstepsD) + by blast + have "\ s t. (s, t) \ (sig_step \ ((rstep \)\))\<^sup>* O (srstep \ \)\<^sup>* \ NFP_redp \ \ s t" + using reduction_join_relations_to_root_step[OF red prop_mctxt_cl_NFP_redp, of "\\" \] + by (auto simp: NFP_redp_def) (metis (no_types, lifting) relcomp.relcompI rstep_converse_dist rtranclD srstepsD) + then show ?thesis unfolding NFP_on_def NFP_redp_def + by (auto simp: normalizability_def) (metis meetI meet_def rstep_converse_dist srstep_converse_dist) +qed + +lemma NFP_lift_to_conversion: + assumes "NFP r" "(s, t) \ (r\<^sup>\)\<^sup>*" and "t \ NF r" + shows "(s, t) \ r\<^sup>*" using assms(2, 3) +proof (induct rule: converse_rtrancl_induct) + case (step s u) + then have "(u, t) \ r\<^sup>!" by auto + then show ?case using assms(1) step(1) unfolding NFP_on_def + by auto +qed simp + +lemma NFP_to_rrstep: + assumes "NFP (srstep \ \)" + shows "\ s t. (s, t) \ srsteps_with_root_step \ (\\<^sup>\) \ NFP_redp \ \ s t" using assms + using NFP_lift_to_conversion[OF assms] unfolding NFP_redp_def srsteps_with_root_step_def + by auto (metis (no_types, lifting) r_into_rtrancl rstep_converse_dist rtrancl_trans srrstep_to_srestep srstep_symcl_dist) + + +\ \Reducing search space for @{const UNC} to conversions involving root steps\ + +definition "UN_redp \ \ s t \ s \ NF (srstep \ \) \ t \ NF (srstep \ \) \ s = t" + +lemma prop_mctxt_cl_UN_redp: + "prop_mctxt_cl \ (UN_redp \ \)" +proof - + {fix f ts ss assume sig: "(f, length ss) \ \" "length ts = length ss" + and steps: "\ i < length ss. ts ! i \ NF (srstep \ \) \ ss ! i \ NF (srstep \ \) \ ts ! i = ss ! i" + and funas: "\ i < length ss. funas_term (ts ! i) \ \ \ funas_term (ss ! i) \ \" + and NF: "Fun f ts \ NF (srstep \ \)" "Fun f ss \ NF (srstep \ \)" + from steps have steps: "i < length ss \ ts ! i = ss ! i" for i + using sig funas NF_srstep_args[OF NF(1)] NF_srstep_args[OF NF(2)] + by (auto simp: UN_subset_iff) (metis in_set_idx) + then have "Fun f ts = Fun f ss" using sig(2) + by (simp add: nth_equalityI)} + then show ?thesis + by (auto simp: UN_redp_def all_ctxt_closed_def) +qed + +lemma UNC_rrstep_intro: + assumes"\ s t. (s, t) \ srsteps_with_root_step \ (\\<^sup>\) \ UN_redp \ \ s t" + shows "UNC (srstep \ \)" +proof - + have "\ s t. (s, t) \ (srstep \ (\\<^sup>\))\<^sup>* \ UN_redp \ \ s t" + using reduction_relations_to_root_step[OF assms(1) prop_mctxt_cl_UN_redp, of "\\<^sup>\"] + by (auto simp: UN_redp_def) (meson rtranclD srstepsD) + then show ?thesis unfolding UNC_def UN_redp_def + by (auto simp: sig_step_conversion_dist) +qed + +lemma UNC_to_rrstep: + assumes "UNC (srstep \ \)" + shows "\ s t. (s, t) \ srsteps_with_root_step \ (\\<^sup>\) \ UN_redp \ \ s t" + using assms unfolding UNC_def UN_redp_def srsteps_with_root_step_def + by (auto dest!: srrstep_to_srestep symcl_srstep_conversion symcl_srsteps_conversion) + (metis (no_types, opaque_lifting) conversion_def rtrancl_trans) + + +\ \Reducing search space for @{const UNF} to conversions involving root steps\ + +lemma UNF_rrstep_intro: + assumes "\ t u. (t, u) \ comp_rrstep_rel' \ (\\) \ \ UN_redp \ \ t u" + shows "UNF (srstep \ \)" +proof - + from assms have red: "\ t u. (t, u) \ comp_rrstep_rel \ (\\) \ \ UN_redp \ \ t u" + apply (auto simp: UN_redp_def rtrancl_eq_or_trancl) + apply (metis NF_no_trancl_step converseD srstep_converse_dist srsteps_with_root_step_srstepsD trancl_converse) + apply blast + apply (meson NF_no_trancl_step srsteps_with_root_step_srstepsD) + by blast + have "\ s t. (s, t) \ (sig_step \ ((rstep \)\))\<^sup>* O (srstep \ \)\<^sup>* \ UN_redp \ \ s t" + using reduction_join_relations_to_root_step[OF red prop_mctxt_cl_UN_redp, of "\\" \] + by (auto simp: UN_redp_def) (metis (no_types, lifting) relcomp.relcompI rstep_converse_dist rtranclD srstepsD) + then show ?thesis unfolding UNF_on_def UN_redp_def + by (auto simp: normalizability_def) (metis meetI meet_def rstep_converse_dist srstep_converse_dist) +qed + +lemma UNF_to_rrstep: + assumes "UNF (srstep \ \)" + shows "\ s t. (s, t) \ comp_rrstep_rel \ (\\) \ \ UN_redp \ \ s t" + using assms unfolding UNF_on_def UN_redp_def normalizability_def srsteps_with_root_step_def + by (auto simp flip: srstep_converse_dist dest!: srrstep_to_srestep) + (metis (no_types, lifting) rstep_converse_dist rtrancl.rtrancl_into_rtrancl rtrancl_converseD rtrancl_idemp srstep_converse_dist)+ + +\ \Reducing search space for @{const CE} to conversions involving root steps\ + +lemma CE_rrstep_intro: + assumes "\ s t. (s, t) \ srsteps_with_root_step \ (\\<^sup>\) \ (s, t) \ (srstep \ \)\<^sup>\\<^sup>*" + and "\ s t. (s, t) \ srsteps_with_root_step \ (\\<^sup>\) \ (s, t) \ (srstep \ \)\<^sup>\\<^sup>*" + shows "CE (srstep \ \) (srstep \ \)" + using reduction_relations_to_root_step[OF assms(1), where ?s1 = "\ s t. s" and ?t1 = "\ s t. t", of \ "\\<^sup>\"] + using reduction_relations_to_root_step[OF assms(2), where ?s1 = "\ s t. s" and ?t1 = "\ s t. t", of \ "\\<^sup>\"] + by (auto simp: CE_on_def) + (metis converseI conversion_converse rtrancl_eq_or_trancl sig_step_conversion_dist sigstep_trancl_funas(1, 2))+ + +lemma CE_to_rrstep: + assumes "CE (srstep \ \) (srstep \ \)" + shows "\ s t. (s, t) \ srsteps_with_root_step \ (\\<^sup>\) \ (s, t) \ (srstep \ \)\<^sup>\\<^sup>*" + "\ s t. (s, t) \ srsteps_with_root_step \ (\\<^sup>\) \ (s, t) \ (srstep \ \)\<^sup>\\<^sup>*" + using assms unfolding CE_on_def srsteps_with_root_step_def + by (auto simp flip: srstep_converse_dist dest!: srrstep_to_srestep symcl_srsteps_conversion symcl_srstep_conversion) + (metis converse_rtrancl_into_rtrancl conversion_rtrancl)+ + + +\ \Reducing search space for @{const NE} to conversions involving root steps\ + +definition NE_redp where + "NE_redp \ \ \ s t \ t \ NF (srstep \ \) \ t \ NF (srstep \ \) \ (s, t) \ (srstep \ \)\<^sup>*" + +lemma prop_mctxt_cl_NE_redp: + "prop_mctxt_cl \ (NE_redp \ \ \)" +proof - + {fix f ts ss assume sig: "(f, length ss) \ \" "length ts = length ss" + and steps: "\ i < length ss. ss ! i \ NF (srstep \ \) \ (ts ! i, ss ! i) \ (srstep \ \)\<^sup>*" + and funas: "\ i < length ss. funas_term (ts ! i) \ \ \ funas_term (ss ! i) \ \" + and NF: "Fun f ss \ NF (srstep \ \)" + from steps have steps: "i < length ss \ (ts ! i, ss ! i) \ (srstep \ \)\<^sup>*" for i + using sig funas NF_srstep_args[OF NF] + by (auto simp: UN_subset_iff) (metis in_set_idx) + then have "(Fun f ts, Fun f ss) \ (srstep \ \)\<^sup>*" using sig + by (metis all_ctxt_closed_def all_ctxt_closed_sig_rsteps funas le_sup_iff)} + then show ?thesis + by (auto simp: all_ctxt_closed_def NE_redp_def) +qed + +lemma NE_rrstep_intro: + assumes "\ s t. (s, t) \ srsteps_with_root_step \ \ \ NE_redp \ \ \ s t" + and "\ s t. (s, t) \ srsteps_with_root_step \ \ \ NE_redp \ \ \ s t" + and "NF (srstep \ \) = NF (srstep \ \)" + shows "NE (srstep \ \) (srstep \ \)" + using assms(3) + using reduction_relations_to_root_step[OF assms(1) prop_mctxt_cl_NE_redp, of \] + using reduction_relations_to_root_step[OF assms(2) prop_mctxt_cl_NE_redp, of \] + by (auto simp: NE_on_def NE_redp_def normalizability_def) + (metis rtrancl.rtrancl_refl sigstep_trancl_funas)+ + + +lemma NE_to_rrstep: + assumes "NE (srstep \ \) (srstep \ \)" + shows "\ s t. (s, t) \ srsteps_with_root_step \ \ \ NE_redp \ \ \ s t" + "\ s t. (s, t) \ srsteps_with_root_step \ \ \ NE_redp \ \ \ s t" + using assms unfolding NE_on_def NE_redp_def srsteps_with_root_step_def + by (auto simp: normalizability_def simp flip: srstep_converse_dist + dest!: srrstep_to_srestep) (meson converse_rtrancl_into_rtrancl rtrancl_trans)+ + +lemma NE_NF_eq: + "NE \ \ \ NF \ = NF \" + by (auto simp: NE_on_def NF_def normalizability_def) + +\ \Reducing search space for @{const SCR} and @{const WCR} involving root steps\ +(*Brute forced proofs could be done nicer with more lemmas related to positions *) + +abbreviation "SCRp \ \ t u \ \v. (t, v) \ (srstep \ \)\<^sup>= \ (u, v) \ (srstep \ \)\<^sup>*" +lemma SCR_rrstep_intro: + assumes "\ s t u. (s, t) \ sig_step \ (rrstep \) \ (s, u) \ srstep \ \ \ SCRp \ \ t u" + and "\ s t u. (s, t) \ srstep \ \ \ (s, u) \ sig_step \ (rrstep \) \ SCRp \ \ t u" + shows "SCR (srstep \ \)" +proof - + {fix s t u assume step: "(s, t) \ srstep \ \" "(s, u) \ srstep \ \" + from step(1) obtain p l r \ where st: "p \ poss s" "(l, r) \ \" "s |_ p = l \ \" "t = s[p \ r \ \]" + using rstep_to_pos_replace[of s t \] unfolding sig_step_def by blast + from step(2) obtain q l2 r2 \2 where su: "q \ poss s" "(l2, r2) \ \" "s |_ q = l2 \ \2" "u = s[q \ r2 \ \2]" + using rstep_to_pos_replace[of s u \] unfolding sig_step_def by blast + from step st su have funas: "funas_term s \ \" "funas_term t \ \" "funas_term u \ \" + by (auto dest: srstepD) + have funas2 :"funas_term (r2 \ \2) \ \" using funas_term_replace_at_lower[OF su(1)] + using funas(3) unfolding su(4) by blast + consider (a) "p \\<^sub>p q" | (b) "q \\<^sub>p p" | (c) "p \ q" + using position_par_def by blast + then have "SCRp \ \ t u" + proof cases + case a + from a have up: "p \ poss u" using st(1) su(1) unfolding st(4) su(4) + by (metis pos_replace_at_pres position_less_eq_def poss_append_poss) + let ?C = "ctxt_at_pos s p" have fc: "funas_ctxt ?C \ \" using funas(1) st(1) + by (metis ctxt_at_pos_subt_at_id funas_ctxt_apply le_sup_iff) + from funas have funas: "funas_term (s |_ p) \ \" "funas_term (t |_ p) \ \" "funas_term (u |_ p) \ \" + using a st(1) pos_replace_at_pres[OF st(1)] up unfolding st(4) su(4) + by (intro funas_term_subterm_atI, blast+)+ + have "(s |_ p, t |_ p) \ sig_step \ (rrstep \)" unfolding st(4) su(4) using st(1 - 3) su(1 - 3) funas + by (metis poss_of_termE poss_of_term_replace_term_at rrstep.intros sig_stepI st(4)) + moreover have "(s |_ p, u |_ p) \ srstep \ \" unfolding st(4) su(4) using st(1 - 3) su(1 - 3) funas + by (smt (verit, best) a ctxt_at_pos_subt_at_pos ctxt_of_pos_term_apply_replace_at_ident position_less_eq_def + poss_append_poss replace_subterm_at_itself replace_term_at_subt_at_id rstepI sig_stepI su(4)) + ultimately obtain v where "(t |_ p, v) \ (srstep \ \)\<^sup>=" "(u |_ p, v) \ (srstep \ \)\<^sup>*" + using assms(1) by blast + from this(1) srsteps_eq_ctxt_closed[OF fc this(2)] + show ?thesis using a st(1) su(1) srsteps_eq_ctxt_closed[OF fc] unfolding st(4) su(4) + apply (intro exI[of _ "?C\v\"]) + apply (auto simp: ctxt_of_pos_term_apply_replace_at_ident less_eq_subt_at_replace) + apply (metis ctxt_of_pos_term_apply_replace_at_ident fc srstep_ctxt_closed) + done + next + case b + then have up: "q \ poss t" using st(1) su(1) unfolding st(4) su(4) + by (metis pos_replace_at_pres position_less_eq_def poss_append_poss) + let ?C = "ctxt_at_pos s q" have fc: "funas_ctxt ?C \ \" using funas(1) su(1) + by (metis Un_subset_iff ctxt_at_pos_subt_at_id funas_ctxt_apply) + from funas have funas: "funas_term (s |_ q) \ \" "funas_term (t |_ q) \ \" "funas_term (u |_ q) \ \" + using su(1) pos_replace_at_pres[OF su(1)] up unfolding st(4) su(4) + by (intro funas_term_subterm_atI, blast+)+ + have "(s |_ q, t |_ q) \ srstep \ \" unfolding st(4) su(4) using st(1 - 3) su(1 - 3) funas + by (smt (verit, del_insts) b ctxt_at_pos_subt_at_pos ctxt_of_pos_term_apply_replace_at_ident + position_less_eq_def poss_append_poss replace_subterm_at_itself replace_term_at_subt_at_id rstepI sig_stepI st(4)) + moreover have "(s |_ q, u |_ q) \ sig_step \ (rrstep \)" unfolding st(4) su(4) using st(1 - 3) su(1 - 3) funas + by (metis poss_of_termE poss_of_term_replace_term_at rrstep.intros sig_stepI su(4)) + ultimately obtain v where "(t |_ q, v) \ (srstep \ \)\<^sup>=" "(u |_ q, v) \ (srstep \ \)\<^sup>*" + using assms(2) by blast + from this(1) srsteps_eq_ctxt_closed[OF fc this(2)] + show ?thesis using b st(1) su(1) srsteps_eq_ctxt_closed[OF fc] unfolding st(4) su(4) + apply (intro exI[of _ "?C\v\"]) + apply (auto simp: ctxt_of_pos_term_apply_replace_at_ident less_eq_subt_at_replace) + apply (smt (verit, best) ctxt_of_pos_term_apply_replace_at_ident fc less_eq_subt_at_replace replace_term_at_above replace_term_at_subt_at_id srstep_ctxt_closed) + done + next + case c + define v where "v = t[q \ r2 \ \2]" + have funasv: "funas_term v \ \" using funas su(1) unfolding v_def su(4) + using funas_term_replace_at_upper funas2 by blast + from c have *: "v = u[p \ r \ \]" unfolding v_def st(4) su(4) using st(1) su(1) + using parallel_replace_term_commute by blast + from c have "(t, v) \ rstep \" unfolding st(4) v_def + using su(1 - 3) par_pos_replace_pres[OF su(1)] + by (metis par_pos_replace_term_at pos_replace_to_rstep position_par_def) + moreover from c have "(u, v) \ rstep \" unfolding su(4) * + using st(1 - 3) par_pos_replace_pres[OF st(1)] + by (intro pos_replace_to_rstep[of _ _ l]) (auto simp: par_pos_replace_term_at) + ultimately show ?thesis using funas(2-) funasv + by auto + qed} + then show ?thesis unfolding SCR_on_def + by blast +qed + +lemma SCE_to_rrstep: + assumes "SCR (srstep \ \)" + shows "\ s t u. (s, t) \ sig_step \ (rrstep \) \ (s, u) \ srstep \ \ \ SCRp \ \ t u" + "\ s t u. (s, t) \ srstep \ \ \ (s, u) \ sig_step \ (rrstep \) \ SCRp \ \ t u" + using assms unfolding SCR_on_def srsteps_with_root_step_def + by (auto simp flip: srstep_converse_dist dest!: srrstep_to_srestep symcl_srsteps_conversion symcl_srstep_conversion) + +lemma WCR_rrstep_intro: + assumes "\ s t u. (s, t) \ sig_step \ (rrstep \) \ (s, u) \ srstep \ \ \ (t, u) \ (srstep \ \)\<^sup>\" + shows "WCR (srstep \ \)" +proof - + {fix s t u assume step: "(s, t) \ srstep \ \" "(s, u) \ srstep \ \" + from step(1) obtain p l r \ where st: "p \ poss s" "(l, r) \ \" "s |_ p = l \ \" "t = s[p \ r \ \]" + using rstep_to_pos_replace[of s t \] unfolding sig_step_def by blast + from step(2) obtain q l2 r2 \2 where su: "q \ poss s" "(l2, r2) \ \" "s |_ q = l2 \ \2" "u = s[q \ r2 \ \2]" + using rstep_to_pos_replace[of s u \] unfolding sig_step_def by blast + from step st su have funas: "funas_term s \ \" "funas_term t \ \" "funas_term u \ \" + by (auto dest: srstepD) + have funas2 :"funas_term (r2 \ \2) \ \" using funas_term_replace_at_lower[OF su(1)] + using funas(3) unfolding su(4) by blast + consider (a) "p \\<^sub>p q" | (b) "q \\<^sub>p p" | (c) "p \ q" + using position_par_def by blast + then have "(t, u) \ (srstep \ \)\<^sup>\" + proof cases + case a + then have up: "p \ poss u" using st(1) su(1) unfolding st(4) su(4) + by (metis pos_replace_at_pres position_less_eq_def poss_append_poss) + let ?C = "ctxt_at_pos s p" have fc: "funas_ctxt ?C \ \" using funas(1) st(1) + by (metis Un_subset_iff ctxt_at_pos_subt_at_id funas_ctxt_apply) + from funas have funas: "funas_term (s |_ p) \ \" "funas_term (t |_ p) \ \" "funas_term (u |_ p) \ \" + using a st(1) pos_replace_at_pres[OF st(1)] up unfolding st(4) su(4) + by (intro funas_term_subterm_atI, blast+)+ + have "(s |_ p, t |_ p) \ sig_step \ (rrstep \)" unfolding st(4) su(4) using st(1 - 3) su(1 - 3) funas + by (metis poss_of_termE poss_of_term_replace_term_at rrstep.intros sig_stepI st(4)) + moreover have "(s |_ p, u |_ p) \ srstep \ \" unfolding st(4) su(4) using st(1 - 3) su(1 - 3) funas + by (smt (verit, ccfv_threshold) a greater_eq_subt_at_replace less_eq_subt_at_replace pos_diff_append_itself + pos_replace_to_rstep position_less_eq_def poss_append_poss replace_term_at_subt_at_id sig_stepI su(4)) + ultimately have "(t |_ p, u |_ p) \ (srstep \ \)\<^sup>\" + using assms(1) by blast + from sig_steps_join_ctxt_closed[OF fc this(1)] + show ?thesis using a st(1) su(1) srstep_ctxt_closed[OF fc] unfolding st(4) su(4) + by (auto simp: ctxt_of_pos_term_apply_replace_at_ident less_eq_subt_at_replace) + next + case b + then have up: "q \ poss t" using st(1) su(1) unfolding st(4) su(4) + by (metis pos_les_eq_append_diff pos_replace_at_pres poss_append_poss) + let ?C = "ctxt_at_pos s q" have fc: "funas_ctxt ?C \ \" using funas(1) su(1) + by (metis Un_subset_iff ctxt_at_pos_subt_at_id funas_ctxt_apply) + from funas have funas: "funas_term (s |_ q) \ \" "funas_term (t |_ q) \ \" "funas_term (u |_ q) \ \" + using su(1) pos_replace_at_pres[OF su(1)] up unfolding st(4) su(4) + by (intro funas_term_subterm_atI, blast+)+ + have "(s |_ q, t |_ q) \ srstep \ \" unfolding st(4) su(4) using st(1 - 3) su(1 - 3) funas + by (smt (verit, ccfv_SIG) b greater_eq_subt_at_replace less_eq_subt_at_replace pos_diff_append_itself + pos_replace_to_rstep position_less_eq_def poss_append_poss replace_term_at_subt_at_id sig_stepI st(4)) + moreover have "(s |_ q, u |_ q) \ sig_step \ (rrstep \)" unfolding st(4) su(4) using st(1 - 3) su(1 - 3) funas + by (metis poss_of_termE poss_of_term_replace_term_at rrstep.intros sig_stepI su(4)) + ultimately have "(t |_ q, u |_ q) \ (srstep \ \)\<^sup>\" + using assms(1) by blast + from sig_steps_join_ctxt_closed[OF fc this(1)] + show ?thesis using b st(1) su(1) srstep_ctxt_closed[OF fc] unfolding st(4) su(4) + by (auto simp: ctxt_of_pos_term_apply_replace_at_ident less_eq_subt_at_replace) + next + case c + define v where "v = t[q \ r2 \ \2]" + have funasv: "funas_term v \ \" using funas su(1) unfolding v_def su(4) + using funas_term_replace_at_upper funas2 by blast + from c have *: "v = u[p \ r \ \]" unfolding v_def st(4) su(4) using st(1) su(1) + using parallel_replace_term_commute by blast + from c have "(t, v) \ rstep \" unfolding st(4) v_def + using su(1 - 3) par_pos_replace_pres[OF su(1)] + by (metis par_pos_replace_term_at pos_replace_to_rstep position_par_def) + moreover from c have "(u, v) \ rstep \" unfolding su(4) * + using st(1 - 3) par_pos_replace_pres[OF st(1)] + by (metis par_pos_replace_term_at pos_replace_to_rstep) + ultimately show ?thesis using funas(2-) funasv + by auto + qed} + then show ?thesis unfolding WCR_on_def + by blast +qed + +end \ No newline at end of file diff --git a/thys/Rewrite_Properties_Reduction/Util/Terms_Positions.thy b/thys/Rewrite_Properties_Reduction/Util/Terms_Positions.thy new file mode 100644 --- /dev/null +++ b/thys/Rewrite_Properties_Reduction/Util/Terms_Positions.thy @@ -0,0 +1,485 @@ +section \Preliminaries\ +theory Terms_Positions + imports Regular_Tree_Relations.Ground_Terms +begin + +subsection \Additional operations on terms and positions\ + +subsubsection \Linearity\ +fun linear_term :: "('f, 'v) term \ bool" where + "linear_term (Var _) = True" | + "linear_term (Fun _ ts) = (is_partition (map vars_term ts) \ (\t\set ts. linear_term t))" +abbreviation "linear_sys \ \ \ (l, r) \ \. linear_term l \ linear_term r" + +subsubsection \Positions induced by contexts, by variables and by given subterms\ + +definition "possc C = {p | p t. p \ poss C\t\}" +definition "varposs s = {p | p. p \ poss s \ is_Var (s |_ p)}" +definition "poss_of_term u t = {p. p \ poss t \ t |_ p = u}" + + +subsubsection \Replacing functions symbols that aren't specified in the signature by variables\ + +definition "funas_rel \ = (\ (l, r) \ \. funas_term l \ funas_term r)" + +fun term_to_sig where + "term_to_sig \ v (Var x) = Var x" +| "term_to_sig \ v (Fun f ts) = + (if (f, length ts) \ \ then Fun f (map (term_to_sig \ v) ts) else Var v)" + +fun ctxt_well_def_hole_path where + "ctxt_well_def_hole_path \ Hole \ True" +| "ctxt_well_def_hole_path \ (More f ss C ts) \ (f, Suc (length ss + length ts)) \ \ \ ctxt_well_def_hole_path \ C" + +fun inv_const_ctxt where + "inv_const_ctxt \ v Hole = Hole" +| "inv_const_ctxt \ v ((More f ss C ts)) + = (More f (map (term_to_sig \ v) ss) (inv_const_ctxt \ v C) (map (term_to_sig \ v) ts))" + +fun inv_const_ctxt' where + "inv_const_ctxt' \ v Hole = Var v" +| "inv_const_ctxt' \ v ((More f ss C ts)) + = (if (f, Suc (length ss + length ts)) \ \ then Fun f (map (term_to_sig \ v) ss @ inv_const_ctxt' \ v C # map (term_to_sig \ v) ts) else Var v)" + + +subsubsection \Replace term at a given position in contexts\ + +fun replace_term_context_at :: "('f, 'v) ctxt \ pos \ ('f, 'v) term \ ('f, 'v) ctxt" + ("_[_ \ _]\<^sub>C" [1000, 0] 1000) where + "replace_term_context_at \ p u = \" +| "replace_term_context_at (More f ss C ts) (i # ps) u = + (if i < length ss then More f (ss[i := (ss ! i)[ps \ u]]) C ts + else if i = length ss then More f ss (replace_term_context_at C ps u) ts + else More f ss C (ts[(i - Suc (length ss)) := (ts ! (i - Suc (length ss)))[ps \ u]]))" + +abbreviation "constT c \ Fun c []" + +subsubsection \Multihole context closure of a term relation as inductive set\ + +definition all_ctxt_closed where + "all_ctxt_closed F r \ (\f ts ss. (f, length ss) \ F \ length ts = length ss \ + (\i. i < length ts \ (ts ! i, ss ! i) \ r) \ + (\ i. i < length ts \ funas_term (ts ! i) \ funas_term (ss ! i) \ F) \ (Fun f ts, Fun f ss) \ r) \ + (\ x. (Var x, Var x) \ r)" + + + +subsection \Destruction and introduction of @{const all_ctxt_closed}\ + +lemma all_ctxt_closedD: "all_ctxt_closed F r \ (f,length ss) \ F \ length ts = length ss + \ \\ i. i < length ts \ (ts ! i, ss ! i) \ r \ + \ \\ i. i < length ts \ funas_term (ts ! i) \ F \ + \ \\ i. i < length ts \ funas_term (ss ! i) \ F \ + \ (Fun f ts, Fun f ss) \ r" + unfolding all_ctxt_closed_def by auto + +lemma trans_ctxt_sig_imp_all_ctxt_closed: assumes tran: "trans r" + and refl: "\ t. funas_term t \ F \ (t,t) \ r" + and ctxt: "\ C s t. funas_ctxt C \ F \ funas_term s \ F \ funas_term t \ F \ (s,t) \ r \ (C \ s \, C \ t \) \ r" + shows "all_ctxt_closed F r" unfolding all_ctxt_closed_def +proof (rule, intro allI impI) + fix f ts ss + assume f: "(f,length ss) \ F" and + l: "length ts = length ss" and + steps: "\ i < length ts. (ts ! i, ss ! i) \ r" and + sig: "\ i < length ts. funas_term (ts ! i) \ funas_term (ss ! i) \ F" + from sig have sig_ts: "\ t. t \ set ts \ funas_term t \ F" unfolding set_conv_nth by auto + let ?p = "\ ss. (Fun f ts, Fun f ss) \ r \ funas_term (Fun f ss) \ F" + let ?r = "\ xsi ysi. (xsi, ysi) \ r \ funas_term ysi \ F" + have init: "?p ts" by (rule conjI[OF refl], insert f sig_ts l, auto) + have "?p ss" + proof (rule parallel_list_update[where p = ?p and r = ?r, OF _ HOL.refl init l[symmetric]]) + fix xs i y + assume len: "length xs = length ts" + and i: "i < length ts" + and r: "?r (xs ! i) y" + and p: "?p xs" + let ?C = "More f (take i xs) Hole (drop (Suc i) xs)" + have id1: "Fun f xs = ?C \ xs ! i\" using id_take_nth_drop[OF i[folded len]] by simp + have id2: "Fun f (xs[i := y]) = ?C \ y \" using upd_conv_take_nth_drop[OF i[folded len]] by simp + from p[unfolded id1] have C: "funas_ctxt ?C \ F" and xi: "funas_term (xs ! i) \ F" by auto + from r have "funas_term y \ F" "(xs ! i, y) \ r" by auto + with ctxt[OF C xi this] C have r: "(Fun f xs, Fun f (xs[i := y])) \ r" + and f: "funas_term (Fun f (xs[i := y])) \ F" unfolding id1 id2 by auto + from p r tran have "(Fun f ts, Fun f (xs[i := y])) \ r" unfolding trans_def by auto + with f + show "?p (xs[i := y])" by auto + qed (insert sig steps, auto) + then show "(Fun f ts, Fun f ss) \ r" .. +qed (insert refl, auto) + + + +subsection \Lemmas for @{const poss} and ordering of positions\ + +lemma subst_poss_mono: "poss s \ poss (s \ \)" + by (induct s) force+ + +lemma par_pos_prefix [simp]: + "(i # p) \ (i # q) \ p \ q" + by (simp add: par_Cons_iff) + +lemma pos_diff_itself [simp]: "p -\<^sub>p p = []" + by (simp add: pos_diff_def) + +lemma pos_les_eq_append_diff [simp]: + "p \\<^sub>p q \ p @ (q -\<^sub>p p) = q" + by (metis option.sel pos_diff_def position_less_eq_def remove_prefix_append) + +lemma pos_diff_append_itself [simp]: "(p @ q) -\<^sub>p p = q" + by (simp add: pos_diff_def remove_prefix_append) + +lemma poss_pos_diffI: + "p \\<^sub>p q \ q \ poss s \ q -\<^sub>p p \ poss (s |_ p)" + using poss_append_poss by fastforce + +lemma less_eq_poss_append_itself [simp]: "p \\<^sub>p (p @ q)" + using position_less_eq_def by blast + +lemma poss_ctxt_apply [simp]: + "hole_pos C @ p \ poss C\s\ \ p \ poss s" + by (induct C) auto + +lemma pos_replace_at_pres: + "p \ poss s \ p \ poss s[p \ t]" +proof (induct p arbitrary: s) + case (Cons i p) + show ?case using Cons(1)[of "args s ! i"] Cons(2-) + by (cases s) auto +qed auto + +lemma par_pos_replace_pres: + "p \ poss s \ p \ q \ p \ poss s[q \ t]" +proof (induct p arbitrary: s q) + case (Cons i p) + show ?case using Cons(1)[of "args s ! i" "tl q"] Cons(2-) + by (cases s; cases q) (auto simp add: nth_list_update par_Cons_iff) +qed auto + +lemma poss_of_termE [elim]: + assumes "p \ poss_of_term u s" + and "p \ poss s \ s |_ p = u \ P" + shows "P" using assms unfolding poss_of_term_def + by blast + +lemma poss_of_term_Cons: + "i # p \ poss_of_term u (Fun f ts) \ p \ poss_of_term u (ts ! i)" + unfolding poss_of_term_def by auto + +lemma poss_of_term_const_ctxt_apply: + assumes "p \ poss_of_term (constT c) C\s\" + shows "p \ (hole_pos C) \ (hole_pos C) \\<^sub>p p" using assms +proof (induct p arbitrary: C) + case Nil then show ?case + by (cases C) auto +next + case (Cons i p) then show ?case + by (cases C) (fastforce simp add: par_Cons_iff dest!: poss_of_term_Cons)+ +qed + + +subsection \Lemmas for @{const subt_at} and @{const replace_term_at}\ + +lemma subt_at_append_dist: + "p @ q \ poss s \ s |_ (p @ q) = (s |_ p) |_ q" +proof (induct p arbitrary: s) + case (Cons i p) then show ?case + by (cases s) auto +qed auto + +lemma ctxt_apply_term_subt_at_hole_pos [simp]: + "C\s\ |_ (hole_pos C @ q) = s |_ q" + by (induct C) auto + +lemma subst_subt_at_dist: + "p \ poss s \ s \ \ |_ p = s |_ p \ \" +proof (induct p arbitrary: s) + case (Cons i p) then show ?case + by (cases s) auto +qed auto + +lemma replace_term_at_subt_at_id [simp]: "s[p \ (s |_ p)] = s" +proof (induct p arbitrary: s) + case (Cons i p) then show ?case + by (cases s) auto +qed auto + + +lemma replace_term_at_same_pos [simp]: + "s[p \ u][p \ t] = s[p \ t]" + using position_less_refl replace_term_at_above by blast + +\ \Replacement at under substitution\ +lemma subt_at_vars_term: + "p \ poss s \ s |_ p = Var x \ x \ vars_term s" + by (metis UnCI ctxt_at_pos_subt_at_id term.set_intros(3) vars_term_ctxt_apply) + +lemma linear_term_varposs_subst_replace_term: + "linear_term s \ p \ varposs s \ p \\<^sub>p q \ + (s \ \)[q \ u] = s \ (\ x. if Var x = s |_ p then (\ x)[q -\<^sub>p p \ u] else (\ x))" +proof (induct q arbitrary: s p) + case (Cons i q) + show ?case using Cons(1)[of "args s ! i" "tl p"] Cons(2-) + by (cases s) (auto simp: varposs_def nth_list_update term_subst_eq_conv + is_partition_alt is_partition_alt_def disjoint_iff subt_at_vars_term intro!: nth_equalityI) +qed (auto simp: varposs_def) + +\ \Replacement at context parallel to the hole position\ +lemma par_hole_pos_replace_term_context_at: + "p \ hole_pos C \ C\s\[p \ u] = (C[p \ u]\<^sub>C)\s\" +proof (induct p arbitrary: C) + case (Cons i p) + from Cons(2) obtain f ss D ts where [simp]: "C = More f ss D ts" by (cases C) auto + show ?case using Cons(1)[of D] Cons(2) + by (auto simp: list_update_append nth_append_Cons minus_nat.simps(2) split: nat.splits) +qed auto + +lemma par_pos_replace_term_at: + "p \ poss s \ p \ q \ s[q \ t] |_ p = s |_ p" +proof (induct p arbitrary: s q) + case (Cons i p) + show ?case using Cons(1)[of "args s ! i" "tl q"] Cons(2-) + by (cases s; cases q) (auto, metis nth_list_update par_Cons_iff) +qed auto + + +lemma less_eq_subt_at_replace: + "p \ poss s \ p \\<^sub>p q \ s[q \ t] |_ p = (s |_ p)[q -\<^sub>p p \ t]" +proof (induct p arbitrary: s q) + case (Cons i p) + show ?case using Cons(1)[of "args s ! i" "tl q"] Cons(2-) + by (cases s; cases q) auto +qed auto + + +lemma greater_eq_subt_at_replace: + "p \ poss s \ q \\<^sub>p p \ s[q \ t] |_ p = t |_ (p -\<^sub>p q)" +proof (induct p arbitrary: s q) + case (Cons i p) + show ?case using Cons(1)[of "args s ! i" "tl q"] Cons(2-) + by (cases s; cases q) auto +qed auto + +lemma replace_subterm_at_itself [simp]: + "s[p \ (s |_ p)[q \ t]] = s[p @ q \ t]" +proof (induct p arbitrary: s) + case (Cons i p) + show ?case using Cons(1)[of "args s ! i"] + by (cases s) auto +qed auto + + +lemma hole_pos_replace_term_at [simp]: + "hole_pos C \\<^sub>p p \ C\s\[p \ u] = C\s[p -\<^sub>p hole_pos C \ u]\" +proof (induct C arbitrary: p) + case (More f ss C ts) then show ?case + by (cases p) auto +qed auto + +lemma ctxt_of_pos_term_apply_replace_at_ident: + assumes "p \ poss s" + shows "(ctxt_at_pos s p)\t\ = s[p \ t]" + using assms +proof (induct p arbitrary: s) + case (Cons i p) + show ?case using Cons(1)[of "args s ! i"] Cons(2-) + by (cases s) (auto simp: nth_append_Cons intro!: nth_equalityI) +qed auto + +lemma ctxt_apply_term_replace_term_hole_pos [simp]: + "C\s\[hole_pos C @ q \ u] = C\s[q \ u]\" + by (simp add: pos_diff_def position_less_eq_def remove_prefix_append) + +lemma ctxt_apply_subt_at_hole_pos [simp]: "C\s\ |_ hole_pos C = s" + by (induct C) auto + +lemma subt_at_imp_supteq': + assumes "p \ poss s" and "s|_p = t" shows "s \ t" using assms +proof (induct p arbitrary: s) + case (Cons i p) + from Cons(2-) show ?case using Cons(1)[of "args s ! i"] + by (cases s) force+ +qed auto + +lemma subt_at_imp_supteq: + assumes "p \ poss s" shows "s \ s|_p" +proof - + have "s|_p = s|_p" by auto + with assms show ?thesis by (rule subt_at_imp_supteq') +qed + + +subsection \@{const term_to_sig} invariants and distributions\ + +lemma fuans_term_term_to_sig [simp]: "funas_term (term_to_sig \ v t) \ \" + by (induct t) auto + +lemma term_to_sig_id [simp]: + "funas_term t \ \ \ term_to_sig \ v t = t" + by (induct t) (auto simp add: UN_subset_iff map_idI) + +lemma term_to_sig_subst_sig [simp]: + "funas_term t \ \ \ term_to_sig \ v (t \ \) = t \ (\ x. term_to_sig \ v (\ x))" + by (induct t) auto + +lemma funas_ctxt_ctxt_inv_const_ctxt_ind [simp]: + "funas_ctxt C \ \ \ inv_const_ctxt \ v C = C" + by (induct C) (auto simp add: UN_subset_iff intro!: nth_equalityI) + +lemma term_to_sig_ctxt_apply [simp]: + "ctxt_well_def_hole_path \ C \ term_to_sig \ v C\s\ = (inv_const_ctxt \ v C)\term_to_sig \ v s\" + by (induct C) auto + +lemma term_to_sig_ctxt_apply' [simp]: + "\ ctxt_well_def_hole_path \ C \ term_to_sig \ v C\s\ = inv_const_ctxt' \ v C" + by (induct C) auto + +lemma funas_ctxt_ctxt_well_def_hole_path: + "funas_ctxt C \ \ \ ctxt_well_def_hole_path \ C" + by (induct C) auto + + +subsection \Misc\ + +lemma funas_term_subt_at: + "(f, n) \ funas_term t \ (\ p ts. p \ poss t \ t |_ p = Fun f ts \ length ts = n)" +proof (induct t) + case (Fun g ts) note IH = this + show ?case + proof (cases "g = f \ length ts = n") + case False + then obtain i where i: "i < length ts" "(f, n) \ funas_term (ts ! i)" using IH(2) + using in_set_idx by force + from IH(1)[OF nth_mem[OF this(1)] this(2)] show ?thesis using i(1) + by (metis poss_Cons_poss subt_at.simps(2) term.sel(4)) + qed auto +qed simp + +lemma finite_poss: "finite (poss s)" +proof (induct s) + case (Fun f ts) + have "poss (Fun f ts) = insert [] (\ (set (map2 (\ i p. ((#) i) ` p) [0..< length ts] (map poss ts))))" + by (auto simp: image_iff set_zip split: prod.splits) + then show ?case using Fun + by (auto simp del: poss.simps dest!: set_zip_rightD) +qed simp + +lemma finite_varposs: "finite (varposs s)" + by (intro finite_subset[of "varposs s" "poss s"]) (auto simp: varposs_def finite_poss) + +lemma gound_linear [simp]: "ground t \ linear_term t" + by (induct t) (auto simp: is_partition_alt is_partition_alt_def) + +declare ground_substI[intro, simp] +lemma ground_ctxt_substI: + "(\ x. x \ vars_ctxt C \ ground (\ x)) \ ground_ctxt (C \\<^sub>c \)" + by (induct C) auto + + +lemma funas_ctxt_subst_apply_ctxt: + "funas_ctxt (C \\<^sub>c \) = funas_ctxt C \ (\ (funas_term ` \ ` vars_ctxt C))" +proof (induct C) + case (More f ss C ts) + then show ?case + by (fastforce simp add: funas_term_subst) +qed simp + +lemma varposs_Var[simp]: + "varposs (Var x) = {[]}" + by (auto simp: varposs_def) + +lemma varposs_Fun[simp]: + "varposs (Fun f ts) = { i # p| i p. i < length ts \ p \ varposs (ts ! i)}" + by (auto simp: varposs_def) + +lemma vars_term_varposs_iff: + "x \ vars_term s \ (\ p \ varposs s. s |_ p = Var x)" +proof (induct s) + case (Fun f ts) + show ?case using Fun[OF nth_mem] + by (force simp: in_set_conv_nth Bex_def) +qed auto + +lemma vars_term_empty_ground: + "vars_term s = {} \ ground s" + by (metis equals0D ground_substI subst_ident) + +lemma ground_subst_apply: "ground t \ t \ \ = t" + by (induct t) (auto intro: nth_equalityI) + +lemma varposs_imp_poss: + "p \ varposs s \ p \ poss s" by (auto simp: varposs_def) + +lemma varposs_empty_gound: + "varposs s = {} \ ground s" + by (induct s) (fastforce simp: in_set_conv_nth)+ + +lemma funas_term_subterm_atI [intro]: + "p \ poss s \ funas_term s \ \ \ funas_term (s |_ p) \ \" + by (metis ctxt_at_pos_subt_at_id funas_ctxt_apply le_sup_iff) + +lemma varposs_ground_replace_at: + "p \ varposs s \ ground u \ varposs s[p \ u] = varposs s - {p}" +proof (induct p arbitrary: s) + case Nil then show ?case + by (cases s) (auto simp: varposs_empty_gound) +next + case (Cons i p) + from Cons(2) obtain f ts where [simp]: "s = Fun f ts" by (cases s) auto + from Cons(2) have var: "p \ varposs (ts ! i)" by auto + from Cons(1)[OF var Cons(3)] have "j < length ts \ {j # q| q. q \ varposs (ts[i := (ts ! i)[p \ u]] ! j)} = + {j # q |q. q \ varposs (ts ! j)} - {i # p}" for j + by (cases "j = i") (auto simp add: nth_list_update) + then show ?case by auto blast +qed + +lemma funas_term_replace_at_upper: + "funas_term s[p \ t] \ funas_term s \ funas_term t" +proof (induct p arbitrary: s) + case (Cons i p) + show ?case using Cons(1)[of "args s ! i"] + by (cases s) (fastforce simp: in_set_conv_nth nth_list_update split!: if_splits)+ +qed simp + +lemma funas_term_replace_at_lower: + "p \ poss s \ funas_term t \ funas_term (s[p \ t])" +proof (induct p arbitrary: s) + case (Cons i p) + show ?case using Cons(1)[of "args s ! i"] Cons(2-) + by (cases s) (fastforce simp: in_set_conv_nth nth_list_update split!: if_splits)+ +qed simp + +lemma poss_of_term_possI [intro!]: + "p \ poss s \ s |_ p = u \ p \ poss_of_term u s" + unfolding poss_of_term_def by blast + +lemma poss_of_term_replace_term_at: + "p \ poss s \ p \ poss_of_term u s[p \ u]" +proof (induct p arbitrary: s) + case (Cons i p) then show ?case + by (cases s) (auto simp: poss_of_term_def) +qed auto + +lemma constT_nfunas_term_poss_of_term_empty: + "(c, 0) \ funas_term t \ poss_of_term (constT c) t = {}" + unfolding poss_of_term_def + using funas_term_subt_at[of c 0 t] + using funas_term_subterm_atI[where ?\ ="funas_term t" and ?s = t, THEN subsetD] + by auto + +lemma poss_of_term_poss_emptyD: + assumes "poss_of_term u s = {}" + shows "p \ poss s \ s |_ p \ u" using assms + unfolding poss_of_term_def by blast + +lemma possc_subt_at_ctxt_apply: + "p \ possc C \ p \ hole_pos C \ C\s\ |_ p = C\t\ |_ p" +proof (induct p arbitrary: C) + case (Cons i p) + have [dest]: "length ss # p \ possc (More f ss D ts) \ p \ possc D" for f ss D ts + by (auto simp: possc_def) + show ?case using Cons + by (cases C) (auto simp: nth_append_Cons) +qed simp + +end \ No newline at end of file diff --git a/thys/Rewrite_Properties_Reduction/document/root.bib b/thys/Rewrite_Properties_Reduction/document/root.bib new file mode 100644 --- /dev/null +++ b/thys/Rewrite_Properties_Reduction/document/root.bib @@ -0,0 +1,12 @@ + + +@article{AFP-CSRT, + author = {Christian Sternagel and René Thiemann}, + title = {Abstract Rewriting}, + journal = {Archive of Formal Proofs}, + month = jun, + year = 2010, + note = {\url{https://isa-afp.org/entries/Abstract-Rewriting.html}, + Formal proof development}, + ISSN = {2150-914x}, +} diff --git a/thys/Rewrite_Properties_Reduction/document/root.tex b/thys/Rewrite_Properties_Reduction/document/root.tex new file mode 100644 --- /dev/null +++ b/thys/Rewrite_Properties_Reduction/document/root.tex @@ -0,0 +1,134 @@ +\documentclass[11pt,a4paper]{article} +\usepackage{isabelle,isabellesym} + +\usepackage{url} +\usepackage{amsmath} +\usepackage{amssymb} +\usepackage{xspace} +\usepackage[T1]{fontenc} + +% this should be the last package used +\usepackage{pdfsetup} + +% urls in roman style, theory text in math-similar italics +\urlstyle{rm} +\isabellestyle{it} + +\newcommand\isafor{\textsf{Isa\kern-0.15exF\kern-0.15exo\kern-0.15exR}} +\newcommand\ceta{\textsf{C\kern-0.15exe\kern-0.45exT\kern-0.45exA}} + + +\newcommand{\h}[1][.3]{\hspace{#1mm}} +\newcommand{\seq}[2][n]{#2_1,\dotsc,#2_{#1}} +\newcommand{\SET}[1]{\{\h #1\h\}} + + +\newcommand{\m}[1]{\mathrm{#1}} +\newcommand{\xR}{\mathcal{R}} +\newcommand{\xS}{\mathcal{S}} + +\newcommand{\R}{\rightarrow} +\newcommand{\Rab}[2][]{\R_{#1}^{#2}} + +\newcommand{\RabR}[1]{\Rab[\xR]{#1}} +\newcommand{\RabS}[1]{\Rab[\xS]{#1}} + +\newcommand{\LR}{\leftrightarrow} +\newcommand{\LRab}[2][]{\LR_{#1}^{#2}} +\newcommand{\Con}[1][]{\LRab[#1]{*}} +\newcommand{\CbR}{\LRab[\xR]{*}} +\newcommand{\CbS}{\LRab[\xS]{*}} + +\newcommand{\xF}{\mathcal{F}} +\newcommand{\xT}{\mathcal{T}} + +\newcommand{\T}[1][\xF]{\xT(#1,\xV)} +\newcommand{\GT}[1][\xF]{\xT(#1)} +\begin{document} + + +\title{Reducing Rewrite Properties to Properties on Ground Terms\footnote{Supported by FWF (Austrian Science Fund) projects P30301.}} +\author{Alexander Lochmann} +\maketitle + +\begin{abstract} +This AFP entry relates important rewriting properties +between the set of terms and the set of ground terms induced +by a given signature. The properties considered are +confluence, strong/local confluence, the normal form property, +unique normal forms with respect to reduction and conversion, commutation, +conversion equivalence, and normalization equivalence. +\end{abstract} + +\tableofcontents + +\section{Introduction} + +Rewriting is an abstract model of computation. +Among other things, it studies important properties +including the following: + +\begin{align*} +\label{prop} +\m{CR}\colon&~~ \forall\,s\,\forall\,t\,\forall\,u\,(s \Rab{*} t \land +s \Rab{*} u \implies t \downarrow u) \tag*{confluence} \\ +\m{SCR}\colon&~~ \forall\,s\,\forall\,t\,\forall\,u\,(s \R t \land +s \R u \implies \exists\,v~(t \Rab{=} v \land u \Rab{*} v)) +\tag*{strong confluence} \\ +\m{WCR}\colon&~~ \forall\,s\,\forall\,t\,\forall\,u\,(s \R t \land s \R u +\implies t \downarrow u) \tag*{local confluence} \\ +\m{NFP}\colon&~~ \forall\,s\,\forall\,t\,\forall\,u\,(s \Rab{*} t \land s +\Rab{!} u \implies t \Rab{!} u) \tag*{normal form property} \\ +\m{UNR}\colon&~~ \forall\,s\,\forall\,t\,\forall\,u\,(s \Rab{!} t \land +s \Rab{!} u \implies t = u) +\tag*{unique normal forms with respect to reduction} \\ +\m{UNC}\colon&~~ \phantom{\forall\,s\,}\forall\,t\,\forall\,u\, +(t \Con u \land \m{NF}(t) \land \m{NF}(u) \implies t = u) +\tag*{unique normal forms with respect to conversion} +\intertext{We also consider the following properties involving two TRSs $\xR$ and +$\xS$:} +\m{COM}:& \quad \forall\,s\,\forall\,t\,\forall\,u\,(s \RabR{*} t \land +s \RabS{*} u \implies \exists\,v\,(t \RabS{*} v \land u \RabR{*} v)) +\tag*{commutation} \\ +\m{CE}:& \quad \forall\,s\,\forall\,t\,(s \CbR t \iff s \CbS t) +\tag*{conversion equivalence} \\ +\m{NE}:& \quad \forall\,s\,\forall\,t\,(s \RabR{!} t \iff s \RabS{!} t) +\tag*{normalization equivalence} +\end{align*} + +An interesting observation is that for each of these properties there +exists a rewrite system that satisfies the property when restricted to +ground terms but not when arbitrary terms are allowed. +Consider the left-linear right-ground TRS $\xR$ consisting of the rules +\begin{align*} +\m{a} &\R \m{b} & +\m{f}(\m{a},x) &\R \m{b} & +\m{f}(\m{b},\m{b}) &\R \m{b} +\end{align*} +over the signature $\xF = \SET{\m{a},\m{b},\m{f}}$. It is ground-confluent +because every ground term in $\GT$ rewrites to $\m{b}$. Confluence does +not hold; the term $\m{f}(\m{a},x)$ rewrites to the different normal forms +$\m{b}$ and $\m{f}(\m{b},x)$. + +In this AFP entry, properties on arbitrary terms are reduced to the +corresponding properties on ground terms, for left-linear right-ground +rewrite systems and for linear variable-separated systems. +To do this, I formalized fundamental term rewriting operations that +include the root step and the one step rewriting relations. Also, I added definitions for +conversion equivalence, normalization equivalence, +strong confluence and the normal from property extending +the list of important rewriting properties of the AFP entry +``Abstract Rewriting'' \cite{AFP-CSRT}. + +Rewrite sequences that contain a root step play an important role +in the formalization. The table of contents should give the reader a good overview +of the content of this entry. + +\input{session} + + +\bibliographystyle{abbrv} +\bibliography{root} + +\end{document} + diff --git a/web/entries/CZH_Elementary_Categories.html b/web/entries/CZH_Elementary_Categories.html --- a/web/entries/CZH_Elementary_Categories.html +++ b/web/entries/CZH_Elementary_Categories.html @@ -1,218 +1,222 @@ Category Theory for ZFC in HOL II: Elementary Theory of 1-Categories - Archive of Formal Proofs

 

 

 

 

 

 

Category Theory for ZFC in HOL II: Elementary Theory of 1-Categories

 

+ + + +
Title: Category Theory for ZFC in HOL II: Elementary Theory of 1-Categories
Author: - Mihails Milehins (user9716869 /at/ gmail /dot/ com) + Mihails Milehins (mihailsmilehins /at/ gmail /dot/ com)
Submission date: 2021-09-06
Abstract: This article provides a formalization of the foundations of the theory of 1-categories in the object logic ZFC in HOL of the formal proof assistant Isabelle. The article builds upon the foundations that were established in the AFP entry Category Theory for ZFC in HOL I: Foundations: Design Patterns, Set Theory, Digraphs, Semicategories.
Change history:[2021-11-07]: added a definition of a dagger monoidal category (revision c9ed46c09de9)
BibTeX:
@article{CZH_Elementary_Categories-AFP,
   author  = {Mihails Milehins},
   title   = {Category Theory for ZFC in HOL II: Elementary Theory of 1-Categories},
   journal = {Archive of Formal Proofs},
   month   = sep,
   year    = 2021,
   note    = {\url{https://isa-afp.org/entries/CZH_Elementary_Categories.html},
             Formal proof development},
   ISSN    = {2150-914x},
 }
License: BSD License
Depends on: CZH_Foundations
Used by: CZH_Universal_Constructions

\ No newline at end of file diff --git a/web/entries/CZH_Foundations.html b/web/entries/CZH_Foundations.html --- a/web/entries/CZH_Foundations.html +++ b/web/entries/CZH_Foundations.html @@ -1,235 +1,235 @@ Category Theory for ZFC in HOL I: Foundations: Design Patterns, Set Theory, Digraphs, Semicategories - Archive of Formal Proofs

 

 

 

 

 

 

Category Theory for ZFC in HOL I: Foundations: Design Patterns, Set Theory, Digraphs, Semicategories

 

Title: Category Theory for ZFC in HOL I: Foundations: Design Patterns, Set Theory, Digraphs, Semicategories
Author: - Mihails Milehins (user9716869 /at/ gmail /dot/ com) + Mihails Milehins (mihailsmilehins /at/ gmail /dot/ com)
Submission date: 2021-09-06
Abstract: This article provides a foundational framework for the formalization of category theory in the object logic ZFC in HOL of the formal proof assistant Isabelle. More specifically, this article provides a formalization of canonical set-theoretic constructions internalized in the type V associated with the ZFC in HOL, establishes a design pattern for the formalization of mathematical structures using sequences and locales, and showcases the developed infrastructure by providing formalizations of the elementary theories of digraphs and semicategories. The methodology chosen for the formalization of the theories of digraphs and semicategories (and categories in future articles) rests on the ideas that were originally expressed in the article Set-Theoretical Foundations of Category Theory written by Solomon Feferman and Georg Kreisel. Thus, in the context of this work, each of the aforementioned mathematical structures is represented as a term of the type V embedded into a stage of the von Neumann hierarchy.
BibTeX:
@article{CZH_Foundations-AFP,
   author  = {Mihails Milehins},
   title   = {Category Theory for ZFC in HOL I: Foundations: Design Patterns, Set Theory, Digraphs, Semicategories},
   journal = {Archive of Formal Proofs},
   month   = sep,
   year    = 2021,
   note    = {\url{https://isa-afp.org/entries/CZH_Foundations.html},
             Formal proof development},
   ISSN    = {2150-914x},
 }
License: BSD License
Depends on: Conditional_Simplification, Intro_Dest_Elim, ZFC_in_HOL
Used by: CZH_Elementary_Categories

\ No newline at end of file diff --git a/web/entries/CZH_Universal_Constructions.html b/web/entries/CZH_Universal_Constructions.html --- a/web/entries/CZH_Universal_Constructions.html +++ b/web/entries/CZH_Universal_Constructions.html @@ -1,212 +1,216 @@ Category Theory for ZFC in HOL III: Universal Constructions - Archive of Formal Proofs

 

 

 

 

 

 

Category Theory for ZFC in HOL III: Universal Constructions

 

+ + + +
Title: Category Theory for ZFC in HOL III: Universal Constructions
Author: - Mihails Milehins (user9716869 /at/ gmail /dot/ com) + Mihails Milehins (mihailsmilehins /at/ gmail /dot/ com)
Submission date: 2021-09-06
Abstract: The article provides a formalization of elements of the theory of universal constructions for 1-categories (such as limits, adjoints and Kan extensions) in the object logic ZFC in HOL of the formal proof assistant Isabelle. The article builds upon the foundations established in the AFP entry Category Theory for ZFC in HOL II: Elementary Theory of 1-Categories.
Change history:[2022-05-16]: creation and preservation of limits (revision 68412a363595)
BibTeX:
@article{CZH_Universal_Constructions-AFP,
   author  = {Mihails Milehins},
   title   = {Category Theory for ZFC in HOL III: Universal Constructions},
   journal = {Archive of Formal Proofs},
   month   = sep,
   year    = 2021,
   note    = {\url{https://isa-afp.org/entries/CZH_Universal_Constructions.html},
             Formal proof development},
   ISSN    = {2150-914x},
 }
License: BSD License
Depends on: CZH_Elementary_Categories

\ No newline at end of file diff --git a/web/entries/Combinable_Wands.html b/web/entries/Combinable_Wands.html new file mode 100644 --- /dev/null +++ b/web/entries/Combinable_Wands.html @@ -0,0 +1,229 @@ + + + + +A Restricted Definition of the Magic Wand to Soundly Combine Fractions of a Wand - Archive of Formal Proofs + + + + + + + + + + + + + + + + + + + + + + + + +
+

 

+ + + +

 

+

 

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

 

+

 

+
+
+

 

+

A + + Restricted + + Definition + + of + + the + + Magic + + Wand + + to + + Soundly + + Combine + + Fractions + + of + + a + + Wand + +

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Title:A Restricted Definition of the Magic Wand to Soundly Combine Fractions of a Wand
+ Author: + + Thibault Dardinier +
Submission date:2022-05-30
Abstract: +Many separation logics support fractional +permissions to distinguish between read and write access to +a heap location, for instance, to allow concurrent reads while +enforcing exclusive writes. The concept has been generalized to +fractional assertions. $A^p$ (where $A$ is a separation logic +assertion and $p$ a fraction between $0$ and $1$) represents a +fraction $p$ of $A$. $A^p$ holds in a state $\sigma$ iff there exists +a state $\sigma_A$ in which $A$ holds and $\sigma$ is obtained from +$\sigma_A$ by multiplying all permission amounts held by $p$. While +$A^{p + q}$ can always be split into $A^p * A^q$, recombining $A^p * +A^q$ into $A^{p+q}$ is not always sound. We say that $A$ is +combinable iff the entailment $A^p * A^q \models +A^{p+q}$ holds for any two positive fractions $p$ and $q$ such that $p ++ q \le 1$. Combinable assertions are particularly useful to reason +about concurrent programs, for instance, to combine the postconditions +of parallel branches when they terminate. Unfortunately, the magic +wand assertion $A \mathbin{-\!\!*} B$, commonly used to specify properties of +partial data structures, is typically not +combinable. In this entry, we formalize a novel, restricted +definition of the magic wand, described in a paper at CAV +22, which we call the combinable wand. +We prove some key properties of the combinable wand; in particular, a +combinable wand is combinable if its right-hand side is combinable.
BibTeX: +
@article{Combinable_Wands-AFP,
+  author  = {Thibault Dardinier},
+  title   = {A Restricted Definition of the Magic Wand to Soundly Combine Fractions of a Wand},
+  journal = {Archive of Formal Proofs},
+  month   = may,
+  year    = 2022,
+  note    = {\url{https://isa-afp.org/entries/Combinable_Wands.html},
+            Formal proof development},
+  ISSN    = {2150-914x},
+}
+
License:BSD License
Depends on:Package_logic
+ +

+ + + + + + + + + + + + + + + + + + +
+
+ + + + + + \ No newline at end of file diff --git a/web/entries/Conditional_Simplification.html b/web/entries/Conditional_Simplification.html --- a/web/entries/Conditional_Simplification.html +++ b/web/entries/Conditional_Simplification.html @@ -1,201 +1,205 @@ Conditional Simplification - Archive of Formal Proofs

 

 

 

 

 

 

Conditional Simplification

 

+ + + +
Title: Conditional Simplification
Author: - Mihails Milehins (user9716869 /at/ gmail /dot/ com) + Mihails Milehins (mihailsmilehins /at/ gmail /dot/ com)
Submission date: 2021-09-06
Abstract: The article provides a collection of experimental general-purpose proof methods for the object logic Isabelle/HOL of the formal proof assistant Isabelle. The methods in the collection offer functionality that is similar to certain aspects of the functionality provided by the standard proof methods of Isabelle that combine classical reasoning and rewriting, such as the method auto, but use a different approach for rewriting. More specifically, these methods allow for the side conditions of the rewrite rules to be solved via intro-resolution.
Change history:[2022-01-07]: added a switch for backtracking (revision 241da1cdeabf)
BibTeX:
@article{Conditional_Simplification-AFP,
   author  = {Mihails Milehins},
   title   = {Conditional Simplification},
   journal = {Archive of Formal Proofs},
   month   = sep,
   year    = 2021,
   note    = {\url{https://isa-afp.org/entries/Conditional_Simplification.html},
             Formal proof development},
   ISSN    = {2150-914x},
 }
License: BSD License
Used by: CZH_Foundations

\ No newline at end of file diff --git a/web/entries/Conditional_Transfer_Rule.html b/web/entries/Conditional_Transfer_Rule.html --- a/web/entries/Conditional_Transfer_Rule.html +++ b/web/entries/Conditional_Transfer_Rule.html @@ -1,200 +1,200 @@ Conditional Transfer Rule - Archive of Formal Proofs

 

 

 

 

 

 

Conditional Transfer Rule

 

Title: Conditional Transfer Rule
Author: - Mihails Milehins (user9716869 /at/ gmail /dot/ com) + Mihails Milehins (mihailsmilehins /at/ gmail /dot/ com)
Submission date: 2021-09-06
Abstract: This article provides a collection of experimental utilities for unoverloading of definitions and synthesis of conditional transfer rules for the object logic Isabelle/HOL of the formal proof assistant Isabelle written in Isabelle/ML.
BibTeX:
@article{Conditional_Transfer_Rule-AFP,
   author  = {Mihails Milehins},
   title   = {Conditional Transfer Rule},
   journal = {Archive of Formal Proofs},
   month   = sep,
   year    = 2021,
   note    = {\url{https://isa-afp.org/entries/Conditional_Transfer_Rule.html},
             Formal proof development},
   ISSN    = {2150-914x},
 }
License: BSD License
Depends on: SpecCheck
Used by: Types_To_Sets_Extension

\ No newline at end of file diff --git a/web/entries/DPRM_Theorem.html b/web/entries/DPRM_Theorem.html new file mode 100644 --- /dev/null +++ b/web/entries/DPRM_Theorem.html @@ -0,0 +1,203 @@ + + + + +Diophantine Equations and the DPRM Theorem - Archive of Formal Proofs + + + + + + + + + + + + + + + + + + + + + + + + +
+

 

+ + + +

 

+

 

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

 

+

 

+
+
+

 

+

Diophantine + + Equations + + and + + the + + DPRM + + Theorem + +

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Title:Diophantine Equations and the DPRM Theorem
+ Authors: + + Jonas Bayer, + Marco David, + Benedikt Stock, + Abhik Pal, + Yuri Matiyasevich and + Dierk Schleicher +
Submission date:2022-06-06
Abstract: +We present a formalization of Matiyasevich's proof of the DPRM +theorem, which states that every recursively enumerable set of natural +numbers is Diophantine. This result from 1970 yields a negative +solution to Hilbert's 10th problem over the integers. To +represent recursively enumerable sets in equations, we implement and +arithmetize register machines. We formalize a general theory of +Diophantine sets and relations to reason about them abstractly. Using +several number-theoretic lemmas, we prove that exponentiation has a +Diophantine representation.
BibTeX: +
@article{DPRM_Theorem-AFP,
+  author  = {Jonas Bayer and Marco David and Benedikt Stock and Abhik Pal and Yuri Matiyasevich and Dierk Schleicher},
+  title   = {Diophantine Equations and the DPRM Theorem},
+  journal = {Archive of Formal Proofs},
+  month   = jun,
+  year    = 2022,
+  note    = {\url{https://isa-afp.org/entries/DPRM_Theorem.html},
+            Formal proof development},
+  ISSN    = {2150-914x},
+}
+
License:BSD License
Depends on:Digit_Expansions, Lucas_Theorem
+ +

+ + + + + + + + + + + + + + + + + + +
+
+ + + + + + \ No newline at end of file diff --git a/web/entries/Digit_Expansions.html b/web/entries/Digit_Expansions.html --- a/web/entries/Digit_Expansions.html +++ b/web/entries/Digit_Expansions.html @@ -1,189 +1,191 @@ Digit Expansions - Archive of Formal Proofs

 

 

 

 

 

 

Digit Expansions

 

- + + +
Title: Digit Expansions
Authors: - Jonas Bayer (jonas /dot/ bayer999 /at/ gmail /dot/ com), - Marco David (marco /dot/ david /at/ hotmail /dot/ de), - Abhik Pal (apal /at/ ucsd /dot/ edu) and - Benedikt Stock (benedikt1999 /at/ freenet /dot/ de) + Jonas Bayer, + Marco David, + Abhik Pal and + Benedikt Stock
Submission date: 2022-04-20
Abstract: We formalize how a natural number can be expanded into its digits in some base and prove properties about functions that operate on digit expansions. This includes the formalization of concepts such as digit shifts and carries. For a base that is a power of 2 we formalize the binary AND, binary orthogonality and binary masking of two natural numbers. This library on digit expansions builds the basis for the formalization of the DPRM theorem.
BibTeX:
@article{Digit_Expansions-AFP,
   author  = {Jonas Bayer and Marco David and Abhik Pal and Benedikt Stock},
   title   = {Digit Expansions},
   journal = {Archive of Formal Proofs},
   month   = apr,
   year    = 2022,
   note    = {\url{https://isa-afp.org/entries/Digit_Expansions.html},
             Formal proof development},
   ISSN    = {2150-914x},
 }
License: BSD License
Used by:DPRM_Theorem

\ No newline at end of file diff --git a/web/entries/Dirichlet_Series.html b/web/entries/Dirichlet_Series.html --- a/web/entries/Dirichlet_Series.html +++ b/web/entries/Dirichlet_Series.html @@ -1,227 +1,227 @@ Dirichlet Series - Archive of Formal Proofs

 

 

 

 

 

 

Dirichlet Series

 

- +
Title: Dirichlet Series
Author: Manuel Eberl
Submission date: 2017-10-12
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.
BibTeX:
@article{Dirichlet_Series-AFP,
   author  = {Manuel Eberl},
   title   = {Dirichlet Series},
   journal = {Archive of Formal Proofs},
   month   = oct,
   year    = 2017,
   note    = {\url{https://isa-afp.org/entries/Dirichlet_Series.html},
             Formal proof development},
   ISSN    = {2150-914x},
 }
License: BSD License
Depends on: Euler_MacLaurin, Landau_Symbols, Polynomial_Factorization
Used by:Dirichlet_L, Gauss_Sums, Zeta_Function
Dirichlet_L, Finite_Fields, Gauss_Sums, Zeta_Function

\ No newline at end of file diff --git a/web/entries/Finite_Fields.html b/web/entries/Finite_Fields.html new file mode 100644 --- /dev/null +++ b/web/entries/Finite_Fields.html @@ -0,0 +1,194 @@ + + + + +Finite Fields - Archive of Formal Proofs + + + + + + + + + + + + + + + + + + + + + + + + +
+

 

+ + + +

 

+

 

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

 

+

 

+
+
+

 

+

Finite + + Fields + +

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Title:Finite Fields
+ Author: + + Emin Karayel +
Submission date:2022-06-08
Abstract: +This entry formalizes the classification of the finite fields (also +called Galois fields): For each prime power $p^n$ there exists exactly +one (up to isomorphisms) finite field of that size and there are no +other finite fields. The derivation includes a formalization of the +characteristic of rings, the Frobenius endomorphism, formal +differentiation for polynomials in HOL-Algebra and Gauss' formula +for the number of monic irreducible polynomials over finite fields: \[ +\frac{1}{n} \sum_{d | n} \mu(d) p^{n/d} \textrm{.} \] The proofs are +based on the books from Ireland +and Rosen, as well as, Lidl and +Niederreiter.
BibTeX: +
@article{Finite_Fields-AFP,
+  author  = {Emin Karayel},
+  title   = {Finite Fields},
+  journal = {Archive of Formal Proofs},
+  month   = jun,
+  year    = 2022,
+  note    = {\url{https://isa-afp.org/entries/Finite_Fields.html},
+            Formal proof development},
+  ISSN    = {2150-914x},
+}
+
License:BSD License
Depends on:Dirichlet_Series
+ +

+ + + + + + + + + + + + + + + + + + +
+
+ + + + + + \ 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,212 +1,212 @@ Formalization of Multiway-Join Algorithms - Archive of Formal Proofs

 

 

 

 

 

 

Formalization of Multiway-Join Algorithms

 

Title: Formalization of Multiway-Join Algorithms
Author: - Thibault Dardinier + 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{https://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/Intro_Dest_Elim.html b/web/entries/Intro_Dest_Elim.html --- a/web/entries/Intro_Dest_Elim.html +++ b/web/entries/Intro_Dest_Elim.html @@ -1,201 +1,201 @@ IDE: Introduction, Destruction, Elimination - Archive of Formal Proofs

 

 

 

 

 

 

IDE: Introduction, Destruction, Elimination

 

Title: IDE: Introduction, Destruction, Elimination
Author: - Mihails Milehins (user9716869 /at/ gmail /dot/ com) + Mihails Milehins (mihailsmilehins /at/ gmail /dot/ com)
Submission date: 2021-09-06
Abstract: The article provides the command mk_ide for the object logic Isabelle/HOL of the formal proof assistant Isabelle. The command mk_ide enables the automated synthesis of the introduction, destruction and elimination rules from arbitrary definitions of constant predicates stated in Isabelle/HOL.
BibTeX:
@article{Intro_Dest_Elim-AFP,
   author  = {Mihails Milehins},
   title   = {IDE: Introduction, Destruction, Elimination},
   journal = {Archive of Formal Proofs},
   month   = sep,
   year    = 2021,
   note    = {\url{https://isa-afp.org/entries/Intro_Dest_Elim.html},
             Formal proof development},
   ISSN    = {2150-914x},
 }
License: BSD License
Used by: CZH_Foundations

\ No newline at end of file diff --git a/web/entries/Jacobson_Basic_Algebra.html b/web/entries/Jacobson_Basic_Algebra.html --- a/web/entries/Jacobson_Basic_Algebra.html +++ b/web/entries/Jacobson_Basic_Algebra.html @@ -1,211 +1,211 @@ A Case Study in Basic Algebra - Archive of Formal Proofs

 

 

 

 

 

 

A Case Study in Basic Algebra

 

- +
Title: A Case Study in Basic Algebra
Author: Clemens Ballarin
Submission date: 2019-08-30
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.
BibTeX:
@article{Jacobson_Basic_Algebra-AFP,
   author  = {Clemens Ballarin},
   title   = {A Case Study in Basic Algebra},
   journal = {Archive of Formal Proofs},
   month   = aug,
   year    = 2019,
   note    = {\url{https://isa-afp.org/entries/Jacobson_Basic_Algebra.html},
             Formal proof development},
   ISSN    = {2150-914x},
 }
License: BSD License
Used by:Grothendieck_Schemes
Grothendieck_Schemes, Pluennecke_Ruzsa_Inequality

\ No newline at end of file diff --git a/web/entries/Lucas_Theorem.html b/web/entries/Lucas_Theorem.html --- a/web/entries/Lucas_Theorem.html +++ b/web/entries/Lucas_Theorem.html @@ -1,203 +1,205 @@ Lucas's Theorem - Archive of Formal Proofs

 

 

 

 

 

 

Lucas's Theorem

 

- + + +
Title: Lucas's Theorem
Author: Chelsea Edmonds
Submission date: 2020-04-07
Abstract: This work presents a formalisation of a generating function proof for Lucas's theorem. We first outline extensions to the existing Formal Power Series (FPS) library, including an equivalence relation for coefficients modulo n, an alternate binomial theorem statement, and a formalised proof of the Freshman's dream (mod p) lemma. The second part of the work presents the formal proof of Lucas's Theorem. Working backwards, the formalisation first proves a well known corollary of the theorem which is easier to formalise, and then applies induction to prove the original theorem statement. The proof of the corollary aims to provide a good example of a formalised generating function equivalence proof using the FPS library. The final theorem statement is intended to be integrated into the formalised proof of Hilbert's 10th Problem.
BibTeX:
@article{Lucas_Theorem-AFP,
   author  = {Chelsea Edmonds},
   title   = {Lucas's Theorem},
   journal = {Archive of Formal Proofs},
   month   = apr,
   year    = 2020,
   note    = {\url{https://isa-afp.org/entries/Lucas_Theorem.html},
             Formal proof development},
   ISSN    = {2150-914x},
 }
License: BSD License
Used by:DPRM_Theorem

\ No newline at end of file diff --git a/web/entries/MFODL_Monitor_Optimized.html b/web/entries/MFODL_Monitor_Optimized.html --- a/web/entries/MFODL_Monitor_Optimized.html +++ b/web/entries/MFODL_Monitor_Optimized.html @@ -1,252 +1,251 @@ 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, + 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 +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.
Change history: [2021-10-19]: corrected a mistake in the calculation of median aggregations (reported by Nicolas Kaletsch, revision 02b14c9bf3da)
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{https://isa-afp.org/entries/MFODL_Monitor_Optimized.html},
             Formal proof development},
   ISSN    = {2150-914x},
 }
License: BSD License
Depends on: Generic_Join, IEEE_Floating_Point, MFOTL_Monitor

\ No newline at end of file diff --git a/web/entries/Package_logic.html b/web/entries/Package_logic.html new file mode 100644 --- /dev/null +++ b/web/entries/Package_logic.html @@ -0,0 +1,214 @@ + + + + +Formalization of a Framework for the Sound Automation of Magic Wands - Archive of Formal Proofs + + + + + + + + + + + + + + + + + + + + + + + + +
+

 

+ + + +

 

+

 

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

 

+

 

+
+
+

 

+

Formalization + + of + + a + + Framework + + for + + the + + Sound + + Automation + + of + + Magic + + Wands + +

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Title:Formalization of a Framework for the Sound Automation of Magic Wands
+ Author: + + Thibault Dardinier +
Submission date:2022-05-18
Abstract: +The magic wand $\mathbin{-\!\!*}$ (also called separating +implication) is a separation logic connective commonly used to specify +properties of partial data structures, for instance during iterative +traversals. A footprint of a magic wand formula +$$A \mathbin{-\!\!*} B$$ is a state that, combined with any state in +which $A$ holds, yields a state in which $B$ holds. The key +challenge of proving a magic wand (also called +packaging a wand) is to find such a footprint. +Existing package algorithms either have a high annotation overhead or +are unsound. In this entry, we formally define a framework for the +sound automation of magic wands, described in an upcoming +paper at CAV 2022, and prove that it is sound and complete. +This framework, called the package logic, +precisely characterises a wide design space of possible package +algorithms applicable to a large class of separation logics.
BibTeX: +
@article{Package_logic-AFP,
+  author  = {Thibault Dardinier},
+  title   = {Formalization of a Framework for the Sound Automation of Magic Wands},
+  journal = {Archive of Formal Proofs},
+  month   = may,
+  year    = 2022,
+  note    = {\url{https://isa-afp.org/entries/Package_logic.html},
+            Formal proof development},
+  ISSN    = {2150-914x},
+}
+
License:BSD License
Used by:Combinable_Wands
+ +

+ + + + + + + + + + + + + + + + + + +
+
+ + + + + + \ No newline at end of file diff --git a/web/entries/Pluennecke_Ruzsa_Inequality.html b/web/entries/Pluennecke_Ruzsa_Inequality.html new file mode 100644 --- /dev/null +++ b/web/entries/Pluennecke_Ruzsa_Inequality.html @@ -0,0 +1,191 @@ + + + + +The Plünnecke-Ruzsa Inequality - Archive of Formal Proofs + + + + + + + + + + + + + + + + + + + + + + + + +
+

 

+ + + +

 

+

 

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

 

+

 

+
+
+

 

+

The + + Plünnecke-Ruzsa + + Inequality + +

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Title:The Plünnecke-Ruzsa Inequality
+ Authors: + + Angeliki Koutsoukou-Argyraki and + Lawrence C. Paulson +
Submission date:2022-05-26
Abstract: +We formalise Plünnecke's inequality and the Plünnecke-Ruzsa +inequality, following the notes by Timothy Gowers: "Introduction +to Additive Combinatorics" (2022) for the University of +Cambridge. To this end, we first introduce basic definitions and prove +elementary facts on sumsets and difference sets. Then, we show two +versions of the Ruzsa triangle inequality. We follow with a proof due +to Petridis.
BibTeX: +
@article{Pluennecke_Ruzsa_Inequality-AFP,
+  author  = {Angeliki Koutsoukou-Argyraki and Lawrence C. Paulson},
+  title   = {The Plünnecke-Ruzsa Inequality},
+  journal = {Archive of Formal Proofs},
+  month   = may,
+  year    = 2022,
+  note    = {\url{https://isa-afp.org/entries/Pluennecke_Ruzsa_Inequality.html},
+            Formal proof development},
+  ISSN    = {2150-914x},
+}
+
License:BSD License
Depends on:Jacobson_Basic_Algebra
+ +

+ + + + + + + + + + + + + + + + + + +
+
+ + + + + + \ No newline at end of file diff --git a/web/entries/Posix-Lexing.html b/web/entries/Posix-Lexing.html --- a/web/entries/Posix-Lexing.html +++ b/web/entries/Posix-Lexing.html @@ -1,240 +1,252 @@ POSIX Lexing with Derivatives of Regular Expressions - Archive of Formal Proofs

 

 

 

 

 

 

POSIX Lexing with Derivatives of Regular Expressions

 

+

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. Their algorithm generates POSIX +values which encode the information of how a regular +expression matches a string--—that is, which part of the string +is matched by which part of the regular expression. In this +paper 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). This holds +also when optimisations are included. Finally we show that +(iii) our inductive definition of a POSIX value is equivalent +to an alternative definition by Okui and Suzuki which +identifies POSIX values as least elements according to an +ordering of values.

+ + + +
Title: POSIX Lexing with Derivatives of Regular Expressions
Authors: Fahad Ausaf, Roy Dyckhoff and Christian Urban
Submission date: 2016-05-24
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.
Change history:[2022-06-17]: Christian Urban added a theory about the Posix definition by Okui and Suzuki.
BibTeX:
@article{Posix-Lexing-AFP,
   author  = {Fahad Ausaf and Roy Dyckhoff and Christian Urban},
   title   = {POSIX Lexing with Derivatives of Regular Expressions},
   journal = {Archive of Formal Proofs},
   month   = may,
   year    = 2016,
   note    = {\url{https://isa-afp.org/entries/Posix-Lexing.html},
             Formal proof development},
   ISSN    = {2150-914x},
 }
License: BSD License
Depends on: Regular-Sets

\ No newline at end of file diff --git a/web/entries/Regular-Sets.html b/web/entries/Regular-Sets.html --- a/web/entries/Regular-Sets.html +++ b/web/entries/Regular-Sets.html @@ -1,286 +1,287 @@ Regular Sets and Expressions - Archive of Formal Proofs

 

 

 

 

 

 

Regular Sets and Expressions

 

+ Manuel Eberl and + Christian Urban +
Title: Regular Sets and Expressions
Authors: Alexander Krauss and Tobias Nipkow
- Contributor: + Contributors: - Manuel Eberl -
Submission 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.

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
BibTeX:
@article{Regular-Sets-AFP,
   author  = {Alexander Krauss and Tobias Nipkow},
   title   = {Regular Sets and Expressions},
   journal = {Archive of Formal Proofs},
   month   = may,
   year    = 2010,
   note    = {\url{https://isa-afp.org/entries/Regular-Sets.html},
             Formal proof development},
   ISSN    = {2150-914x},
 }
License: BSD License
Used by: Abstract-Rewriting, Coinductive_Languages, Containers, Finite_Automata_HF, Functional-Automata, Lambda_Free_KBOs, List_Update, Myhill-Nerode, Posix-Lexing, Quick_Sort_Cost, Regex_Equivalence, Transitive-Closure-II

\ No newline at end of file diff --git a/web/entries/Regular_Tree_Relations.html b/web/entries/Regular_Tree_Relations.html --- a/web/entries/Regular_Tree_Relations.html +++ b/web/entries/Regular_Tree_Relations.html @@ -1,205 +1,205 @@ Regular Tree Relations - Archive of Formal Proofs

 

 

 

 

 

 

Regular Tree Relations

 

- +
Title: Regular Tree Relations
Authors: Alexander Lochmann (alexander /dot/ lochmann /at/ uibk /dot/ ac /dot/ at), Bertram Felgenhauer, Christian Sternagel, René Thiemann (rene /dot/ thiemann /at/ uibk /dot/ ac /dot/ at) and Thomas Sternagel
Submission date: 2021-12-15
Abstract: Tree automata have good closure properties and therefore a commonly used to prove/disprove properties. This formalization contains among other things the proofs of many closure properties of tree automata (anchored) ground tree transducers and regular relations. Additionally it includes the well known pumping lemma and a lifting of the Myhill Nerode theorem for regular languages to tree languages. We want to mention the existence of a tree automata APF-entry developed by Peter Lammich. His work is based on epsilon free top-down tree automata, while this entry builds on bottom-up tree auotamta with epsilon transitions. Moreover our formalization relies on the Collections Framework, also by Peter Lammich, to obtain efficient code. All proven constructions of the closure properties are exportable using the Isabelle/HOL code generation facilities.
BibTeX:
@article{Regular_Tree_Relations-AFP,
   author  = {Alexander Lochmann and Bertram Felgenhauer and Christian Sternagel and René Thiemann and Thomas Sternagel},
   title   = {Regular Tree Relations},
   journal = {Archive of Formal Proofs},
   month   = dec,
   year    = 2021,
   note    = {\url{https://isa-afp.org/entries/Regular_Tree_Relations.html},
             Formal proof development},
   ISSN    = {2150-914x},
 }
License: BSD License
Depends on: Knuth_Bendix_Order
Used by:FO_Theory_Rewriting
FO_Theory_Rewriting, Rewrite_Properties_Reduction

\ No newline at end of file diff --git a/web/entries/Rewrite_Properties_Reduction.html b/web/entries/Rewrite_Properties_Reduction.html new file mode 100644 --- /dev/null +++ b/web/entries/Rewrite_Properties_Reduction.html @@ -0,0 +1,199 @@ + + + + +Reducing Rewrite Properties to Properties on Ground Terms - Archive of Formal Proofs + + + + + + + + + + + + + + + + + + + + + + + + +
+

 

+ + + +

 

+

 

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

 

+

 

+
+
+

 

+

Reducing + + Rewrite + + Properties + + to + + Properties + + on + + Ground + + Terms + +

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Title:Reducing Rewrite Properties to Properties on Ground Terms
+ Author: + + Alexander Lochmann (alexander /dot/ lochmann /at/ uibk /dot/ ac /dot/ at) +
Submission date:2022-06-02
Abstract: +This AFP entry relates important rewriting properties between the set +of terms and the set of ground terms induced by a given signature. The +properties considered are confluence, strong/local confluence, the +normal form property, unique normal forms with respect to reduction +and conversion, commutation, conversion equivalence, and normalization +equivalence.
BibTeX: +
@article{Rewrite_Properties_Reduction-AFP,
+  author  = {Alexander Lochmann},
+  title   = {Reducing Rewrite Properties to Properties on Ground Terms},
+  journal = {Archive of Formal Proofs},
+  month   = jun,
+  year    = 2022,
+  note    = {\url{https://isa-afp.org/entries/Rewrite_Properties_Reduction.html},
+            Formal proof development},
+  ISSN    = {2150-914x},
+}
+
License:BSD License
Depends on:Regular_Tree_Relations
+ +

+ + + + + + + + + + + + + + + + + + +
+
+ + + + + + \ No newline at end of file diff --git a/web/entries/Types_To_Sets_Extension.html b/web/entries/Types_To_Sets_Extension.html --- a/web/entries/Types_To_Sets_Extension.html +++ b/web/entries/Types_To_Sets_Extension.html @@ -1,216 +1,220 @@ Extension of Types-To-Sets - Archive of Formal Proofs

 

 

 

 

 

 

Extension of Types-To-Sets

 

+ + + +
Title: Extension of Types-To-Sets
Author: - Mihails Milehins (user9716869 /at/ gmail /dot/ com) + Mihails Milehins (mihailsmilehins /at/ gmail /dot/ com)
Submission date: 2021-09-06
Abstract: In their article titled From Types to Sets by Local Type Definitions in Higher-Order Logic and published in the proceedings of the conference Interactive Theorem Proving in 2016, Ondřej Kunčar and Andrei Popescu propose an extension of the logic Isabelle/HOL and an associated algorithm for the relativization of the type-based theorems to more flexible set-based theorems, collectively referred to as Types-To-Sets. One of the aims of their work was to open an opportunity for the development of a software tool for applied relativization in the implementation of the logic Isabelle/HOL of the proof assistant Isabelle. In this article, we provide a prototype of a software framework for the interactive automated relativization of theorems in Isabelle/HOL, developed as an extension of the proof language Isabelle/Isar. The software framework incorporates the implementation of the proposed extension of the logic, and builds upon some of the ideas for further work expressed in the original article on Types-To-Sets by Ondřej Kunčar and Andrei Popescu and the subsequent article Smooth Manifolds and Types to Sets for Linear Algebra in Isabelle/HOL that was written by Fabian Immler and Bohua Zhan and published in the proceedings of the International Conference on Certified Programs and Proofs in 2019.
Change history:[2021-11-15]: integration with SpecCheck (revision 61e152c118d4)
BibTeX:
@article{Types_To_Sets_Extension-AFP,
   author  = {Mihails Milehins},
   title   = {Extension of Types-To-Sets},
   journal = {Archive of Formal Proofs},
   month   = sep,
   year    = 2021,
   note    = {\url{https://isa-afp.org/entries/Types_To_Sets_Extension.html},
             Formal proof development},
   ISSN    = {2150-914x},
 }
License: BSD License
Depends on: Conditional_Transfer_Rule, SpecCheck

\ 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,6205 +1,6259 @@ 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.

 

 

+ + + + + + + + + + + + + + + + + +
2022
+ 2022-06-08: Finite Fields +
+ Author: + Emin Karayel +
+ 2022-06-06: Diophantine Equations and the DPRM Theorem +
+ Authors: + Jonas Bayer, + Marco David, + Benedikt Stock, + Abhik Pal, + Yuri Matiyasevich + and Dierk Schleicher +
+ 2022-06-02: Reducing Rewrite Properties to Properties on Ground Terms +
+ Author: + Alexander Lochmann +
+ 2022-05-30: A Restricted Definition of the Magic Wand to Soundly Combine Fractions of a Wand +
+ Author: + Thibault Dardinier +
+ 2022-05-26: The Plünnecke-Ruzsa Inequality +
+ Authors: + Angeliki Koutsoukou-Argyraki + and Lawrence C. Paulson +
+ 2022-05-18: Formalization of a Framework for the Sound Automation of Magic Wands +
+ Author: + Thibault Dardinier +
2022-05-08: Clique is not solvable by monotone circuits of polynomial size
Author: René Thiemann
2022-04-21: Fisher's Inequality: Linear Algebraic Proof Techniques for Combinatorics
Authors: Chelsea Edmonds and Lawrence C. Paulson
2022-04-20: The Generalized Multiset Ordering is NP-Complete
Authors: René Thiemann and Lukas Schmidinger
2022-04-20: Digit Expansions
Authors: Jonas Bayer, Marco David, Abhik Pal and Benedikt Stock
2022-04-10: The Sophomore's Dream
Author: Manuel Eberl
2022-04-08: A Combinator Library for Prefix-Free Codes
Author: Emin Karayel
2022-04-08: Formalization of Randomized Approximation Algorithms for Frequency Moments
Author: Emin Karayel
2022-03-24: Constructing the Reals as Dedekind Cuts of Rationals
Authors: Jacques D. Fleuriot and Lawrence C. Paulson
2022-03-23: Ackermann's Function Is Not Primitive Recursive
Author: Lawrence C. Paulson
2022-03-22: A Naive Prover for First-Order Logic
Author: Asta Halkjær From
2022-03-15: A Proof from THE BOOK: The Partial Fraction Expansion of the Cotangent
Author: Manuel Eberl
2022-03-06: The Independence of the Continuum Hypothesis in Isabelle/ZF
Authors: Emmanuel Gunther, Miguel Pagano, Pedro Sánchez Terraf and Matías Steinberg
2022-03-03: Transitive Models of Fragments of ZFC
Authors: Emmanuel Gunther, Miguel Pagano, Pedro Sánchez Terraf and Matías Steinberg
2022-02-28: Residuated Transition Systems
Author: Eugene W. Stark
2022-02-20: Universal Hash Families
Author: Emin Karayel
2022-02-18: Wetzel's Problem and the Continuum Hypothesis
Author: Lawrence C Paulson
2022-02-15: First-Order Query Evaluation
Author: Martin Raszyk
2022-02-13: Multi-Head Monitoring of Metric Dynamic Logic
Author: Martin Raszyk
2022-02-04: Enumeration of Equivalence Relations
Author: Emin Karayel
2022-02-03: Quasi-Borel Spaces
Authors: Michikazu Hirata, Yasuhiko Minamide and Tetsuya Sato
2022-02-03: Duality of Linear Programming
Author: René Thiemann
2022-02-02: First-Order Theory of Rewriting
Authors: Alexander Lochmann and Bertram Felgenhauer
2022-01-31: Young's Inequality for Increasing Functions
Author: Lawrence C Paulson
2022-01-31: A Sequent Calculus Prover for First-Order Logic with Functions
Authors: Asta Halkjær From and Frederik Krogsdal Jacobsen
2022-01-29: Interpolation Polynomials (in HOL-Algebra)
Author: Emin Karayel
2022-01-25: Median Method
Author: Emin Karayel
2022-01-23: Actuarial Mathematics
Author: Yosuke Ito
2022-01-08: Irrational numbers from THE BOOK
Author: Lawrence C Paulson
2022-01-04: Knight's Tour Revisited Revisited
Author: Lukas Koller

 

2021
2021-12-31: Hyperdual Numbers and Forward Differentiation
Authors: Filip Smola and Jacques Fleuriot
2021-12-29: Gale-Shapley Algorithm
Author: Tobias Nipkow
2021-12-28: Roth's Theorem on Arithmetic Progressions
Authors: Chelsea Edmonds, Angeliki Koutsoukou-Argyraki and Lawrence C. Paulson
2021-12-16: Markov Decision Processes with Rewards
Authors: Maximilian Schäffeler and Mohammad Abdulaziz
2021-12-16: Verified Algorithms for Solving Markov Decision Processes
Authors: Maximilian Schäffeler and Mohammad Abdulaziz
2021-12-15: Regular Tree Relations
Authors: Alexander Lochmann, Bertram Felgenhauer, Christian Sternagel, René Thiemann and Thomas Sternagel
2021-11-29: Simplicial Complexes and Boolean functions
Authors: Jesús Aransay, Alejandro del Campo and Julius Michaelis
2021-11-23: van Emde Boas Trees
Authors: Thomas Ammer and Peter Lammich
2021-11-22: Foundation of geometry in planes, and some complements: Excluding the parallel axioms
Author: Fumiya Iwama
2021-11-19: The Hahn and Jordan Decomposition Theorems
Authors: Marie Cousin, Mnacho Echenim and Hervé Guiol
2021-11-08: Exploring Simplified Variants of Gödel’s Ontological Argument in Isabelle/HOL
Author: Christoph Benzmüller
2021-11-08: Real Exponents as the Limits of Sequences of Rational Exponents
Author: Jacques D. Fleuriot
2021-11-08: Automating Public Announcement Logic and the Wise Men Puzzle in Isabelle/HOL
Authors: Christoph Benzmüller and Sebastian Reiche
2021-11-08: Factorization of Polynomials with Algebraic Coefficients
Authors: Manuel Eberl and René Thiemann
2021-11-05: Szemerédi's Regularity Lemma
Authors: Chelsea Edmonds, Angeliki Koutsoukou-Argyraki and Lawrence C. Paulson
2021-10-28: Quantum and Classical Registers
Author: Dominique Unruh
2021-10-19: Belief Revision Theory
Authors: Valentin Fouillard, Safouan Taha, Frédéric Boulanger and Nicolas Sabouret
2021-10-13: X86 instruction semantics and basic block symbolic execution
Authors: Freek Verbeek, Abhijith Bharadwaj, Joshua Bockenek, Ian Roessle, Timmy Weerwag and Binoy Ravindran
2021-10-12: Algebras for Iteration, Infinite Executions and Correctness of Sequential Computations
Author: Walter Guttmann
2021-10-02: Verified Quadratic Virtual Substitution for Real Arithmetic
Authors: Matias Scharager, Katherine Cordwell, Stefan Mitsch and André Platzer
2021-09-24: Soundness and Completeness of an Axiomatic System for First-Order Logic
Author: Asta Halkjær From
2021-09-18: Complex Bounded Operators
Authors: Jose Manuel Rodriguez Caballero and Dominique Unruh
2021-09-16: A Formalization of Weighted Path Orders and Recursive Path Orders
Authors: Christian Sternagel, René Thiemann and Akihisa Yamada
2021-09-06: Extension of Types-To-Sets
Author: Mihails Milehins
2021-09-06: IDE: Introduction, Destruction, Elimination
Author: Mihails Milehins
2021-09-06: Conditional Transfer Rule
Author: Mihails Milehins
2021-09-06: Conditional Simplification
Author: Mihails Milehins
2021-09-06: Category Theory for ZFC in HOL III: Universal Constructions
Author: Mihails Milehins
2021-09-06: Category Theory for ZFC in HOL I: Foundations: Design Patterns, Set Theory, Digraphs, Semicategories
Author: Mihails Milehins
2021-09-06: Category Theory for ZFC in HOL II: Elementary Theory of 1-Categories
Author: Mihails Milehins
2021-09-05: A data flow analysis algorithm for computing dominators
Author: Nan Jiang
2021-09-03: Solving Cubic and Quartic Equations
Author: René Thiemann
2021-08-26: Logging-independent Message Anonymity in the Relational Method
Author: Pasquale Noce
2021-08-21: The Theorem of Three Circles
Authors: Fox Thomson and Wenda Li
2021-08-16: Fresh identifiers
Authors: Andrei Popescu and Thomas Bauereiss
2021-08-16: CoSMed: A confidentiality-verified social media platform
Authors: Thomas Bauereiss and Andrei Popescu
2021-08-16: CoSMeDis: A confidentiality-verified distributed social media platform
Authors: Thomas Bauereiss and Andrei Popescu
2021-08-16: CoCon: A Confidentiality-Verified Conference Management System
Authors: Andrei Popescu, Peter Lammich and Thomas Bauereiss
2021-08-16: Compositional BD Security
Authors: Thomas Bauereiss and Andrei Popescu
2021-08-13: Combinatorial Design Theory
Authors: Chelsea Edmonds and Lawrence Paulson
2021-08-03: Relational Forests
Author: Walter Guttmann
2021-07-27: Schutz' Independent Axioms for Minkowski Spacetime
Authors: Richard Schmoetten, Jake Palmer and Jacques Fleuriot
2021-07-07: Finitely Generated Abelian Groups
Authors: Joseph Thommes and Manuel Eberl
2021-07-01: SpecCheck - Specification-Based Testing for Isabelle/ML
Authors: Kevin Kappelmann, Lukas Bulwahn and Sebastian Willenbrink
2021-06-22: Van der Waerden's Theorem
Authors: Katharina Kreuzer and Manuel Eberl
2021-06-18: MiniSail - A kernel language for the ISA specification language SAIL
Author: Mark Wassell
2021-06-17: Public Announcement Logic
Author: Asta Halkjær From
2021-06-04: A Shorter Compiler Correctness Proof for Language IMP
Author: Pasquale Noce
2021-05-24: Lyndon words
Authors: Štěpán Holub and Štěpán Starosta
2021-05-24: Graph Lemma
Authors: Štěpán Holub and Štěpán Starosta
2021-05-24: Combinatorics on Words Basics
Authors: Štěpán Holub, Martin Raška and Štěpán Starosta
2021-04-30: Regression Test Selection
Author: Susannah Mansky
2021-04-27: Isabelle's Metalogic: Formalization and Proof Checker
Authors: Tobias Nipkow and Simon Roßkopf
2021-04-27: Lifting the Exponent
Author: Jakub Kądziołka
2021-04-24: The BKR Decision Procedure for Univariate Real Arithmetic
Authors: Katherine Cordwell, Yong Kiam Tan and André Platzer
2021-04-23: Gale-Stewart Games
Author: Sebastiaan Joosten
2021-04-13: Formalization of Timely Dataflow's Progress Tracking Protocol
Authors: Matthias Brun, Sára Decova, Andrea Lattuada and Dmitriy Traytel
2021-04-01: Information Flow Control via Dependency Tracking
Author: Benedikt Nordhoff
2021-03-29: Grothendieck's Schemes in Algebraic Geometry
Authors: Anthony Bordg, Lawrence Paulson and Wenda Li
2021-03-23: Hensel's Lemma for the p-adic Integers
Author: Aaron Crighton
2021-03-17: Constructive Cryptography in HOL: the Communication Modeling Aspect
Authors: Andreas Lochbihler and S. Reza Sefidgar
2021-03-12: Two algorithms based on modular arithmetic: lattice basis reduction and Hermite normal form computation
Authors: Ralph Bottesch, Jose Divasón and René Thiemann
2021-03-03: Quantum projective measurements and the CHSH inequality
Author: Mnacho Echenim
2021-03-03: The Hermite–Lindemann–Weierstraß Transcendence Theorem
Author: Manuel Eberl
2021-03-01: Mereology
Author: Ben Blumson
2021-02-25: The Sunflower Lemma of Erdős and Rado
Author: René Thiemann
2021-02-24: A Verified Imperative Implementation of B-Trees
Author: Niels Mündler
2021-02-17: Formal Puiseux Series
Author: Manuel Eberl
2021-02-10: The Laws of Large Numbers
Author: Manuel Eberl
2021-01-31: Tarski's Parallel Postulate implies the 5th Postulate of Euclid, the Postulate of Playfair and the original Parallel Postulate of Euclid
Author: Roland Coghetto
2021-01-30: Solution to the xkcd Blue Eyes puzzle
Author: Jakub Kądziołka
2021-01-18: Hood-Melville Queue
Author: Alejandro Gómez-Londoño
2021-01-11: JinjaDCI: a Java semantics with dynamic class initialization
Author: Susannah Mansky

 

2020
2020-12-27: Cofinality and the Delta System Lemma
Author: Pedro Sánchez Terraf
2020-12-17: Topological semantics for paraconsistent and paracomplete logics
Author: David Fuenmayor
2020-12-08: Relational Minimum Spanning Tree Algorithms
Authors: Walter Guttmann and Nicolas Robinson-O'Brien
2020-12-07: Inline Caching and Unboxing Optimization for Interpreters
Author: Martin Desharnais
2020-12-05: The Relational Method with Message Anonymity for the Verification of Cryptographic Protocols
Author: Pasquale Noce
2020-11-22: Isabelle Marries Dirac: a Library for Quantum Computation and Quantum Information
Authors: Anthony Bordg, Hanna Lachnitt and Yijun He
2020-11-19: The HOL-CSP Refinement Toolkit
Authors: Safouan Taha, Burkhart Wolff and Lina Ye
2020-10-29: Verified SAT-Based AI Planning
Authors: Mohammad Abdulaziz and Friedrich Kurz
2020-10-29: AI Planning Languages Semantics
Authors: Mohammad Abdulaziz and Peter Lammich
2020-10-20: A Sound Type System for Physical Quantities, Units, and Measurements
Authors: Simon Foster and Burkhart Wolff
2020-10-12: Finite Map Extras
Author: Javier Díaz
2020-09-28: A Formal Model of the Safely Composable Document Object Model with Shadow Roots
Authors: Achim D. Brucker and Michael Herzberg
2020-09-28: A Formal Model of the Document Object Model with Shadow Roots
Authors: Achim D. Brucker and Michael Herzberg
2020-09-28: A Formalization of Safely Composable Web Components
Authors: Achim D. Brucker and Michael Herzberg
2020-09-28: A Formalization of Web Components
Authors: Achim D. Brucker and Michael Herzberg
2020-09-28: The Safely Composable DOM
Authors: Achim D. Brucker and Michael Herzberg
2020-09-16: Syntax-Independent Logic Infrastructure
Authors: Andrei Popescu and Dmitriy Traytel
2020-09-16: Robinson Arithmetic
Authors: Andrei Popescu and Dmitriy Traytel
2020-09-16: An Abstract Formalization of Gödel's Incompleteness Theorems
Authors: Andrei Popescu and Dmitriy Traytel
2020-09-16: From Abstract to Concrete Gödel's Incompleteness Theorems—Part II
Authors: Andrei Popescu and Dmitriy Traytel
2020-09-16: From Abstract to Concrete Gödel's Incompleteness Theorems—Part I
Authors: Andrei Popescu and Dmitriy Traytel
2020-09-07: A Formal Model of Extended Finite State Machines
Authors: Michael Foster, Achim D. Brucker, Ramsay G. Taylor and John Derrick
2020-09-07: Inference of Extended Finite State Machines
Authors: Michael Foster, Achim D. Brucker, Ramsay G. Taylor and John Derrick
2020-08-31: Practical Algebraic Calculus Checker
Authors: Mathias Fleury and Daniela Kaufmann
2020-08-31: Some classical results in inductive inference of recursive functions
Author: Frank J. Balbach
2020-08-26: Relational Disjoint-Set Forests
Author: Walter Guttmann
2020-08-25: Extensions to the Comprehensive Framework for Saturation Theorem Proving
Authors: Jasmin Blanchette and Sophie Tourret
2020-08-25: Putting the `K' into Bird's derivation of Knuth-Morris-Pratt string matching
Author: Peter Gammie
2020-08-04: Amicable Numbers
Author: Angeliki Koutsoukou-Argyraki
2020-08-03: Ordinal Partitions
Author: Lawrence C. Paulson
2020-07-21: A Formal Proof of The Chandy--Lamport Distributed Snapshot Algorithm
Authors: Ben Fiedler and Dmitriy Traytel
2020-07-13: Relational Characterisations of Paths
Authors: Walter Guttmann and Peter Höfner
2020-06-01: A Formally Verified Checker of the Safe Distance Traffic Rules for Autonomous Vehicles
Authors: Albert Rizaldi and Fabian Immler
2020-05-23: A verified algorithm for computing the Smith normal form of a matrix
Author: Jose Divasón
2020-05-16: The Nash-Williams Partition Theorem
Author: Lawrence C. Paulson
2020-05-13: A Formalization of Knuth–Bendix Orders
Authors: Christian Sternagel and René Thiemann
2020-05-12: Irrationality Criteria for Series by Erdős and Straus
Authors: Angeliki Koutsoukou-Argyraki and Wenda Li
2020-05-11: Recursion Theorem in ZF
Author: Georgy Dunaev
2020-05-08: An Efficient Normalisation Procedure for Linear Temporal Logic: Isabelle/HOL Formalisation
Author: Salomon Sickert
2020-05-06: Formalization of Forcing in Isabelle/ZF
Authors: Emmanuel Gunther, Miguel Pagano and Pedro Sánchez Terraf
2020-05-02: Banach-Steinhaus Theorem
Authors: Dominique Unruh and Jose Manuel Rodriguez Caballero
2020-04-27: Attack Trees in Isabelle for GDPR compliance of IoT healthcare systems
Author: Florian Kammueller
2020-04-24: Power Sum Polynomials
Author: Manuel Eberl
2020-04-24: The Lambert W Function on the Reals
Author: Manuel Eberl
2020-04-24: Gaussian Integers
Author: Manuel Eberl
2020-04-19: Matrices for ODEs
Author: Jonathan Julian Huerta y Munive
2020-04-16: Authenticated Data Structures As Functors
Authors: Andreas Lochbihler and Ognjen Marić
2020-04-10: Formalization of an Algorithm for Greedily Computing Associative Aggregations on Sliding Windows
Authors: Lukas Heimes, Dmitriy Traytel and Joshua Schneider
2020-04-09: A Comprehensive Framework for Saturation Theorem Proving
Author: Sophie Tourret
2020-04-09: Formalization of an Optimized Monitoring Algorithm for Metric First-Order Dynamic Logic with Aggregations
Authors: - Thibault Dardinier, + Thibault Dardinier, Lukas Heimes, Martin Raszyk, Joshua Schneider and Dmitriy Traytel
2020-04-08: Stateful Protocol Composition and Typing
Authors: Andreas V. Hess, Sebastian Mödersheim and Achim D. Brucker
2020-04-08: Automated Stateful Protocol Verification
Authors: Andreas V. Hess, Sebastian Mödersheim, Achim D. Brucker and Anders Schlichtkrull
2020-04-07: Lucas's Theorem
Author: Chelsea Edmonds
2020-03-25: Strong Eventual Consistency of the Collaborative Editing Framework WOOT
Authors: Emin Karayel and Edgar Gonzàlez
2020-03-22: Furstenberg's topology and his proof of the infinitude of primes
Author: Manuel Eberl
2020-03-12: An Under-Approximate Relational Logic
Author: Toby Murray
2020-03-07: Hello World
Authors: Cornelius Diekmann and Lars Hupel
2020-02-21: Implementing the Goodstein Function in λ-Calculus
Author: Bertram Felgenhauer
2020-02-10: A Generic Framework for Verified Compilers
Author: Martin Desharnais
2020-02-01: Arithmetic progressions and relative primes
Author: José Manuel Rodríguez Caballero
2020-01-31: A Hierarchy of Algebras for Boolean Subsets
Authors: Walter Guttmann and Bernhard Möller
2020-01-17: Mersenne primes and the Lucas–Lehmer test
Author: Manuel Eberl
2020-01-16: Verified Approximation Algorithms
Authors: Robin Eßmann, Tobias Nipkow, Simon Robillard and Ujkan Sulejmani
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: Rose 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 + 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: Order Extension and Szpilrajn's Extension Theorem
Authors: Peter Zeller and Lukas Stevens
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: Completeness of Modal Logics
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: Rose 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, Peter Lammich and Thomas Bauereiss
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,675 +1,659 @@ 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. - 08 May 2022 00:00:00 +0000 + 08 Jun 2022 00:00:00 +0000 + + Finite Fields + https://www.isa-afp.org/entries/Finite_Fields.html + https://www.isa-afp.org/entries/Finite_Fields.html + Emin Karayel + 08 Jun 2022 00:00:00 +0000 + +This entry formalizes the classification of the finite fields (also +called Galois fields): For each prime power $p^n$ there exists exactly +one (up to isomorphisms) finite field of that size and there are no +other finite fields. The derivation includes a formalization of the +characteristic of rings, the Frobenius endomorphism, formal +differentiation for polynomials in HOL-Algebra and Gauss' formula +for the number of monic irreducible polynomials over finite fields: \[ +\frac{1}{n} \sum_{d | n} \mu(d) p^{n/d} \textrm{.} \] The proofs are +based on the books from <a +href="https://doi.org/10.1007/978-1-4757-2103-4">Ireland +and Rosen</a>, as well as, <a +href="https://doi.org/10.1017/CBO9781139172769">Lidl and +Niederreiter</a>. + + + Diophantine Equations and the DPRM Theorem + https://www.isa-afp.org/entries/DPRM_Theorem.html + https://www.isa-afp.org/entries/DPRM_Theorem.html + Jonas Bayer, Marco David, Benedikt Stock, Abhik Pal, Yuri Matiyasevich, Dierk Schleicher + 06 Jun 2022 00:00:00 +0000 + +We present a formalization of Matiyasevich's proof of the DPRM +theorem, which states that every recursively enumerable set of natural +numbers is Diophantine. This result from 1970 yields a negative +solution to Hilbert's 10th problem over the integers. To +represent recursively enumerable sets in equations, we implement and +arithmetize register machines. We formalize a general theory of +Diophantine sets and relations to reason about them abstractly. Using +several number-theoretic lemmas, we prove that exponentiation has a +Diophantine representation. + + + Reducing Rewrite Properties to Properties on Ground Terms + https://www.isa-afp.org/entries/Rewrite_Properties_Reduction.html + https://www.isa-afp.org/entries/Rewrite_Properties_Reduction.html + Alexander Lochmann + 02 Jun 2022 00:00:00 +0000 + +This AFP entry relates important rewriting properties between the set +of terms and the set of ground terms induced by a given signature. The +properties considered are confluence, strong/local confluence, the +normal form property, unique normal forms with respect to reduction +and conversion, commutation, conversion equivalence, and normalization +equivalence. + + + A Restricted Definition of the Magic Wand to Soundly Combine Fractions of a Wand + https://www.isa-afp.org/entries/Combinable_Wands.html + https://www.isa-afp.org/entries/Combinable_Wands.html + Thibault Dardinier + 30 May 2022 00:00:00 +0000 + +Many separation logics support <em>fractional +permissions</em> to distinguish between read and write access to +a heap location, for instance, to allow concurrent reads while +enforcing exclusive writes. The concept has been generalized to +fractional assertions. $A^p$ (where $A$ is a separation logic +assertion and $p$ a fraction between $0$ and $1$) represents a +fraction $p$ of $A$. $A^p$ holds in a state $\sigma$ iff there exists +a state $\sigma_A$ in which $A$ holds and $\sigma$ is obtained from +$\sigma_A$ by multiplying all permission amounts held by $p$. While +$A^{p + q}$ can always be split into $A^p * A^q$, recombining $A^p * +A^q$ into $A^{p+q}$ is not always sound. We say that $A$ is +<em>combinable</em> iff the entailment $A^p * A^q \models +A^{p+q}$ holds for any two positive fractions $p$ and $q$ such that $p ++ q \le 1$. Combinable assertions are particularly useful to reason +about concurrent programs, for instance, to combine the postconditions +of parallel branches when they terminate. Unfortunately, the magic +wand assertion $A \mathbin{-\!\!*} B$, commonly used to specify properties of +partial data structures, is typically <em>not</em> +combinable. In this entry, we formalize a novel, restricted +definition of the magic wand, described in <a +href="https://arxiv.org/abs/2205.11325">a paper at CAV +22</a>, which we call the <em>combinable wand</em>. +We prove some key properties of the combinable wand; in particular, a +combinable wand is combinable if its right-hand side is combinable. + + + The Plünnecke-Ruzsa Inequality + https://www.isa-afp.org/entries/Pluennecke_Ruzsa_Inequality.html + https://www.isa-afp.org/entries/Pluennecke_Ruzsa_Inequality.html + Angeliki Koutsoukou-Argyraki, Lawrence C. Paulson + 26 May 2022 00:00:00 +0000 + +We formalise Plünnecke's inequality and the Plünnecke-Ruzsa +inequality, following the notes by Timothy Gowers: "Introduction +to Additive Combinatorics" (2022) for the University of +Cambridge. To this end, we first introduce basic definitions and prove +elementary facts on sumsets and difference sets. Then, we show two +versions of the Ruzsa triangle inequality. We follow with a proof due +to Petridis. + + + Formalization of a Framework for the Sound Automation of Magic Wands + https://www.isa-afp.org/entries/Package_logic.html + https://www.isa-afp.org/entries/Package_logic.html + Thibault Dardinier + 18 May 2022 00:00:00 +0000 + +The magic wand $\mathbin{-\!\!*}$ (also called separating +implication) is a separation logic connective commonly used to specify +properties of partial data structures, for instance during iterative +traversals. A <em>footprint</em> of a magic wand formula +$$A \mathbin{-\!\!*} B$$ is a state that, combined with any state in +which $A$ holds, yields a state in which $B$ holds. The key +challenge of proving a magic wand (also called +<em>packaging</em> a wand) is to find such a footprint. +Existing package algorithms either have a high annotation overhead or +are unsound. In this entry, we formally define a framework for the +sound automation of magic wands, described in an <a href="https://www.cs.ubc.ca/~alexsumm/papers/DardinierParthasarathyWeeksMuellerSummers22.pdf">upcoming +paper at CAV 2022</a>, and prove that it is sound and complete. +This framework, called the <em>package logic</em>, +precisely characterises a wide design space of possible package +algorithms applicable to a large class of separation logics. + Clique is not solvable by monotone circuits of polynomial size https://www.isa-afp.org/entries/Clique_and_Monotone_Circuits.html https://www.isa-afp.org/entries/Clique_and_Monotone_Circuits.html René Thiemann 08 May 2022 00:00:00 +0000 <p> Given a graph $G$ with $n$ vertices and a number $s$, the decision problem Clique asks whether $G$ contains a fully connected subgraph with $s$ vertices. For this NP-complete problem there exists a non-trivial lower bound: no monotone circuit of a size that is polynomial in $n$ can solve Clique. </p><p> This entry provides an Isabelle/HOL formalization of a concrete lower bound (the bound is $\sqrt[7]{n}^{\sqrt[8]{n}}$ for the fixed choice of $s = \sqrt[4]{n}$), following a proof by Gordeev. </p> Fisher's Inequality: Linear Algebraic Proof Techniques for Combinatorics https://www.isa-afp.org/entries/Fishers_Inequality.html https://www.isa-afp.org/entries/Fishers_Inequality.html Chelsea Edmonds, Lawrence C. Paulson 21 Apr 2022 00:00:00 +0000 Linear algebraic techniques are powerful, yet often underrated tools in combinatorial proofs. This formalisation provides a library including matrix representations of incidence set systems, general formal proof techniques for the rank argument and linear bound argument, and finally a formalisation of a number of variations of the well-known Fisher's inequality. We build on our prior work formalising combinatorial design theory using a locale-centric approach, including extensions such as constant intersect designs and dual incidence systems. In addition to Fisher's inequality, we also formalise proofs on other incidence system properties using the incidence matrix representation, such as design existence, dual system relationships and incidence system isomorphisms. This formalisation is presented in the paper "Formalising Fisher's Inequality: Formal Linear Algebraic Techniques in Combinatorics", accepted to ITP 2022. The Generalized Multiset Ordering is NP-Complete https://www.isa-afp.org/entries/Multiset_Ordering_NPC.html https://www.isa-afp.org/entries/Multiset_Ordering_NPC.html René Thiemann, Lukas Schmidinger 20 Apr 2022 00:00:00 +0000 We consider the problem of comparing two multisets via the generalized multiset ordering. We show that the corresponding decision problem is NP-complete. To be more precise, we encode multiset-comparisons into propositional formulas or into conjunctive normal forms of quadratic size; we further prove that satisfiability of conjunctive normal forms can be encoded as multiset-comparison problems of linear size. As a corollary, we also show that the problem of deciding whether two terms are related by a recursive path order is NP-hard, provided the recursive path order is based on the generalized multiset ordering. Digit Expansions https://www.isa-afp.org/entries/Digit_Expansions.html https://www.isa-afp.org/entries/Digit_Expansions.html Jonas Bayer, Marco David, Abhik Pal, Benedikt Stock 20 Apr 2022 00:00:00 +0000 We formalize how a natural number can be expanded into its digits in some base and prove properties about functions that operate on digit expansions. This includes the formalization of concepts such as digit shifts and carries. For a base that is a power of 2 we formalize the binary AND, binary orthogonality and binary masking of two natural numbers. This library on digit expansions builds the basis for the formalization of the DPRM theorem. The Sophomore's Dream https://www.isa-afp.org/entries/Sophomores_Dream.html https://www.isa-afp.org/entries/Sophomores_Dream.html Manuel Eberl 10 Apr 2022 00:00:00 +0000 <p>This article provides a brief formalisation of the two equations known as the <em>Sophomore's Dream</em>, first discovered by Johann Bernoulli in 1697:</p> \[\int_0^1 x^{-x}\,\text{d}x = \sum_{n=1}^\infty n^{-n} \quad\text{and}\quad \int_0^1 x^x\,\text{d}x = -\sum_{n=1}^\infty (-n)^{-n}\] A Combinator Library for Prefix-Free Codes https://www.isa-afp.org/entries/Prefix_Free_Code_Combinators.html https://www.isa-afp.org/entries/Prefix_Free_Code_Combinators.html Emin Karayel 08 Apr 2022 00:00:00 +0000 This entry contains a set of binary encodings for primitive data types, such as natural numbers, integers, floating-point numbers as well as combinators to construct encodings for products, lists, sets or functions of/between such types. For natural numbers and integers, the entry contains various encodings, such as Elias-Gamma-Codes and exponential Golomb Codes, which are efficient variable-length codes in use by current compression formats. A use-case for this library is measuring the persisted size of a complex data structure without having to hand-craft a dedicated encoding for it, independent of Isabelle's internal representation. Formalization of Randomized Approximation Algorithms for Frequency Moments https://www.isa-afp.org/entries/Frequency_Moments.html https://www.isa-afp.org/entries/Frequency_Moments.html Emin Karayel 08 Apr 2022 00:00:00 +0000 In 1999 Alon et. al. introduced the still active research topic of approximating the frequency moments of a data stream using randomized algorithms with minimal space usage. This includes the problem of estimating the cardinality of the stream elements - the zeroth frequency moment. But, also higher-order frequency moments that provide information about the skew of the data stream. (The <i>k</i>-th frequency moment of a data stream is the sum of the <i>k</i>-th powers of the occurrence counts of each element in the stream.) This entry formalizes three randomized algorithms for the approximation of <i>F<sub>0</sub></i>, <i>F<sub>2</sub></i> and <i>F<sub>k</sub></i> for <i>k ≥ 3</i> based on [<a href="https://doi.org/10.1006/jcss.1997.1545">1</a>, <a href="https://doi.org/10.1007/3-540-45726-7_1">2</a>] and verifies their expected accuracy, success probability and space usage. Constructing the Reals as Dedekind Cuts of Rationals https://www.isa-afp.org/entries/Dedekind_Real.html https://www.isa-afp.org/entries/Dedekind_Real.html Jacques D. Fleuriot, Lawrence C. Paulson 24 Mar 2022 00:00:00 +0000 The type of real numbers is constructed from the positive rationals using the method of Dedekind cuts. This development, briefly described in papers by the authors, follows the textbook presentation by Gleason. It's notable that the first formalisation of a significant piece of mathematics, by Jutting in 1977, involved a similar construction. Ackermann's Function Is Not Primitive Recursive https://www.isa-afp.org/entries/Ackermanns_not_PR.html https://www.isa-afp.org/entries/Ackermanns_not_PR.html Lawrence C. Paulson 23 Mar 2022 00:00:00 +0000 Ackermann's function is defined in the usual way and a number of its elementary properties are proved. Then, the primitive recursive functions are defined inductively: as a predicate on the functions that map lists of numbers to numbers. It is shown that every primitive recursive function is strictly dominated by Ackermann's function. The formalisation follows an earlier one by Nora Szasz. A Naive Prover for First-Order Logic https://www.isa-afp.org/entries/FOL_Seq_Calc3.html https://www.isa-afp.org/entries/FOL_Seq_Calc3.html Asta Halkjær From 22 Mar 2022 00:00:00 +0000 <p> The AFP entry <a href="https://www.isa-afp.org/entries/Abstract_Completeness.html">Abstract Completeness</a> by Blanchette, Popescu and Traytel formalizes the core of Beth/Hintikka-style completeness proofs for first-order logic and can be used to formalize executable sequent calculus provers. In the Journal of Automated Reasoning, the authors instantiate the framework with a sequent calculus for first-order logic and prove its completeness. Their use of an infinite set of proof rules indexed by formulas yields very direct arguments. A fair stream of these rules controls the prover, making its definition remarkably simple. The AFP entry, however, only contains a toy example for propositional logic. The AFP entry <a href="https://www.isa-afp.org/entries/FOL_Seq_Calc2.html">A Sequent Calculus Prover for First-Order Logic with Functions</a> by From and Jacobsen also uses the framework, but uses a finite set of generic rules resulting in a more sophisticated prover with more complicated proofs. </p> <p> This entry contains an executable sequent calculus prover for first-order logic with functions in the style presented by Blanchette et al. The prover can be exported to Haskell and this entry includes formalized proofs of its soundness and completeness. The proofs are simpler than those for the prover by From and Jacobsen but the performance of the prover is significantly worse. </p> <p> The included theory <em>Fair-Stream</em> first proves that the sequence of natural numbers 0, 0, 1, 0, 1, 2, etc. is fair. It then proves that mapping any surjective function across the sequence preserves fairness. This method of obtaining a fair stream of rules is similar to the one given by Blanchette et al. The concrete functions from natural numbers to terms, formulas and rules are defined using the <em>Nat-Bijection</em> theory in the HOL-Library. </p> A Proof from THE BOOK: The Partial Fraction Expansion of the Cotangent https://www.isa-afp.org/entries/Cotangent_PFD_Formula.html https://www.isa-afp.org/entries/Cotangent_PFD_Formula.html Manuel Eberl 15 Mar 2022 00:00:00 +0000 <p>In this article, I formalise a proof from <a href="https://dx.doi.org/10.1007/978-3-662-57265-8">THE BOOK</a>; namely a formula that was called ‘one of the most beautiful formulas involving elementary functions’:</p> \[\pi \cot(\pi z) = \frac{1}{z} + \sum_{n=1}^\infty\left(\frac{1}{z+n} + \frac{1}{z-n}\right)\] <p>The proof uses Herglotz's trick to show the real case and analytic continuation for the complex case.</p> The Independence of the Continuum Hypothesis in Isabelle/ZF https://www.isa-afp.org/entries/Independence_CH.html https://www.isa-afp.org/entries/Independence_CH.html Emmanuel Gunther, Miguel Pagano, Pedro Sánchez Terraf, Matías Steinberg 06 Mar 2022 00:00:00 +0000 We redeveloped our formalization of forcing in the set theory framework of Isabelle/ZF. Under the assumption of the existence of a countable transitive model of ZFC, we construct proper generic extensions that satisfy the Continuum Hypothesis and its negation. Transitive Models of Fragments of ZFC https://www.isa-afp.org/entries/Transitive_Models.html https://www.isa-afp.org/entries/Transitive_Models.html Emmanuel Gunther, Miguel Pagano, Pedro Sánchez Terraf, Matías Steinberg 03 Mar 2022 00:00:00 +0000 We extend the ZF-Constructibility library by relativizing theories of the Isabelle/ZF and Delta System Lemma sessions to a transitive class. We also relativize Paulson's work on Aleph and our former treatment of the Axiom of Dependent Choices. This work is a prerrequisite to our formalization of the independence of the Continuum Hypothesis. Residuated Transition Systems https://www.isa-afp.org/entries/ResiduatedTransitionSystem.html https://www.isa-afp.org/entries/ResiduatedTransitionSystem.html Eugene W. Stark 28 Feb 2022 00:00:00 +0000 <p> A <em>residuated transition system</em> (RTS) is a transition system that is equipped with a certain partial binary operation, called <em>residuation</em>, on transitions. Using the residuation operation, one can express nuances, such as a distinction between nondeterministic and concurrent choice, as well as partial commutativity relationships between transitions, which are not captured by ordinary transition systems. A version of residuated transition systems was introduced in previous work by the author, in which they were called “concurrent transition systems” in view of the original motivation for their definition from the study of concurrency. In the first part of the present article, we give a formal development that generalizes and subsumes the original presentation. We give an axiomatic definition of residuated transition systems that assumes only a single partial binary operation as given structure. From the axioms, we derive notions of “arrow“ (transition), “source”, “target”, “identity”, as well as “composition” and “join” of transitions; thereby recovering structure that in the previous work was assumed as given. We formalize and generalize the result, that residuation extends from transitions to transition paths, and we systematically develop the properties of this extension. A significant generalization made in the present work is the identification of a general notion of congruence on RTS’s, along with an associated quotient construction. </p> <p> In the second part of this article, we use the RTS framework to formalize several results in the theory of reduction in Church’s λ-calculus. Using a de Bruijn index-based syntax in which terms represent parallel reduction steps, we define residuation on terms and show that it satisfies the axioms for an RTS. An application of the results on paths from the first part of the article allows us to prove the classical Church-Rosser Theorem with little additional effort. We then use residuation to define the notion of “development” and we prove the Finite Developments Theorem, that every development is finite, formalizing and adapting to de Bruijn indices a proof by de Vrijer. We also use residuation to define the notion of a “standard reduction path”, and we prove the Standardization Theorem: that every reduction path is congruent to a standard one. As a corollary of the Standardization Theorem, we obtain the Leftmost Reduction Theorem: that leftmost reduction is a normalizing strategy. </p> Universal Hash Families https://www.isa-afp.org/entries/Universal_Hash_Families.html https://www.isa-afp.org/entries/Universal_Hash_Families.html Emin Karayel 20 Feb 2022 00:00:00 +0000 A <i>k</i>-universal hash family is a probability space of functions, which have uniform distribution and form <i>k</i>-wise independent random variables. They can often be used in place of classic (or cryptographic) hash functions and allow the rigorous analysis of the performance of randomized algorithms and data structures that rely on hash functions. In 1981 <a href="https://doi.org/10.1016/0022-0000(81)90033-7">Wegman and Carter</a> introduced a generic construction for such families with arbitrary <i>k</i> using polynomials over a finite field. This entry contains a formalization of them and establishes the property of <i>k</i>-universality. To be useful the formalization also provides an explicit construction of finite fields using the factor ring of integers modulo a prime. Additionally, some generic results about independent families are shown that might be of independent interest. Wetzel's Problem and the Continuum Hypothesis https://www.isa-afp.org/entries/Wetzels_Problem.html https://www.isa-afp.org/entries/Wetzels_Problem.html Lawrence C Paulson 18 Feb 2022 00:00:00 +0000 Let $F$ be a set of analytic functions on the complex plane such that, for each $z\in\mathbb{C}$, the set $\{f(z) \mid f\in F\}$ is countable; must then $F$ itself be countable? The answer is yes if the Continuum Hypothesis is false, i.e., if the cardinality of $\mathbb{R}$ exceeds $\aleph_1$. But if CH is true then such an $F$, of cardinality $\aleph_1$, can be constructed by transfinite recursion. The formal proof illustrates reasoning about complex analysis (analytic and homomorphic functions) and set theory (transfinite cardinalities) in a single setting. The mathematical text comes from <em>Proofs from THE BOOK</em> by Aigner and Ziegler. First-Order Query Evaluation https://www.isa-afp.org/entries/Eval_FO.html https://www.isa-afp.org/entries/Eval_FO.html Martin Raszyk 15 Feb 2022 00:00:00 +0000 We formalize first-order query evaluation over an infinite domain with equality. We first define the syntax and semantics of first-order logic with equality. Next we define a locale <i>eval&lowbar;fo</i> abstracting a representation of a potentially infinite set of tuples satisfying a first-order query over finite relations. Inside the locale, we define a function <i>eval</i> checking if the set of tuples satisfying a first-order query over a database (an interpretation of the query's predicates) is finite (i.e., deciding <i>relative safety</i>) and computing the set of satisfying tuples if it is finite. Altogether the function <i>eval</i> solves <i>capturability</i> (Avron and Hirshfeld, 1991) of first-order logic with equality. We also use the function <i>eval</i> to prove a code equation for the semantics of first-order logic, i.e., the function checking if a first-order query over a database is satisfied by a variable assignment.<br/> We provide an interpretation of the locale <i>eval&lowbar;fo</i> based on the approach by Ailamazyan et al. A core notion in the interpretation is the active domain of a query and a database that contains all domain elements that occur in the database or interpret the query's constants. We prove the main theorem of Ailamazyan et al. relating the satisfaction of a first-order query over an infinite domain to the satisfaction of this query over a finite domain consisting of the active domain and a few additional domain elements (outside the active domain) whose number only depends on the query. In our interpretation of the locale <i>eval&lowbar;fo</i>, we use a potentially higher number of the additional domain elements, but their number still only depends on the query and thus has no effect on the data complexity (Vardi, 1982) of query evaluation. Our interpretation yields an <i>executable</i> function <i>eval</i>. The time complexity of <i>eval</i> on a query is linear in the total number of tuples in the intermediate relations for the subqueries. Specifically, we build a database index to evaluate a conjunction. We also optimize the case of a negated subquery in a conjunction. Finally, we export code for the infinite domain of natural numbers. Multi-Head Monitoring of Metric Dynamic Logic https://www.isa-afp.org/entries/VYDRA_MDL.html https://www.isa-afp.org/entries/VYDRA_MDL.html Martin Raszyk 13 Feb 2022 00:00:00 +0000 <p>Runtime monitoring (or runtime verification) is an approach to checking compliance of a system's execution with a specification (e.g., a temporal formula). The system's execution is logged into a <i>trace</i>&mdash;a sequence of time-points, each consisting of a time-stamp and observed events. A <i>monitor</i> is an algorithm that produces <i>verdicts</i> on the satisfaction of a temporal formula on a trace.</p> <p>We formalize the time-stamps as an abstract algebraic structure satisfying certain assumptions. Instances of this structure include natural numbers, real numbers, and lexicographic combinations of them. We also include the formalization of a conversion from the abstract time domain introduced by Koymans (1990) to our time-stamps.</p> <p>We formalize a monitoring algorithm for metric dynamic logic, an extension of metric temporal logic with regular expressions. The monitor computes whether a given formula is satisfied at every position in an input trace of time-stamped events. Our monitor follows the multi-head paradigm: it reads the input simultaneously at multiple positions and moves its reading heads asynchronously. This mode of operation results in unprecedented time and space complexity guarantees for metric dynamic logic: The monitor's amortized time complexity to process a time-point and the monitor's space complexity neither depends on the event-rate, i.e., the number of events within a fixed time-unit, nor on the numeric constants occurring in the quantitative temporal constraints in the given formula.</p> <p>The multi-head monitoring algorithm for metric dynamic logic is reported in our paper ``Multi-Head Monitoring of Metric Dynamic Logic'' published at ATVA 2020. We have also formalized unpublished specialized algorithms for the temporal operators of metric temporal logic.</p> Enumeration of Equivalence Relations https://www.isa-afp.org/entries/Equivalence_Relation_Enumeration.html https://www.isa-afp.org/entries/Equivalence_Relation_Enumeration.html Emin Karayel 04 Feb 2022 00:00:00 +0000 <p>This entry contains a formalization of an algorithm enumerating all equivalence relations on an initial segment of the natural numbers. The approach follows the method described by Stanton and White <a href="https://doi.org/10.1007/978-1-4612-4968-9">[5,§ 1.5]</a> using restricted growth functions.</p> <p>The algorithm internally enumerates restricted growth functions (as lists), whose equivalence kernels then form the equivalence relations. This has the advantage that the representation is compact and lookup of the relation reduces to a list lookup operation.</p> <p>The algorithm can also be used within a proof and an example application is included, where a sequence of variables is split by the possible partitions they can form.</p> Quasi-Borel Spaces https://www.isa-afp.org/entries/Quasi_Borel_Spaces.html https://www.isa-afp.org/entries/Quasi_Borel_Spaces.html Michikazu Hirata, Yasuhiko Minamide, Tetsuya Sato 03 Feb 2022 00:00:00 +0000 The notion of quasi-Borel spaces was introduced by <a href="https://dl.acm.org/doi/10.5555/3329995.3330072"> Heunen et al</a>. The theory provides a suitable denotational model for higher-order probabilistic programming languages with continuous distributions. This entry is a formalization of the theory of quasi-Borel spaces, including construction of quasi-Borel spaces (product, coproduct, function spaces), the adjunction between the category of measurable spaces and the category of quasi-Borel spaces, and the probability monad on quasi-Borel spaces. This entry also contains the formalization of the Bayesian regression presented in the work of Heunen et al. This work is a part of the work by same authors, <i>Program Logic for Higher-Order Probabilistic Programs in Isabelle/HOL</i>, which will be published in the proceedings of the 16th International Symposium on Functional and Logic Programming (FLOPS 2022). Duality of Linear Programming https://www.isa-afp.org/entries/LP_Duality.html https://www.isa-afp.org/entries/LP_Duality.html René Thiemann 03 Feb 2022 00:00:00 +0000 We formalize the weak and strong duality theorems of linear programming. For the strong duality theorem we provide three sufficient preconditions: both the primal problem and the dual problem are satisfiable, the primal problem is satisfiable and bounded, or the dual problem is satisfiable and bounded. The proofs are based on an existing formalization of Farkas' Lemma. First-Order Theory of Rewriting https://www.isa-afp.org/entries/FO_Theory_Rewriting.html https://www.isa-afp.org/entries/FO_Theory_Rewriting.html Alexander Lochmann, Bertram Felgenhauer 02 Feb 2022 00:00:00 +0000 The first-order theory of rewriting (FORT) is a decidable theory for linear variable-separated rewrite systems. The decision procedure is based on tree automata technique and an inference system presented in "Certifying Proofs in the First-Order Theory of Rewriting". This AFP entry provides a formalization of the underlying decision procedure. Moreover it allows to generate a function that can verify each inference step via the code generation facility of Isabelle/HOL. Additionally it contains the specification of a certificate language (that allows to state proofs in FORT) and a formalized function that allows to verify the validity of the proof. This gives software tool authors, that implement the decision procedure, the possibility to verify their output. Young's Inequality for Increasing Functions https://www.isa-afp.org/entries/Youngs_Inequality.html https://www.isa-afp.org/entries/Youngs_Inequality.html Lawrence C Paulson 31 Jan 2022 00:00:00 +0000 Young's inequality states that $$ ab \leq \int_0^a f(x)dx + \int_0^b f^{-1}(y) dy $$ where $a\geq 0$, $b\geq 0$ and $f$ is strictly increasing and continuous. Its proof is formalised following <a href="https://www.jstor.org/stable/2318018">the development</a> by Cunningham and Grossman. Their idea is to make the intuitive, geometric folklore proof rigorous by reasoning about step functions. The lack of the Riemann integral makes the development longer than one would like, but their argument is reproduced faithfully. A Sequent Calculus Prover for First-Order Logic with Functions https://www.isa-afp.org/entries/FOL_Seq_Calc2.html https://www.isa-afp.org/entries/FOL_Seq_Calc2.html Asta Halkjær From, Frederik Krogsdal Jacobsen 31 Jan 2022 00:00:00 +0000 We formalize an automated theorem prover for first-order logic with functions. The proof search procedure is based on sequent calculus and we verify its soundness and completeness using the Abstract Soundness and Abstract Completeness theories. Our analytic completeness proof covers both open and closed formulas. Since our deterministic prover considers only the subset of terms relevant to proving a given sequent, we do so as well when building a countermodel from a failed proof. We formally connect our prover with the proof system and semantics of the existing SeCaV system. In particular, the prover's output can be post-processed in Haskell to generate human-readable SeCaV proofs which are also machine-verifiable proof certificates. - - Interpolation Polynomials (in HOL-Algebra) - https://www.isa-afp.org/entries/Interpolation_Polynomials_HOL_Algebra.html - https://www.isa-afp.org/entries/Interpolation_Polynomials_HOL_Algebra.html - Emin Karayel - 29 Jan 2022 00:00:00 +0000 - -<p>A well known result from algebra is that, on any field, there -is exactly one polynomial of degree less than n interpolating n points -[<a -href="https://doi.org/10.1017/CBO9780511814549">1</a>, -§7].</p> <p>This entry contains a formalization of the -above result, as well as the following generalization in the case of -finite fields <i>F</i>: There are -<i>|F|<sup>m-n</sup></i> polynomials of degree -less than <i>m ≥ n</i> interpolating the same n points, -where <i>|F|</i> denotes the size of the domain of the -field. To establish the result the entry also includes a formalization -of Lagrange interpolation, which might be of independent -interest.</p> <p>The formalized results are defined on the -algebraic structures from HOL-Algebra, which are distinct from the -type-class based structures defined in HOL. Note that there is an -existing formalization for polynomial interpolation and, in -particular, Lagrange interpolation by Thiemann and Yamada [<a -href="https://www.isa-afp.org/entries/Polynomial_Interpolation.html">2</a>] -on the type-class based structures in HOL.</p> - - - Median Method - https://www.isa-afp.org/entries/Median_Method.html - https://www.isa-afp.org/entries/Median_Method.html - Emin Karayel - 25 Jan 2022 00:00:00 +0000 - -<p>The median method is an amplification result for randomized -approximation algorithms described in [<a -href="https://doi.org/10.1006/jcss.1997.1545">1</a>]. -Given an algorithm whose result is in a desired interval with a -probability larger than <i>1/2</i>, it is possible to -improve the success probability, by running the algorithm multiple -times independently and using the median. In contrast to using the -mean, the amplification of the success probability grows exponentially -with the number of independent runs.</p> <p>This entry -contains a formalization of the underlying theorem: Given a sequence -of n independent random variables, which are in a desired interval -with a probability <i>1/2 + a</i>. Then their median will -be in the desired interval with a probability of <i>1 − -exp(−2a<sup>2</sup> n)</i>. In particular, the -success probability approaches <i>1</i> exponentially with -the number of variables.</p> <p>In addition to that, this -entry also contains a proof that order-statistics of Borel-measurable -random variables are themselves measurable and that generalized -intervals in linearly ordered Borel-spaces are measurable.</p> - - - Actuarial Mathematics - https://www.isa-afp.org/entries/Actuarial_Mathematics.html - https://www.isa-afp.org/entries/Actuarial_Mathematics.html - Yosuke Ito - 23 Jan 2022 00:00:00 +0000 - -Actuarial Mathematics is a theory in applied mathematics, which is -mainly used for determining the prices of insurance products and -evaluating the liability of a company associating with insurance -contracts. It is related to calculus, probability theory and financial -theory, etc. In this entry, I formalize the very basic part of -Actuarial Mathematics in Isabelle/HOL. The first formalization is -about the theory of interest which deals with interest rates, present -value factors, an annuity certain, etc. I have already formalized the -basic part of Actuarial Mathematics in Coq -(https://github.com/Yosuke-Ito-345/Actuary). This entry is currently -the partial translation and a little generalization of the Coq -formalization. The further translation in Isabelle/HOL is now -proceeding. - - - Irrational numbers from THE BOOK - https://www.isa-afp.org/entries/Irrationals_From_THEBOOK.html - https://www.isa-afp.org/entries/Irrationals_From_THEBOOK.html - Lawrence C Paulson - 08 Jan 2022 00:00:00 +0000 - -An elementary proof is formalised: that <em>exp r</em> is irrational for -every nonzero rational number <em>r</em>. The mathematical development comes -from the well-known volume <em>Proofs from THE BOOK</em>, -by Aigner and Ziegler, who credit the idea to Hermite. The development -illustrates a number of basic Isabelle techniques: the manipulation of -summations, the calculation of quite complicated derivatives and the -estimation of integrals. We also see how to import another AFP entry (Stirling's formula). -As for the theorem itself, note that a much stronger and more general -result (the Hermite--Lindemann--Weierstraß transcendence theorem) is -already available in the AFP. - - - Knight's Tour Revisited Revisited - https://www.isa-afp.org/entries/Knights_Tour.html - https://www.isa-afp.org/entries/Knights_Tour.html - Lukas Koller - 04 Jan 2022 00:00:00 +0000 - -This is a formalization of the article <i>Knight's Tour Revisited</i> by -Cull and De Curtins where they prove the existence of a Knight's -path for arbitrary <i>n &times; m</i>-boards with <i>min(n,m) &ge; -5</i>. If <i>n &middot; m</i> is even, then there exists a Knight's -circuit. A Knight's Path is a sequence of moves of a Knight on a -chessboard s.t. the Knight visits every square of a chessboard -exactly once. Finding a Knight's path is a an instance of the -Hamiltonian path problem. A Knight's circuit is a Knight's path, -where additionally the Knight can move from the last square to the -first square of the path, forming a loop. During the formalization -two mistakes in the original proof were discovered. These mistakes -are corrected in this formalization. - - - Hyperdual Numbers and Forward Differentiation - https://www.isa-afp.org/entries/Hyperdual.html - https://www.isa-afp.org/entries/Hyperdual.html - Filip Smola, Jacques Fleuriot - 31 Dec 2021 00:00:00 +0000 - -<p>Hyperdual numbers are ones with a real component and a number -of infinitesimal components, usually written as $a_0 + a_1 \cdot -\epsilon_1 + a_2 \cdot \epsilon_2 + a_3 \cdot \epsilon_1\epsilon_2$. -They have been proposed by <a -href="https://doi.org/10.2514/6.2011-886">Fike and -Alonso</a> in an approach to automatic -differentiation.</p> <p>In this entry we formalise -hyperdual numbers and their application to forward differentiation. We -show them to be an instance of multiple algebraic structures and then, -along with facts about twice-differentiability, we define what we call -the hyperdual extensions of functions on real-normed fields. This -extension formally represents the proposed way that the first and -second derivatives of a function can be automatically calculated. We -demonstrate it on the standard logistic function $f(x) = \frac{1}{1 + -e^{-x}}$ and also reproduce the example analytic function $f(x) = -\frac{e^x}{\sqrt{sin(x)^3 + cos(x)^3}}$ used for demonstration by Fike -and Alonso.</p> - diff --git a/web/statistics.html b/web/statistics.html --- a/web/statistics.html +++ b/web/statistics.html @@ -1,302 +1,302 @@ Archive of Formal Proofs

 

 

 

 

 

 

Statistics

 

Statistics

- - - - + + + +
Number of Articles:679
Number of Authors:429
Number of lemmas:~197,700
Lines of Code:~3,419,000
Number of Articles:685
Number of Authors:431
Number of lemmas:~199,200
Lines of Code:~3,448,800

Most used AFP articles:

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

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

 

 

 

 

 

 

Index by Topic

 

Computer science

Artificial intelligence

Automata and formal languages

Algorithms

Knuth_Morris_Pratt   Probabilistic_While   Comparison_Sort_Lower_Bound   Quick_Sort_Cost   TortoiseHare   Selection_Heap_Sort   VerifyThis2018   CYK   Boolean_Expression_Checkers   Efficient-Mergesort   SATSolverVerification   MuchAdoAboutTwo   First_Order_Terms   MDP-Algorithms   Monad_Memo_DP   Hidden_Markov_Models   Imperative_Insertion_Sort   Formal_SSA   ROBDD   Median_Of_Medians_Selection   Fisher_Yates   Optimal_BST   IMP2   Auto2_Imperative_HOL   List_Inversions   IMP2_Binary_Heap   MFOTL_Monitor   Adaptive_State_Counting   Generic_Join   VerifyThis2019   Generalized_Counting_Sort   MFODL_Monitor_Optimized   Sliding_Window_Algorithm   PAC_Checker   Regression_Test_Selection   Gale_Shapley   VYDRA_MDL   Universal_Hash_Families   Prefix_Free_Code_Combinators   Graph: DFS_Framework   Prpu_Maxflow   Floyd_Warshall   Roy_Floyd_Warshall   Dijkstra_Shortest_Path   EdmondsKarp_Maxflow   Depth-First-Search   GraphMarkingIBP   Transitive-Closure   Transitive-Closure-II   Gabow_SCC   Kruskal   Prim_Dijkstra_Simple   Relational_Minimum_Spanning_Trees   Distributed: DiskPaxos   GenClock   ClockSynchInst   Heard_Of   Consensus_Refined   Abortable_Linearizable_Modules   IMAP-CRDT   CRDT   Chandy_Lamport   OpSets   Stellar_Quorums   WOOT_Strong_Eventual_Consistency   Progress_Tracking   Concurrent: ConcurrentGC   Online: List_Update   Geometry: Closest_Pair_Points   Approximation: Approximation_Algorithms   Frequency_Moments   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   BenOr_Kozen_Reif   Smith_Normal_Form   Safe_Distance   Modular_arithmetic_LLL_and_HNF_algorithms   Virtual_Substitution   Equivalence_Relation_Enumeration   Optimization: Simplex   Quantum computing: Isabelle_Marries_Dirac   Projective_Measurements   Registers  

Concurrency

Data structures

Functional programming

Hardware

Machine learning

Networks

Programming languages

Clean   Decl_Sem_Fun_PL   Language definitions: CakeML   WebAssembly   pGCL   GPU_Kernel_PL   LightweightJava   CoreC++   FeatherweightJava   Jinja   JinjaThreads   Locally-Nameless-Sigma   AutoFocus-Stream   FocusStreamsCaseStudies   Isabelle_Meta_Model   Simpl   Complx   Safe_OCL   Isabelle_C   JinjaDCI   Lambda calculi: Higher_Order_Terms   Launchbury   PCF   POPLmark-deBruijn   Lam-ml-Normalization   LambdaMu   Binding_Syntax_Theory   LambdaAuth   ResiduatedTransitionSystem   Type systems: Name_Carrying_Type_Inference   MiniML   Possibilistic_Noninterference   SIFUM_Type_Systems   Dependent_SIFUM_Type_Systems   Strong_Security   WHATandWHERE_Security   VolpanoSmith   Physical_Quantities   MiniSail   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   + Package_logic   + Combinable_Wands   Correctness_Algebras   Registers   Compiling: CakeML_Codegen   Compiling-Exceptions-Correctly   NormByEval   Density_Compiler   VeriComp   IMP_Compiler   Static analysis: RIPEMD-160-SPARK   Program-Conflict-Analysis   Shivers-CFA   Slicing   HRB-Slicing   InfPathElimination   Abs_Int_ITP2012   Dominance_CHK   Transformations: Call_Arity   Refine_Imperative_HOL   WorkerWrapper   Monad_Memo_DP   Formal_SSA   Minimal_SSA   Misc: JiveDataStoreModel   Pop_Refinement   Case_Labeling   Interpreter_Optimizations  

Security

Semantics

System description languages

Logic

Philosophical aspects

General logic

Computability

Set theory

Proof theory

Rewriting

Mathematics

Order

Algebra

Optics   Subresultants   Buildings   Algebraic_VCs   C2KA_DistributedSystems   Multirelations   Residuated_Lattices   PseudoHoops   Impossible_Geometry   Gauss-Jordan-Elim-Fun   Matrix_Tensor   Kleene_Algebra   KAT_and_DRA   KAD   Regular_Algebras   Free-Groups   CofGroups   Finitely_Generated_Abelian_Groups   Group-Ring-Module   Robbins-Conjecture   Valuation   Rank_Nullity_Theorem   Polynomials   Relation_Algebra   PSemigroupsConvolution   Secondary_Sylow   Jordan_Hoelder   Cayley_Hamilton   VectorSpace   Echelon_Form   QR_Decomposition   Hermite   Rep_Fin_Groups   Jordan_Normal_Form   Algebraic_Numbers   Polynomial_Interpolation   Polynomial_Factorization   Perron_Frobenius   Stochastic_Matrices   Groebner_Bases   Nullstellensatz   Mason_Stothers   Berlekamp_Zassenhaus   Stone_Relation_Algebras   Stone_Kleene_Relation_Algebras   Orbit_Stabiliser   Dirichlet_L   Symmetric_Polynomials   Taylor_Models   LLL_Basis_Reduction   LLL_Factorization   Localization_Ring   Quaternions   Octonions   Aggregation_Algebras   Signature_Groebner   Quantales   Transformer_Semantics   Farkas   Groebner_Macaulay   Linear_Inequalities   Linear_Programming   Jacobson_Basic_Algebra   Hybrid_Systems_VCs   Subset_Boolean_Algebras   Power_Sum_Polynomials   Formal_Puiseux_Series   Matrices_for_ODEs   Smith_Normal_Form   Grothendieck_Schemes   Factor_Algebraic_Polynomial   Hyperdual   Interpolation_Polynomials_HOL_Algebra   LP_Duality   Fishers_Inequality   + Finite_Fields  

Analysis

Measure theory

Probability theory

Number theory

Games and economics

Geometry

Topology

Graph theory

Combinatorics

Category theory

Physics

Misc

Tools

\ No newline at end of file